2 # -*- coding: utf-8; -*-
4 # Copyright (C) 2011 Google Inc. All rights reserved.
5 # Copyright (C) 2009 Torch Mobile Inc.
6 # Copyright (C) 2009 Apple Inc. All rights reserved.
7 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions are
13 # * Redistributions of source code must retain the above copyright
14 # notice, this list of conditions and the following disclaimer.
15 # * Redistributions in binary form must reproduce the above
16 # copyright notice, this list of conditions and the following disclaimer
17 # in the documentation and/or other materials provided with the
19 # * Neither the name of Google Inc. nor the names of its
20 # contributors may be used to endorse or promote products derived from
21 # this software without specific prior written permission.
23 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 """Unit test for cpp_style.py."""
37 # FIXME: Add a good test that tests UpdateIncludeState.
44 import cpp as cpp_style
45 from cpp import CppChecker
46 from ..filter import FilterConfiguration
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):
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
62 filter = FilterConfiguration()
65 def __call__(self, unused_linenum, category, confidence, message):
66 self._assert_fn(category in self._all_style_categories,
67 'Message "%s" has category "%s",'
68 ' which is not in STYLE_CATEGORIES' % (message, category))
69 if self._filter.should_check(category, ""):
70 self._seen_style_categories[category] = 1
71 self._errors.append('%s [%s] [%d]' % (message, category, confidence))
74 if len(self._errors) < 2:
75 return ''.join(self._errors) # Most tests expect to have a string.
77 return self._errors # Let's give a list if there is more than one.
79 def result_list(self):
82 def verify_all_categories_are_seen(self):
83 """Fails if there's a category in _all_style_categories - _seen_style_categories.
85 This should only be called after all tests are run, so
86 _seen_style_categories has had a chance to fully populate. Since
87 this isn't called from within the normal unittest framework, we
88 can't use the normal unittest assert macros. Instead we just exit
89 when we see an error. Good thing this test is always run last!
91 for category in self._all_style_categories:
92 if category not in self._seen_style_categories:
94 sys.exit('FATAL ERROR: There are no tests for category "%s"' % category)
97 # This class is a lame mock of codecs. We do not verify filename, mode, or
98 # encoding, but for the current use case it is not needed.
100 def __init__(self, mock_file):
101 self.mock_file = mock_file
103 def open(self, unused_filename, unused_mode, unused_encoding, _): # NOLINT
104 # (lint doesn't like open as a method name)
105 return self.mock_file
108 class CppFunctionsTest(unittest.TestCase):
110 """Supports testing functions that do not need CppStyleTestBase."""
112 def test_convert_to_lower_with_underscores(self):
113 self.assertEquals(cpp_style._convert_to_lower_with_underscores('ABC'), 'abc')
114 self.assertEquals(cpp_style._convert_to_lower_with_underscores('aB'), 'a_b')
115 self.assertEquals(cpp_style._convert_to_lower_with_underscores('isAName'), 'is_a_name')
116 self.assertEquals(cpp_style._convert_to_lower_with_underscores('AnotherTest'), 'another_test')
117 self.assertEquals(cpp_style._convert_to_lower_with_underscores('PassRefPtr<MyClass>'), 'pass_ref_ptr<my_class>')
118 self.assertEquals(cpp_style._convert_to_lower_with_underscores('_ABC'), '_abc')
120 def test_create_acronym(self):
121 self.assertEquals(cpp_style._create_acronym('ABC'), 'ABC')
122 self.assertEquals(cpp_style._create_acronym('IsAName'), 'IAN')
123 self.assertEquals(cpp_style._create_acronym('PassRefPtr<MyClass>'), 'PRP<MC>')
125 def test_is_c_or_objective_c(self):
126 clean_lines = cpp_style.CleansedLines([''])
127 clean_objc_lines = cpp_style.CleansedLines(['#import "header.h"'])
128 self.assertTrue(cpp_style._FileState(clean_lines, 'c').is_c_or_objective_c())
129 self.assertTrue(cpp_style._FileState(clean_lines, 'm').is_c_or_objective_c())
130 self.assertFalse(cpp_style._FileState(clean_lines, 'cpp').is_c_or_objective_c())
131 self.assertFalse(cpp_style._FileState(clean_lines, 'cc').is_c_or_objective_c())
132 self.assertFalse(cpp_style._FileState(clean_lines, 'h').is_c_or_objective_c())
133 self.assertTrue(cpp_style._FileState(clean_objc_lines, 'h').is_c_or_objective_c())
135 def test_parameter(self):
137 parameter = cpp_style.Parameter('ExceptionCode', 13, 1)
138 self.assertEquals(parameter.type, 'ExceptionCode')
139 self.assertEquals(parameter.name, '')
140 self.assertEquals(parameter.row, 1)
142 # Test type and name.
143 parameter = cpp_style.Parameter('PassRefPtr<MyClass> parent', 19, 1)
144 self.assertEquals(parameter.type, 'PassRefPtr<MyClass>')
145 self.assertEquals(parameter.name, 'parent')
146 self.assertEquals(parameter.row, 1)
148 # Test type, no name, with default value.
149 parameter = cpp_style.Parameter('MyClass = 0', 7, 0)
150 self.assertEquals(parameter.type, 'MyClass')
151 self.assertEquals(parameter.name, '')
152 self.assertEquals(parameter.row, 0)
154 # Test type, name, and default value.
155 parameter = cpp_style.Parameter('MyClass a = 0', 7, 0)
156 self.assertEquals(parameter.type, 'MyClass')
157 self.assertEquals(parameter.name, 'a')
158 self.assertEquals(parameter.row, 0)
160 def test_single_line_view(self):
161 start_position = cpp_style.Position(row=1, column=1)
162 end_position = cpp_style.Position(row=3, column=1)
163 single_line_view = cpp_style.SingleLineView(['0', 'abcde', 'fgh', 'i'], start_position, end_position)
164 self.assertEquals(single_line_view.single_line, 'bcde fgh i')
165 self.assertEquals(single_line_view.convert_column_to_row(0), 1)
166 self.assertEquals(single_line_view.convert_column_to_row(4), 1)
167 self.assertEquals(single_line_view.convert_column_to_row(5), 2)
168 self.assertEquals(single_line_view.convert_column_to_row(8), 2)
169 self.assertEquals(single_line_view.convert_column_to_row(9), 3)
170 self.assertEquals(single_line_view.convert_column_to_row(100), 3)
172 start_position = cpp_style.Position(row=0, column=3)
173 end_position = cpp_style.Position(row=0, column=4)
174 single_line_view = cpp_style.SingleLineView(['abcdef'], start_position, end_position)
175 self.assertEquals(single_line_view.single_line, 'd')
177 def test_create_skeleton_parameters(self):
178 self.assertEquals(cpp_style.create_skeleton_parameters(''), '')
179 self.assertEquals(cpp_style.create_skeleton_parameters(' '), ' ')
180 self.assertEquals(cpp_style.create_skeleton_parameters('long'), 'long,')
181 self.assertEquals(cpp_style.create_skeleton_parameters('const unsigned long int'), ' int,')
182 self.assertEquals(cpp_style.create_skeleton_parameters('long int*'), ' int ,')
183 self.assertEquals(cpp_style.create_skeleton_parameters('PassRefPtr<Foo> a'), 'PassRefPtr a,')
184 self.assertEquals(cpp_style.create_skeleton_parameters(
185 'ComplexTemplate<NestedTemplate1<MyClass1, MyClass2>, NestedTemplate1<MyClass1, MyClass2> > param, int second'),
186 'ComplexTemplate param, int second,')
187 self.assertEquals(cpp_style.create_skeleton_parameters('int = 0, Namespace::Type& a'), 'int , Type a,')
188 # Create skeleton parameters is a bit too aggressive with function variables, but
189 # it allows for parsing other parameters and declarations like this are rare.
190 self.assertEquals(cpp_style.create_skeleton_parameters('void (*fn)(int a, int b), Namespace::Type& a'),
193 # This doesn't look like functions declarations but the simplifications help to eliminate false positives.
194 self.assertEquals(cpp_style.create_skeleton_parameters('b{d}'), 'b ,')
196 def test_find_parameter_name_index(self):
197 self.assertEquals(cpp_style.find_parameter_name_index(' int a '), 5)
198 self.assertEquals(cpp_style.find_parameter_name_index(' PassRefPtr '), 16)
199 self.assertEquals(cpp_style.find_parameter_name_index('double'), 6)
201 def test_parameter_list(self):
202 elided_lines = ['int blah(PassRefPtr<MyClass> paramName,',
203 'const Other1Class& foo,',
204 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const * param = new ComplexTemplate<Class1, NestedTemplate<P1, P2> >(34, 42),',
205 'int* myCount = 0);']
206 start_position = cpp_style.Position(row=0, column=8)
207 end_position = cpp_style.Position(row=3, column=16)
209 expected_parameters = ({'type': 'PassRefPtr<MyClass>', 'name': 'paramName', 'row': 0},
210 {'type': 'const Other1Class&', 'name': 'foo', 'row': 1},
211 {'type': 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const *', 'name': 'param', 'row': 2},
212 {'type': 'int*', 'name': 'myCount', 'row': 3})
214 for parameter in cpp_style.parameter_list(elided_lines, start_position, end_position):
215 expected_parameter = expected_parameters[index]
216 self.assertEquals(parameter.type, expected_parameter['type'])
217 self.assertEquals(parameter.name, expected_parameter['name'])
218 self.assertEquals(parameter.row, expected_parameter['row'])
220 self.assertEquals(index, len(expected_parameters))
222 def test_check_parameter_against_text(self):
223 error_collector = ErrorCollector(self.assert_)
224 parameter = cpp_style.Parameter('FooF ooF', 4, 1)
225 self.assertFalse(cpp_style._check_parameter_name_against_text(parameter, 'FooF', error_collector))
226 self.assertEquals(error_collector.results(),
227 'The parameter name "ooF" adds no information, so it should be removed. [readability/parameter_name] [5]')
229 class CppStyleTestBase(unittest.TestCase):
230 """Provides some useful helper functions for cpp_style tests.
233 min_confidence: An integer that is the current minimum confidence
238 # FIXME: Refactor the unit tests so the confidence level is passed
239 # explicitly, just like it is in the real code.
242 # Helper function to avoid needing to explicitly pass confidence
243 # in all the unit test calls to cpp_style.process_file_data().
244 def process_file_data(self, filename, file_extension, lines, error, unit_test_config={}):
245 """Call cpp_style.process_file_data() with the min_confidence."""
246 return cpp_style.process_file_data(filename, file_extension, lines,
247 error, self.min_confidence, unit_test_config)
249 def perform_lint(self, code, filename, basic_error_rules, unit_test_config={}):
250 error_collector = ErrorCollector(self.assert_, FilterConfiguration(basic_error_rules))
251 lines = code.split('\n')
252 extension = filename.split('.')[1]
253 self.process_file_data(filename, extension, lines, error_collector, unit_test_config)
254 return error_collector.results()
256 # Perform lint on single line of input and return the error message.
257 def perform_single_line_lint(self, code, filename):
258 basic_error_rules = ('-build/header_guard',
260 '-readability/fn_size',
261 '-readability/parameter_name',
262 '-readability/pass_ptr',
263 '-whitespace/ending_newline')
264 return self.perform_lint(code, filename, basic_error_rules)
266 # Perform lint over multiple lines and return the error message.
267 def perform_multi_line_lint(self, code, file_extension):
268 basic_error_rules = ('-build/header_guard',
270 '-readability/parameter_name',
271 '-whitespace/ending_newline')
272 return self.perform_lint(code, 'test.' + file_extension, basic_error_rules)
274 # Only keep some errors related to includes, namespaces and rtti.
275 def perform_language_rules_check(self, filename, code):
276 basic_error_rules = ('-',
278 '+build/include_order',
281 return self.perform_lint(code, filename, basic_error_rules)
283 # Only keep function length errors.
284 def perform_function_lengths_check(self, code):
285 basic_error_rules = ('-',
286 '+readability/fn_size')
287 return self.perform_lint(code, 'test.cpp', basic_error_rules)
289 # Only keep pass ptr errors.
290 def perform_pass_ptr_check(self, code):
291 basic_error_rules = ('-',
292 '+readability/pass_ptr')
293 return self.perform_lint(code, 'test.cpp', basic_error_rules)
295 # Only include what you use errors.
296 def perform_include_what_you_use(self, code, filename='foo.h', io=codecs):
297 basic_error_rules = ('-',
298 '+build/include_what_you_use')
299 unit_test_config = {cpp_style.INCLUDE_IO_INJECTION_KEY: io}
300 return self.perform_lint(code, filename, basic_error_rules, unit_test_config)
302 # Perform lint and compare the error message with "expected_message".
303 def assert_lint(self, code, expected_message, file_name='foo.cpp'):
304 self.assertEquals(expected_message, self.perform_single_line_lint(code, file_name))
306 def assert_lint_one_of_many_errors_re(self, code, expected_message_re, file_name='foo.cpp'):
307 messages = self.perform_single_line_lint(code, file_name)
308 for message in messages:
309 if re.search(expected_message_re, message):
312 self.assertEquals(expected_message_re, messages)
314 def assert_multi_line_lint(self, code, expected_message, file_name='foo.h'):
315 file_extension = file_name[file_name.rfind('.') + 1:]
316 self.assertEquals(expected_message, self.perform_multi_line_lint(code, file_extension))
318 def assert_multi_line_lint_re(self, code, expected_message_re, file_name='foo.h'):
319 file_extension = file_name[file_name.rfind('.') + 1:]
320 message = self.perform_multi_line_lint(code, file_extension)
321 if not re.search(expected_message_re, message):
322 self.fail('Message was:\n' + message + 'Expected match to "' + expected_message_re + '"')
324 def assert_language_rules_check(self, file_name, code, expected_message):
325 self.assertEquals(expected_message,
326 self.perform_language_rules_check(file_name, code))
328 def assert_include_what_you_use(self, code, expected_message):
329 self.assertEquals(expected_message,
330 self.perform_include_what_you_use(code))
332 def assert_blank_lines_check(self, lines, start_errors, end_errors):
333 error_collector = ErrorCollector(self.assert_)
334 self.process_file_data('foo.cpp', 'cpp', lines, error_collector)
337 error_collector.results().count(
338 'Blank line at the start of a code block. Is this needed?'
339 ' [whitespace/blank_line] [2]'))
342 error_collector.results().count(
343 'Blank line at the end of a code block. Is this needed?'
344 ' [whitespace/blank_line] [3]'))
346 def assert_positions_equal(self, position, tuple_position):
347 """Checks if the two positions are equal.
349 position: a cpp_style.Position object.
350 tuple_position: a tuple (row, column) to compare against."""
351 self.assertEquals(position, cpp_style.Position(tuple_position[0], tuple_position[1]),
352 'position %s, tuple_position %s' % (position, tuple_position))
355 class FunctionDetectionTest(CppStyleTestBase):
356 def perform_function_detection(self, lines, function_information, detection_line=0):
357 clean_lines = cpp_style.CleansedLines(lines)
358 function_state = cpp_style._FunctionState(5)
359 error_collector = ErrorCollector(self.assert_)
360 cpp_style.detect_functions(clean_lines, detection_line, function_state, error_collector)
361 if not function_information:
362 self.assertEquals(function_state.in_a_function, False)
364 self.assertEquals(function_state.in_a_function, True)
365 self.assertEquals(function_state.current_function, function_information['name'] + '()')
366 self.assertEquals(function_state.modifiers_and_return_type(), function_information['modifiers_and_return_type'])
367 self.assertEquals(function_state.is_pure, function_information['is_pure'])
368 self.assertEquals(function_state.is_declaration, function_information['is_declaration'])
369 self.assert_positions_equal(function_state.function_name_start_position, function_information['function_name_start_position'])
370 self.assert_positions_equal(function_state.parameter_start_position, function_information['parameter_start_position'])
371 self.assert_positions_equal(function_state.parameter_end_position, function_information['parameter_end_position'])
372 self.assert_positions_equal(function_state.body_start_position, function_information['body_start_position'])
373 self.assert_positions_equal(function_state.end_position, function_information['end_position'])
374 expected_parameters = function_information.get('parameter_list')
375 if expected_parameters:
376 actual_parameters = function_state.parameter_list()
377 self.assertEquals(len(actual_parameters), len(expected_parameters))
378 for index in range(len(expected_parameters)):
379 actual_parameter = actual_parameters[index]
380 expected_parameter = expected_parameters[index]
381 self.assertEquals(actual_parameter.type, expected_parameter['type'])
382 self.assertEquals(actual_parameter.name, expected_parameter['name'])
383 self.assertEquals(actual_parameter.row, expected_parameter['row'])
385 def test_basic_function_detection(self):
386 self.perform_function_detection(
387 ['void theTestFunctionName(int) {',
389 {'name': 'theTestFunctionName',
390 'modifiers_and_return_type': 'void',
391 'function_name_start_position': (0, 5),
392 'parameter_start_position': (0, 24),
393 'parameter_end_position': (0, 29),
394 'body_start_position': (0, 30),
395 'end_position': (1, 1),
397 'is_declaration': False})
399 def test_function_declaration_detection(self):
400 self.perform_function_detection(
401 ['void aFunctionName(int);'],
402 {'name': 'aFunctionName',
403 'modifiers_and_return_type': 'void',
404 'function_name_start_position': (0, 5),
405 'parameter_start_position': (0, 18),
406 'parameter_end_position': (0, 23),
407 'body_start_position': (0, 23),
408 'end_position': (0, 24),
410 'is_declaration': True})
412 self.perform_function_detection(
413 ['CheckedInt<T> operator /(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
414 {'name': 'operator /',
415 'modifiers_and_return_type': 'CheckedInt<T>',
416 'function_name_start_position': (0, 14),
417 'parameter_start_position': (0, 24),
418 'parameter_end_position': (0, 76),
419 'body_start_position': (0, 76),
420 'end_position': (0, 77),
422 'is_declaration': True})
424 self.perform_function_detection(
425 ['CheckedInt<T> operator -(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
426 {'name': 'operator -',
427 'modifiers_and_return_type': 'CheckedInt<T>',
428 'function_name_start_position': (0, 14),
429 'parameter_start_position': (0, 24),
430 'parameter_end_position': (0, 76),
431 'body_start_position': (0, 76),
432 'end_position': (0, 77),
434 'is_declaration': True})
436 self.perform_function_detection(
437 ['CheckedInt<T> operator !=(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
438 {'name': 'operator !=',
439 'modifiers_and_return_type': 'CheckedInt<T>',
440 'function_name_start_position': (0, 14),
441 'parameter_start_position': (0, 25),
442 'parameter_end_position': (0, 77),
443 'body_start_position': (0, 77),
444 'end_position': (0, 78),
446 'is_declaration': True})
448 self.perform_function_detection(
449 ['CheckedInt<T> operator +(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
450 {'name': 'operator +',
451 'modifiers_and_return_type': 'CheckedInt<T>',
452 'function_name_start_position': (0, 14),
453 'parameter_start_position': (0, 24),
454 'parameter_end_position': (0, 76),
455 'body_start_position': (0, 76),
456 'end_position': (0, 77),
458 'is_declaration': True})
460 def test_pure_function_detection(self):
461 self.perform_function_detection(
462 ['virtual void theTestFunctionName(int = 0);'],
463 {'name': 'theTestFunctionName',
464 'modifiers_and_return_type': 'virtual void',
465 'function_name_start_position': (0, 13),
466 'parameter_start_position': (0, 32),
467 'parameter_end_position': (0, 41),
468 'body_start_position': (0, 41),
469 'end_position': (0, 42),
471 'is_declaration': True})
473 self.perform_function_detection(
474 ['virtual void theTestFunctionName(int) = 0;'],
475 {'name': 'theTestFunctionName',
476 'modifiers_and_return_type': 'virtual void',
477 'function_name_start_position': (0, 13),
478 'parameter_start_position': (0, 32),
479 'parameter_end_position': (0, 37),
480 'body_start_position': (0, 41),
481 'end_position': (0, 42),
483 'is_declaration': True})
485 # Hopefully, no one writes code like this but it is a tricky case.
486 self.perform_function_detection(
487 ['virtual void theTestFunctionName(int)',
490 {'name': 'theTestFunctionName',
491 'modifiers_and_return_type': 'virtual void',
492 'function_name_start_position': (0, 13),
493 'parameter_start_position': (0, 32),
494 'parameter_end_position': (0, 37),
495 'body_start_position': (2, 3),
496 'end_position': (2, 4),
498 'is_declaration': True})
500 def test_ignore_macros(self):
501 self.perform_function_detection(['void aFunctionName(int); \\'], None)
503 def test_non_functions(self):
504 # This case exposed an error because the open brace was in quotes.
505 self.perform_function_detection(
507 ' "stmdb sp!, {r1-r3}" "\n"',
509 # This isn't a function but it looks like one to our simple
510 # algorithm and that is ok.
512 'modifiers_and_return_type': '',
513 'function_name_start_position': (0, 0),
514 'parameter_start_position': (0, 3),
515 'parameter_end_position': (2, 1),
516 'body_start_position': (2, 1),
517 'end_position': (2, 2),
519 'is_declaration': True})
521 # Simple test case with something that is not a function.
522 self.perform_function_detection(['class Stuff;'], None)
524 def test_parameter_list(self):
525 # A function with no arguments.
526 function_state = self.perform_function_detection(
527 ['void functionName();'],
528 {'name': 'functionName',
529 'modifiers_and_return_type': 'void',
530 'function_name_start_position': (0, 5),
531 'parameter_start_position': (0, 17),
532 'parameter_end_position': (0, 19),
533 'body_start_position': (0, 19),
534 'end_position': (0, 20),
536 'is_declaration': True,
537 'parameter_list': ()})
539 # A function with one argument.
540 function_state = self.perform_function_detection(
541 ['void functionName(int);'],
542 {'name': 'functionName',
543 'modifiers_and_return_type': 'void',
544 'function_name_start_position': (0, 5),
545 'parameter_start_position': (0, 17),
546 'parameter_end_position': (0, 22),
547 'body_start_position': (0, 22),
548 'end_position': (0, 23),
550 'is_declaration': True,
552 ({'type': 'int', 'name': '', 'row': 0},)})
554 # A function with unsigned and short arguments
555 function_state = self.perform_function_detection(
556 ['void functionName(unsigned a, short b, long c, long long short unsigned int);'],
557 {'name': 'functionName',
558 'modifiers_and_return_type': 'void',
559 'function_name_start_position': (0, 5),
560 'parameter_start_position': (0, 17),
561 'parameter_end_position': (0, 76),
562 'body_start_position': (0, 76),
563 'end_position': (0, 77),
565 'is_declaration': True,
567 ({'type': 'unsigned', 'name': 'a', 'row': 0},
568 {'type': 'short', 'name': 'b', 'row': 0},
569 {'type': 'long', 'name': 'c', 'row': 0},
570 {'type': 'long long short unsigned int', 'name': '', 'row': 0})})
572 # Some parameter type with modifiers and no parameter names.
573 function_state = self.perform_function_detection(
574 ['virtual void determineARIADropEffects(Vector<String>*&, const unsigned long int*&, const MediaPlayer::Preload, Other<Other2, Other3<P1, P2> >, int);'],
575 {'name': 'determineARIADropEffects',
576 'modifiers_and_return_type': 'virtual void',
577 'parameter_start_position': (0, 37),
578 'function_name_start_position': (0, 13),
579 'parameter_end_position': (0, 147),
580 'body_start_position': (0, 147),
581 'end_position': (0, 148),
583 'is_declaration': True,
585 ({'type': 'Vector<String>*&', 'name': '', 'row': 0},
586 {'type': 'const unsigned long int*&', 'name': '', 'row': 0},
587 {'type': 'const MediaPlayer::Preload', 'name': '', 'row': 0},
588 {'type': 'Other<Other2, Other3<P1, P2> >', 'name': '', 'row': 0},
589 {'type': 'int', 'name': '', 'row': 0})})
591 # Try parsing a function with a very complex definition.
592 function_state = self.perform_function_detection(
593 ['#define MyMacro(a) a',
595 'AnotherTemplate<Class1, Class2> aFunctionName(PassRefPtr<MyClass> paramName,',
596 'const Other1Class& foo,',
597 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const * param = new ComplexTemplate<Class1, NestedTemplate<P1, P2> >(34, 42),',
598 'int* myCount = 0);'],
599 {'name': 'aFunctionName',
600 'modifiers_and_return_type': 'virtual AnotherTemplate<Class1, Class2>',
601 'function_name_start_position': (2, 32),
602 'parameter_start_position': (2, 45),
603 'parameter_end_position': (5, 17),
604 'body_start_position': (5, 17),
605 'end_position': (5, 18),
607 'is_declaration': True,
609 ({'type': 'PassRefPtr<MyClass>', 'name': 'paramName', 'row': 2},
610 {'type': 'const Other1Class&', 'name': 'foo', 'row': 3},
611 {'type': 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const *', 'name': 'param', 'row': 4},
612 {'type': 'int*', 'name': 'myCount', 'row': 5})},
616 class CppStyleTest(CppStyleTestBase):
618 # Test get line width.
619 def test_get_line_width(self):
620 self.assertEquals(0, cpp_style.get_line_width(''))
621 self.assertEquals(10, cpp_style.get_line_width(u'x' * 10))
622 self.assertEquals(16, cpp_style.get_line_width(u'都|道|府|県|支庁'))
624 def test_find_next_multi_line_comment_start(self):
625 self.assertEquals(1, cpp_style.find_next_multi_line_comment_start([''], 0))
627 lines = ['a', 'b', '/* c']
628 self.assertEquals(2, cpp_style.find_next_multi_line_comment_start(lines, 0))
630 lines = ['char a[] = "/*";'] # not recognized as comment.
631 self.assertEquals(1, cpp_style.find_next_multi_line_comment_start(lines, 0))
633 def test_find_next_multi_line_comment_end(self):
634 self.assertEquals(1, cpp_style.find_next_multi_line_comment_end([''], 0))
635 lines = ['a', 'b', ' c */']
636 self.assertEquals(2, cpp_style.find_next_multi_line_comment_end(lines, 0))
638 def test_remove_multi_line_comments_from_range(self):
639 lines = ['a', ' /* comment ', ' * still comment', ' comment */ ', 'b']
640 cpp_style.remove_multi_line_comments_from_range(lines, 1, 4)
641 self.assertEquals(['a', '// dummy', '// dummy', '// dummy', 'b'], lines)
643 def test_position(self):
644 position = cpp_style.Position(3, 4)
645 self.assert_positions_equal(position, (3, 4))
646 self.assertEquals(position.row, 3)
647 self.assertTrue(position > cpp_style.Position(position.row - 1, position.column + 1))
648 self.assertTrue(position > cpp_style.Position(position.row, position.column - 1))
649 self.assertTrue(position < cpp_style.Position(position.row, position.column + 1))
650 self.assertTrue(position < cpp_style.Position(position.row + 1, position.column - 1))
651 self.assertEquals(position.__str__(), '(3, 4)')
653 def test_rfind_in_lines(self):
654 not_found_position = cpp_style.Position(10, 11)
655 start_position = cpp_style.Position(2, 2)
656 lines = ['ab', 'ace', 'test']
657 self.assertEquals(not_found_position, cpp_style._rfind_in_lines('st', lines, start_position, not_found_position))
658 self.assertTrue(cpp_style.Position(1, 1) == cpp_style._rfind_in_lines('a', lines, start_position, not_found_position))
659 self.assertEquals(cpp_style.Position(2, 2), cpp_style._rfind_in_lines('(te|a)', lines, start_position, not_found_position))
661 def test_close_expression(self):
662 self.assertEquals(cpp_style.Position(1, -1), cpp_style.close_expression([')('], cpp_style.Position(0, 1)))
663 self.assertEquals(cpp_style.Position(1, -1), cpp_style.close_expression([') ()'], cpp_style.Position(0, 1)))
664 self.assertEquals(cpp_style.Position(0, 4), cpp_style.close_expression([')[)]'], cpp_style.Position(0, 1)))
665 self.assertEquals(cpp_style.Position(0, 5), cpp_style.close_expression(['}{}{}'], cpp_style.Position(0, 3)))
666 self.assertEquals(cpp_style.Position(1, 1), cpp_style.close_expression(['}{}{', '}'], cpp_style.Position(0, 3)))
667 self.assertEquals(cpp_style.Position(2, -1), cpp_style.close_expression(['][][', ' '], cpp_style.Position(0, 3)))
669 def test_spaces_at_end_of_line(self):
672 'Line ends in whitespace. Consider deleting these extra spaces.'
673 ' [whitespace/end_of_line] [4]')
675 # Test C-style cast cases.
676 def test_cstyle_cast(self):
679 'Using C-style cast. Use static_cast<int>(...) instead'
680 ' [readability/casting] [4]')
682 'int *a = (int *)DEFINED_VALUE;',
683 'Using C-style cast. Use reinterpret_cast<int *>(...) instead'
684 ' [readability/casting] [4]', 'foo.c')
686 'uint16 a = (uint16)1.0;',
687 'Using C-style cast. Use static_cast<uint16>(...) instead'
688 ' [readability/casting] [4]')
690 'int32 a = (int32)1.0;',
691 'Using C-style cast. Use static_cast<int32>(...) instead'
692 ' [readability/casting] [4]')
694 'uint64 a = (uint64)1.0;',
695 'Using C-style cast. Use static_cast<uint64>(...) instead'
696 ' [readability/casting] [4]')
698 # Test taking address of casts (runtime/casting)
699 def test_runtime_casting(self):
701 'int* x = &static_cast<int*>(foo);',
702 'Are you taking an address of a cast? '
703 'This is dangerous: could be a temp var. '
704 'Take the address before doing the cast, rather than after'
705 ' [runtime/casting] [4]')
708 'int* x = &dynamic_cast<int *>(foo);',
709 ['Are you taking an address of a cast? '
710 'This is dangerous: could be a temp var. '
711 'Take the address before doing the cast, rather than after'
712 ' [runtime/casting] [4]',
713 'Do not use dynamic_cast<>. If you need to cast within a class '
714 'hierarchy, use static_cast<> to upcast. Google doesn\'t support '
715 'RTTI. [runtime/rtti] [5]'])
718 'int* x = &reinterpret_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]')
724 # It's OK to cast an address.
726 'int* x = reinterpret_cast<int *>(&foo);',
729 def test_runtime_selfinit(self):
731 'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }',
732 'You seem to be initializing a member variable with itself.'
733 ' [runtime/init] [4]')
735 'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }',
738 'Foo::Foo(Bar r) : r_(r), l_(r_), ll_(l_) { }',
741 def test_runtime_rtti(self):
742 statement = 'int* x = dynamic_cast<int*>(&foo);'
744 'Do not use dynamic_cast<>. If you need to cast within a class '
745 'hierarchy, use static_cast<> to upcast. Google doesn\'t support '
746 'RTTI. [runtime/rtti] [5]')
747 # dynamic_cast is disallowed in most files.
748 self.assert_language_rules_check('foo.cpp', statement, error_message)
749 self.assert_language_rules_check('foo.h', statement, error_message)
751 # We cannot test this functionality because of difference of
752 # function definitions. Anyway, we may never enable this.
754 # # Test for unnamed arguments in a method.
755 # def test_check_for_unnamed_params(self):
756 # message = ('All parameters should be named in a function'
757 # ' [readability/function] [3]')
758 # self.assert_lint('virtual void A(int*) const;', message)
759 # self.assert_lint('virtual void B(void (*fn)(int*));', message)
760 # self.assert_lint('virtual void C(int*);', message)
761 # self.assert_lint('void *(*f)(void *) = x;', message)
762 # self.assert_lint('void Method(char*) {', message)
763 # self.assert_lint('void Method(char*);', message)
764 # self.assert_lint('void Method(char* /*x*/);', message)
765 # self.assert_lint('typedef void (*Method)(int32);', message)
766 # self.assert_lint('static void operator delete[](void*) throw();', message)
768 # self.assert_lint('virtual void D(int* p);', '')
769 # self.assert_lint('void operator delete(void* x) throw();', '')
770 # self.assert_lint('void Method(char* x)\n{', '')
771 # self.assert_lint('void Method(char* /*x*/)\n{', '')
772 # self.assert_lint('void Method(char* x);', '')
773 # self.assert_lint('typedef void (*Method)(int32 x);', '')
774 # self.assert_lint('static void operator delete[](void* x) throw();', '')
775 # self.assert_lint('static void operator delete[](void* /*x*/) throw();', '')
777 # # This one should technically warn, but doesn't because the function
778 # # pointer is confusing.
779 # self.assert_lint('virtual void E(void (*fn)(int* p));', '')
781 # Test deprecated casts such as int(d)
782 def test_deprecated_cast(self):
785 'Using deprecated casting style. '
786 'Use static_cast<int>(...) instead'
787 ' [readability/casting] [4]')
788 # Checks for false positives...
790 'int a = int(); // Constructor, o.k.',
793 'X::X() : a(int()) { } // default Constructor, o.k.',
796 'operator bool(); // Conversion operator, o.k.',
799 # The second parameter to a gMock method definition is a function signature
800 # that often looks like a bad cast but should not picked up by lint.
801 def test_mock_method(self):
803 'MOCK_METHOD0(method, int());',
806 'MOCK_CONST_METHOD1(method, float(string));',
809 'MOCK_CONST_METHOD2_T(method, double(float, float));',
812 # Test sizeof(type) cases.
813 def test_sizeof_type(self):
816 'Using sizeof(type). Use sizeof(varname) instead if possible'
817 ' [runtime/sizeof] [1]')
820 'Using sizeof(type). Use sizeof(varname) instead if possible'
821 ' [runtime/sizeof] [1]')
823 # Test typedef cases. There was a bug that cpp_style misidentified
824 # typedef for pointer to function as C-style cast and produced
825 # false-positive error messages.
826 def test_typedef_for_pointer_to_function(self):
828 'typedef void (*Func)(int x);',
831 'typedef void (*Func)(int *x);',
834 'typedef void Func(int x);',
837 'typedef void Func(int *x);',
840 def test_include_what_you_use_no_implementation_files(self):
841 code = 'std::vector<int> foo;'
842 self.assertEquals('Add #include <vector> for vector<>'
843 ' [build/include_what_you_use] [4]',
844 self.perform_include_what_you_use(code, 'foo.h'))
845 self.assertEquals('',
846 self.perform_include_what_you_use(code, 'foo.cpp'))
848 def test_include_what_you_use(self):
849 self.assert_include_what_you_use(
851 std::vector<int> foo;
854 self.assert_include_what_you_use(
856 std::pair<int,int> foo;
859 self.assert_include_what_you_use(
860 '''#include <multimap>
861 std::pair<int,int> foo;
864 self.assert_include_what_you_use(
865 '''#include <hash_map>
866 std::pair<int,int> foo;
869 self.assert_include_what_you_use(
870 '''#include <utility>
871 std::pair<int,int> foo;
874 self.assert_include_what_you_use(
876 DECLARE_string(foobar);
879 self.assert_include_what_you_use(
881 DEFINE_string(foobar, "", "");
884 self.assert_include_what_you_use(
886 std::pair<int,int> foo;
888 'Add #include <utility> for pair<>'
889 ' [build/include_what_you_use] [4]')
890 self.assert_include_what_you_use(
891 '''#include "base/foobar.h"
892 std::vector<int> foo;
894 'Add #include <vector> for vector<>'
895 ' [build/include_what_you_use] [4]')
896 self.assert_include_what_you_use(
900 'Add #include <set> for set<>'
901 ' [build/include_what_you_use] [4]')
902 self.assert_include_what_you_use(
903 '''#include "base/foobar.h"
904 hash_map<int, int> foobar;
906 'Add #include <hash_map> for hash_map<>'
907 ' [build/include_what_you_use] [4]')
908 self.assert_include_what_you_use(
909 '''#include "base/foobar.h"
910 bool foobar = std::less<int>(0,1);
912 'Add #include <functional> for less<>'
913 ' [build/include_what_you_use] [4]')
914 self.assert_include_what_you_use(
915 '''#include "base/foobar.h"
916 bool foobar = min<int>(0,1);
918 'Add #include <algorithm> for min [build/include_what_you_use] [4]')
919 self.assert_include_what_you_use(
920 'void a(const string &foobar);',
921 'Add #include <string> for string [build/include_what_you_use] [4]')
922 self.assert_include_what_you_use(
923 '''#include "base/foobar.h"
924 bool foobar = swap(0,1);
926 'Add #include <algorithm> for swap [build/include_what_you_use] [4]')
927 self.assert_include_what_you_use(
928 '''#include "base/foobar.h"
929 bool foobar = transform(a.begin(), a.end(), b.start(), Foo);
931 'Add #include <algorithm> for transform '
932 '[build/include_what_you_use] [4]')
933 self.assert_include_what_you_use(
934 '''#include "base/foobar.h"
935 bool foobar = min_element(a.begin(), a.end());
937 'Add #include <algorithm> for min_element '
938 '[build/include_what_you_use] [4]')
939 self.assert_include_what_you_use(
944 self.assert_include_what_you_use(
946 void a(const std::multimap<int,string> &foobar);
948 'Add #include <map> for multimap<>'
949 ' [build/include_what_you_use] [4]')
950 self.assert_include_what_you_use(
952 void a(const std::priority_queue<int> &foobar);
955 self.assert_include_what_you_use(
956 '''#include "base/basictypes.h"
957 #include "base/port.h"
961 vector<string> hajoa;''', '')
962 self.assert_include_what_you_use(
964 int i = numeric_limits<int>::max()
966 'Add #include <limits> for numeric_limits<>'
967 ' [build/include_what_you_use] [4]')
968 self.assert_include_what_you_use(
970 int i = numeric_limits<int>::max()
974 # Test the UpdateIncludeState code path.
975 mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"']
976 message = self.perform_include_what_you_use(
977 '#include "config.h"\n'
978 '#include "blah/a.h"\n',
979 filename='blah/a.cpp',
980 io=MockIo(mock_header_contents))
981 self.assertEquals(message, '')
983 mock_header_contents = ['#include <set>']
984 message = self.perform_include_what_you_use(
985 '''#include "config.h"
988 std::set<int> foo;''',
989 filename='blah/a.cpp',
990 io=MockIo(mock_header_contents))
991 self.assertEquals(message, '')
993 # If there's just a .cpp and the header can't be found then it's ok.
994 message = self.perform_include_what_you_use(
995 '''#include "config.h"
998 std::set<int> foo;''',
999 filename='blah/a.cpp')
1000 self.assertEquals(message, '')
1002 # Make sure we find the headers with relative paths.
1003 mock_header_contents = ['']
1004 message = self.perform_include_what_you_use(
1005 '''#include "config.h"
1008 std::set<int> foo;''' % (os.path.basename(os.getcwd()), os.path.sep),
1010 io=MockIo(mock_header_contents))
1011 self.assertEquals(message, 'Add #include <set> for set<> '
1012 '[build/include_what_you_use] [4]')
1014 def test_files_belong_to_same_module(self):
1015 f = cpp_style.files_belong_to_same_module
1016 self.assertEquals((True, ''), f('a.cpp', 'a.h'))
1017 self.assertEquals((True, ''), f('base/google.cpp', 'base/google.h'))
1018 self.assertEquals((True, ''), f('base/google_test.cpp', 'base/google.h'))
1019 self.assertEquals((True, ''),
1020 f('base/google_unittest.cpp', 'base/google.h'))
1021 self.assertEquals((True, ''),
1022 f('base/internal/google_unittest.cpp',
1023 'base/public/google.h'))
1024 self.assertEquals((True, 'xxx/yyy/'),
1025 f('xxx/yyy/base/internal/google_unittest.cpp',
1026 'base/public/google.h'))
1027 self.assertEquals((True, 'xxx/yyy/'),
1028 f('xxx/yyy/base/google_unittest.cpp',
1029 'base/public/google.h'))
1030 self.assertEquals((True, ''),
1031 f('base/google_unittest.cpp', 'base/google-inl.h'))
1032 self.assertEquals((True, '/home/build/google3/'),
1033 f('/home/build/google3/base/google.cpp', 'base/google.h'))
1035 self.assertEquals((False, ''),
1036 f('/home/build/google3/base/google.cpp', 'basu/google.h'))
1037 self.assertEquals((False, ''), f('a.cpp', 'b.h'))
1039 def test_cleanse_line(self):
1040 self.assertEquals('int foo = 0; ',
1041 cpp_style.cleanse_comments('int foo = 0; // danger!'))
1042 self.assertEquals('int o = 0;',
1043 cpp_style.cleanse_comments('int /* foo */ o = 0;'))
1044 self.assertEquals('foo(int a, int b);',
1045 cpp_style.cleanse_comments('foo(int a /* abc */, int b);'))
1046 self.assertEqual('f(a, b);',
1047 cpp_style.cleanse_comments('f(a, /* name */ b);'))
1048 self.assertEqual('f(a, b);',
1049 cpp_style.cleanse_comments('f(a /* name */, b);'))
1050 self.assertEqual('f(a, b);',
1051 cpp_style.cleanse_comments('f(a, /* name */b);'))
1053 def test_multi_line_comments(self):
1054 # missing explicit is bad
1055 self.assert_multi_line_lint(
1059 Foo(int f); // should cause a lint warning in code
1063 self.assert_multi_line_lint(
1064 r'''/* int a = 0; multi-liner
1065 static const int b = 0;''',
1066 ['Could not find end of multi-line comment'
1067 ' [readability/multiline_comment] [5]',
1068 'Complex multi-line /*...*/-style comment found. '
1069 'Lint may give bogus warnings. Consider replacing these with '
1070 '//-style comments, with #if 0...#endif, or with more clearly '
1071 'structured multi-line comments. [readability/multiline_comment] [5]'])
1072 self.assert_multi_line_lint(r''' /* multi-line comment''',
1073 ['Could not find end of multi-line comment'
1074 ' [readability/multiline_comment] [5]',
1075 'Complex multi-line /*...*/-style comment found. '
1076 'Lint may give bogus warnings. Consider replacing these with '
1077 '//-style comments, with #if 0...#endif, or with more clearly '
1078 'structured multi-line comments. [readability/multiline_comment] [5]'])
1079 self.assert_multi_line_lint(r''' // /* comment, but not multi-line''', '')
1081 def test_multiline_strings(self):
1082 multiline_string_error_message = (
1083 'Multi-line string ("...") found. This lint script doesn\'t '
1084 'do well with such strings, and may give bogus warnings. They\'re '
1085 'ugly and unnecessary, and you should use concatenation instead".'
1086 ' [readability/multiline_string] [5]')
1088 file_path = 'mydir/foo.cpp'
1090 error_collector = ErrorCollector(self.assert_)
1091 self.process_file_data(file_path, 'cpp',
1092 ['const char* str = "This is a\\',
1093 ' multiline string.";'],
1097 error_collector.result_list().count(multiline_string_error_message))
1099 # Test non-explicit single-argument constructors
1100 def test_explicit_single_argument_constructors(self):
1101 # missing explicit is bad
1102 self.assert_multi_line_lint(
1106 'Single-argument constructors should be marked explicit.'
1107 ' [runtime/explicit] [5]')
1108 # missing explicit is bad, even with whitespace
1109 self.assert_multi_line_lint(
1113 ['Extra space before ( in function call [whitespace/parens] [4]',
1114 'Single-argument constructors should be marked explicit.'
1115 ' [runtime/explicit] [5]'])
1116 # missing explicit, with distracting comment, is still bad
1117 self.assert_multi_line_lint(
1119 Foo(int f); // simpler than Foo(blargh, blarg)
1121 'Single-argument constructors should be marked explicit.'
1122 ' [runtime/explicit] [5]')
1123 # missing explicit, with qualified classname
1124 self.assert_multi_line_lint(
1125 '''class Qualifier::AnotherOne::Foo {
1128 'Single-argument constructors should be marked explicit.'
1129 ' [runtime/explicit] [5]')
1130 # structs are caught as well.
1131 self.assert_multi_line_lint(
1135 'Single-argument constructors should be marked explicit.'
1136 ' [runtime/explicit] [5]')
1137 # Templatized classes are caught as well.
1138 self.assert_multi_line_lint(
1139 '''template<typename T> class Foo {
1142 'Single-argument constructors should be marked explicit.'
1143 ' [runtime/explicit] [5]')
1144 # proper style is okay
1145 self.assert_multi_line_lint(
1147 explicit Foo(int f);
1150 # two argument constructor is okay
1151 self.assert_multi_line_lint(
1156 # two argument constructor, across two lines, is okay
1157 self.assert_multi_line_lint(
1163 # non-constructor (but similar name), is okay
1164 self.assert_multi_line_lint(
1169 # constructor with void argument is okay
1170 self.assert_multi_line_lint(
1175 # single argument method is okay
1176 self.assert_multi_line_lint(
1181 # comments should be ignored
1182 self.assert_multi_line_lint(
1187 # single argument function following class definition is okay
1188 # (okay, it's not actually valid, but we don't want a false positive)
1189 self.assert_multi_line_lint(
1195 # single argument function is okay
1196 self.assert_multi_line_lint(
1197 '''static Foo(int f);''',
1199 # single argument copy constructor is okay.
1200 self.assert_multi_line_lint(
1205 self.assert_multi_line_lint(
1211 def test_slash_star_comment_on_single_line(self):
1212 self.assert_multi_line_lint(
1213 '''/* static */ Foo(int f);''',
1215 self.assert_multi_line_lint(
1216 '''/*/ static */ Foo(int f);''',
1218 self.assert_multi_line_lint(
1219 '''/*/ static Foo(int f);''',
1220 'Could not find end of multi-line comment'
1221 ' [readability/multiline_comment] [5]')
1222 self.assert_multi_line_lint(
1223 ''' /*/ static Foo(int f);''',
1224 'Could not find end of multi-line comment'
1225 ' [readability/multiline_comment] [5]')
1226 self.assert_multi_line_lint(
1227 ''' /**/ static Foo(int f);''',
1230 # Test suspicious usage of "if" like this:
1233 # } if (a == c) { // Should be "else if".
1234 # DoSomething(); // This gets called twice if a == b && a == c.
1236 def test_suspicious_usage_of_if(self):
1242 'Did you mean "else if"? If not, start a new line for "if".'
1243 ' [readability/braces] [4]')
1245 # Test suspicious usage of memset. Specifically, a 0
1246 # as the final argument is almost certainly an error.
1247 def test_suspicious_usage_of_memset(self):
1248 # Normal use is okay.
1250 ' memset(buf, 0, sizeof(buf))',
1253 # A 0 as the final argument is almost certainly an error.
1255 ' memset(buf, sizeof(buf), 0)',
1256 'Did you mean "memset(buf, 0, sizeof(buf))"?'
1257 ' [runtime/memset] [4]')
1259 ' memset(buf, xsize * ysize, 0)',
1260 'Did you mean "memset(buf, 0, xsize * ysize)"?'
1261 ' [runtime/memset] [4]')
1263 # There is legitimate test code that uses this form.
1264 # This is okay since the second argument is a literal.
1266 " memset(buf, 'y', 0)",
1269 ' memset(buf, 4, 0)',
1272 ' memset(buf, -1, 0)',
1275 ' memset(buf, 0xF1, 0)',
1278 ' memset(buf, 0xcd, 0)',
1281 def test_check_posix_threading(self):
1282 self.assert_lint('sctime_r()', '')
1283 self.assert_lint('strtok_r()', '')
1284 self.assert_lint(' strtok_r(foo, ba, r)', '')
1285 self.assert_lint('brand()', '')
1286 self.assert_lint('_rand()', '')
1287 self.assert_lint('.rand()', '')
1288 self.assert_lint('>rand()', '')
1289 self.assert_lint('rand()',
1290 'Consider using rand_r(...) instead of rand(...)'
1291 ' for improved thread safety.'
1292 ' [runtime/threadsafe_fn] [2]')
1293 self.assert_lint('strtok()',
1294 'Consider using strtok_r(...) '
1295 'instead of strtok(...)'
1296 ' for improved thread safety.'
1297 ' [runtime/threadsafe_fn] [2]')
1299 # Test potential format string bugs like printf(foo).
1300 def test_format_strings(self):
1301 self.assert_lint('printf("foo")', '')
1302 self.assert_lint('printf("foo: %s", foo)', '')
1303 self.assert_lint('DocidForPrintf(docid)', '') # Should not trigger.
1306 'Potential format string bug. Do printf("%s", foo) instead.'
1307 ' [runtime/printf] [4]')
1309 'printf(foo.c_str())',
1310 'Potential format string bug. '
1311 'Do printf("%s", foo.c_str()) instead.'
1312 ' [runtime/printf] [4]')
1314 'printf(foo->c_str())',
1315 'Potential format string bug. '
1316 'Do printf("%s", foo->c_str()) instead.'
1317 ' [runtime/printf] [4]')
1319 'StringPrintf(foo)',
1320 'Potential format string bug. Do StringPrintf("%s", foo) instead.'
1322 ' [runtime/printf] [4]')
1324 # Variable-length arrays are not permitted.
1325 def test_variable_length_array_detection(self):
1326 errmsg = ('Do not use variable-length arrays. Use an appropriately named '
1327 "('k' followed by CamelCase) compile-time constant for the size."
1328 ' [runtime/arrays] [1]')
1330 self.assert_lint('int a[any_old_variable];', errmsg)
1331 self.assert_lint('int doublesize[some_var * 2];', errmsg)
1332 self.assert_lint('int a[afunction()];', errmsg)
1333 self.assert_lint('int a[function(kMaxFooBars)];', errmsg)
1334 self.assert_lint('bool aList[items_->size()];', errmsg)
1335 self.assert_lint('namespace::Type buffer[len+1];', errmsg)
1337 self.assert_lint('int a[64];', '')
1338 self.assert_lint('int a[0xFF];', '')
1339 self.assert_lint('int first[256], second[256];', '')
1340 self.assert_lint('int arrayName[kCompileTimeConstant];', '')
1341 self.assert_lint('char buf[somenamespace::kBufSize];', '')
1342 self.assert_lint('int arrayName[ALL_CAPS];', '')
1343 self.assert_lint('AClass array1[foo::bar::ALL_CAPS];', '')
1344 self.assert_lint('int a[kMaxStrLen + 1];', '')
1345 self.assert_lint('int a[sizeof(foo)];', '')
1346 self.assert_lint('int a[sizeof(*foo)];', '')
1347 self.assert_lint('int a[sizeof foo];', '')
1348 self.assert_lint('int a[sizeof(struct Foo)];', '')
1349 self.assert_lint('int a[128 - sizeof(const bar)];', '')
1350 self.assert_lint('int a[(sizeof(foo) * 4)];', '')
1351 self.assert_lint('int a[(arraysize(fixed_size_array)/2) << 1];', 'Missing spaces around / [whitespace/operators] [3]')
1352 self.assert_lint('delete a[some_var];', '')
1353 self.assert_lint('return a[some_var];', '')
1356 def test_braces(self):
1357 # Braces shouldn't be followed by a ; unless they're defining a struct
1358 # or initializing an array
1359 self.assert_lint('int a[3] = { 1, 2, 3 };', '')
1361 '''const int foo[] =
1364 # For single line, unmatched '}' with a ';' is ignored (not enough context)
1365 self.assert_multi_line_lint(
1370 self.assert_multi_line_lint(
1371 '''int a[2][3] = { { 1, 2 },
1374 self.assert_multi_line_lint(
1380 # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements
1381 def test_check_check(self):
1382 self.assert_lint('CHECK(x == 42)',
1383 'Consider using CHECK_EQ instead of CHECK(a == b)'
1384 ' [readability/check] [2]')
1385 self.assert_lint('CHECK(x != 42)',
1386 'Consider using CHECK_NE instead of CHECK(a != b)'
1387 ' [readability/check] [2]')
1388 self.assert_lint('CHECK(x >= 42)',
1389 'Consider using CHECK_GE instead of CHECK(a >= b)'
1390 ' [readability/check] [2]')
1391 self.assert_lint('CHECK(x > 42)',
1392 'Consider using CHECK_GT instead of CHECK(a > b)'
1393 ' [readability/check] [2]')
1394 self.assert_lint('CHECK(x <= 42)',
1395 'Consider using CHECK_LE instead of CHECK(a <= b)'
1396 ' [readability/check] [2]')
1397 self.assert_lint('CHECK(x < 42)',
1398 'Consider using CHECK_LT instead of CHECK(a < b)'
1399 ' [readability/check] [2]')
1401 self.assert_lint('DCHECK(x == 42)',
1402 'Consider using DCHECK_EQ instead of DCHECK(a == b)'
1403 ' [readability/check] [2]')
1404 self.assert_lint('DCHECK(x != 42)',
1405 'Consider using DCHECK_NE instead of DCHECK(a != b)'
1406 ' [readability/check] [2]')
1407 self.assert_lint('DCHECK(x >= 42)',
1408 'Consider using DCHECK_GE instead of DCHECK(a >= b)'
1409 ' [readability/check] [2]')
1410 self.assert_lint('DCHECK(x > 42)',
1411 'Consider using DCHECK_GT instead of DCHECK(a > b)'
1412 ' [readability/check] [2]')
1413 self.assert_lint('DCHECK(x <= 42)',
1414 'Consider using DCHECK_LE instead of DCHECK(a <= b)'
1415 ' [readability/check] [2]')
1416 self.assert_lint('DCHECK(x < 42)',
1417 'Consider using DCHECK_LT instead of DCHECK(a < b)'
1418 ' [readability/check] [2]')
1421 'EXPECT_TRUE("42" == x)',
1422 'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)'
1423 ' [readability/check] [2]')
1425 'EXPECT_TRUE("42" != x)',
1426 'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)'
1427 ' [readability/check] [2]')
1429 'EXPECT_TRUE(+42 >= x)',
1430 'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)'
1431 ' [readability/check] [2]')
1433 'EXPECT_TRUE_M(-42 > x)',
1434 'Consider using EXPECT_GT_M instead of EXPECT_TRUE_M(a > b)'
1435 ' [readability/check] [2]')
1437 'EXPECT_TRUE_M(42U <= x)',
1438 'Consider using EXPECT_LE_M instead of EXPECT_TRUE_M(a <= b)'
1439 ' [readability/check] [2]')
1441 'EXPECT_TRUE_M(42L < x)',
1442 'Consider using EXPECT_LT_M instead of EXPECT_TRUE_M(a < b)'
1443 ' [readability/check] [2]')
1446 'EXPECT_FALSE(x == 42)',
1447 'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)'
1448 ' [readability/check] [2]')
1450 'EXPECT_FALSE(x != 42)',
1451 'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)'
1452 ' [readability/check] [2]')
1454 'EXPECT_FALSE(x >= 42)',
1455 'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)'
1456 ' [readability/check] [2]')
1458 'ASSERT_FALSE(x > 42)',
1459 'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)'
1460 ' [readability/check] [2]')
1462 'ASSERT_FALSE(x <= 42)',
1463 'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)'
1464 ' [readability/check] [2]')
1466 'ASSERT_FALSE_M(x < 42)',
1467 'Consider using ASSERT_GE_M instead of ASSERT_FALSE_M(a < b)'
1468 ' [readability/check] [2]')
1470 self.assert_lint('CHECK(some_iterator == obj.end())', '')
1471 self.assert_lint('EXPECT_TRUE(some_iterator == obj.end())', '')
1472 self.assert_lint('EXPECT_FALSE(some_iterator == obj.end())', '')
1474 self.assert_lint('CHECK(CreateTestFile(dir, (1 << 20)));', '')
1475 self.assert_lint('CHECK(CreateTestFile(dir, (1 >> 20)));', '')
1477 self.assert_lint('CHECK(x<42)',
1478 ['Missing spaces around <'
1479 ' [whitespace/operators] [3]',
1480 'Consider using CHECK_LT instead of CHECK(a < b)'
1481 ' [readability/check] [2]'])
1482 self.assert_lint('CHECK(x>42)',
1483 'Consider using CHECK_GT instead of CHECK(a > b)'
1484 ' [readability/check] [2]')
1487 ' EXPECT_TRUE(42 < x) // Random comment.',
1488 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1489 ' [readability/check] [2]')
1491 'EXPECT_TRUE( 42 < x )',
1492 ['Extra space after ( in function call'
1493 ' [whitespace/parens] [4]',
1494 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1495 ' [readability/check] [2]'])
1497 'CHECK("foo" == "foo")',
1498 'Consider using CHECK_EQ instead of CHECK(a == b)'
1499 ' [readability/check] [2]')
1501 self.assert_lint('CHECK_EQ("foo", "foo")', '')
1503 def test_brace_at_begin_of_line(self):
1504 self.assert_lint('{',
1505 'This { should be at the end of the previous line'
1506 ' [whitespace/braces] [4]')
1507 self.assert_multi_line_lint(
1512 self.assert_multi_line_lint(
1515 self.assert_multi_line_lint(
1516 ' MACRO1(macroArg) {',
1518 self.assert_multi_line_lint(
1519 'ACCESSOR_GETTER(MessageEventPorts) {',
1520 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
1521 self.assert_multi_line_lint(
1523 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
1524 self.assert_multi_line_lint(
1525 'int foo() const {',
1526 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
1527 self.assert_multi_line_lint(
1532 self.assert_multi_line_lint(
1535 ' && condition3) {\n'
1539 def test_mismatching_spaces_in_parens(self):
1540 self.assert_lint('if (foo ) {', 'Extra space before ) in if'
1541 ' [whitespace/parens] [5]')
1542 self.assert_lint('switch ( foo) {', 'Extra space after ( in switch'
1543 ' [whitespace/parens] [5]')
1544 self.assert_lint('for (foo; ba; bar ) {', 'Extra space before ) in for'
1545 ' [whitespace/parens] [5]')
1546 self.assert_lint('for ((foo); (ba); (bar) ) {', 'Extra space before ) in for'
1547 ' [whitespace/parens] [5]')
1548 self.assert_lint('for (; foo; bar) {', '')
1549 self.assert_lint('for (; (foo); (bar)) {', '')
1550 self.assert_lint('for ( ; foo; bar) {', '')
1551 self.assert_lint('for ( ; (foo); (bar)) {', '')
1552 self.assert_lint('for ( ; foo; bar ) {', 'Extra space before ) in for'
1553 ' [whitespace/parens] [5]')
1554 self.assert_lint('for ( ; (foo); (bar) ) {', 'Extra space before ) in for'
1555 ' [whitespace/parens] [5]')
1556 self.assert_lint('for (foo; bar; ) {', '')
1557 self.assert_lint('for ((foo); (bar); ) {', '')
1558 self.assert_lint('foreach (foo, foos ) {', 'Extra space before ) in foreach'
1559 ' [whitespace/parens] [5]')
1560 self.assert_lint('foreach ( foo, foos) {', 'Extra space after ( in foreach'
1561 ' [whitespace/parens] [5]')
1562 self.assert_lint('while ( foo) {', 'Extra space after ( in while'
1563 ' [whitespace/parens] [5]')
1565 def test_spacing_for_fncall(self):
1566 self.assert_lint('if (foo) {', '')
1567 self.assert_lint('for (foo;bar;baz) {', '')
1568 self.assert_lint('foreach (foo, foos) {', '')
1569 self.assert_lint('while (foo) {', '')
1570 self.assert_lint('switch (foo) {', '')
1571 self.assert_lint('new (RenderArena()) RenderInline(document())', '')
1572 self.assert_lint('foo( bar)', 'Extra space after ( in function call'
1573 ' [whitespace/parens] [4]')
1574 self.assert_lint('foobar( \\', '')
1575 self.assert_lint('foobar( \\', '')
1576 self.assert_lint('( a + b)', 'Extra space after ('
1577 ' [whitespace/parens] [2]')
1578 self.assert_lint('((a+b))', '')
1579 self.assert_lint('foo (foo)', 'Extra space before ( in function call'
1580 ' [whitespace/parens] [4]')
1581 self.assert_lint('#elif (foo(bar))', '')
1582 self.assert_lint('#elif (foo(bar) && foo(baz))', '')
1583 self.assert_lint('typedef foo (*foo)(foo)', '')
1584 self.assert_lint('typedef foo (*foo12bar_)(foo)', '')
1585 self.assert_lint('typedef foo (Foo::*bar)(foo)', '')
1586 self.assert_lint('foo (Foo::*bar)(',
1587 'Extra space before ( in function call'
1588 ' [whitespace/parens] [4]')
1589 self.assert_lint('typedef foo (Foo::*bar)(', '')
1590 self.assert_lint('(foo)(bar)', '')
1591 self.assert_lint('Foo (*foo)(bar)', '')
1592 self.assert_lint('Foo (*foo)(Bar bar,', '')
1593 self.assert_lint('char (*p)[sizeof(foo)] = &foo', '')
1594 self.assert_lint('char (&ref)[sizeof(foo)] = &foo', '')
1595 self.assert_lint('const char32 (*table[])[6];', '')
1597 def test_spacing_before_braces(self):
1598 self.assert_lint('if (foo){', 'Missing space before {'
1599 ' [whitespace/braces] [5]')
1600 self.assert_lint('for{', 'Missing space before {'
1601 ' [whitespace/braces] [5]')
1602 self.assert_lint('for {', '')
1603 self.assert_lint('EXPECT_DEBUG_DEATH({', '')
1605 def test_spacing_between_braces(self):
1606 self.assert_lint(' { }', '')
1607 self.assert_lint(' {}', 'Missing space inside { }. [whitespace/braces] [5]')
1608 self.assert_lint(' { }', 'Too many spaces inside { }. [whitespace/braces] [5]')
1610 def test_spacing_around_else(self):
1611 self.assert_lint('}else {', 'Missing space before else'
1612 ' [whitespace/braces] [5]')
1613 self.assert_lint('} else{', 'Missing space before {'
1614 ' [whitespace/braces] [5]')
1615 self.assert_lint('} else {', '')
1616 self.assert_lint('} else if', '')
1618 def test_spacing_for_binary_ops(self):
1619 self.assert_lint('if (foo<=bar) {', 'Missing spaces around <='
1620 ' [whitespace/operators] [3]')
1621 self.assert_lint('if (foo<bar) {', 'Missing spaces around <'
1622 ' [whitespace/operators] [3]')
1623 self.assert_lint('if (foo<bar->baz) {', 'Missing spaces around <'
1624 ' [whitespace/operators] [3]')
1625 self.assert_lint('if (foo<bar->bar) {', 'Missing spaces around <'
1626 ' [whitespace/operators] [3]')
1627 self.assert_lint('typedef hash_map<Foo, Bar', 'Missing spaces around <'
1628 ' [whitespace/operators] [3]')
1629 self.assert_lint('typedef hash_map<FoooooType, BaaaaarType,', '')
1630 self.assert_lint('a<Foo> t+=b;', 'Missing spaces around +='
1631 ' [whitespace/operators] [3]')
1632 self.assert_lint('a<Foo> t-=b;', 'Missing spaces around -='
1633 ' [whitespace/operators] [3]')
1634 self.assert_lint('a<Foo*> t*=b;', 'Missing spaces around *='
1635 ' [whitespace/operators] [3]')
1636 self.assert_lint('a<Foo*> t/=b;', 'Missing spaces around /='
1637 ' [whitespace/operators] [3]')
1638 self.assert_lint('a<Foo*> t|=b;', 'Missing spaces around |='
1639 ' [whitespace/operators] [3]')
1640 self.assert_lint('a<Foo*> t&=b;', 'Missing spaces around &='
1641 ' [whitespace/operators] [3]')
1642 self.assert_lint('a<Foo*> t<<=b;', 'Missing spaces around <<='
1643 ' [whitespace/operators] [3]')
1644 self.assert_lint('a<Foo*> t>>=b;', 'Missing spaces around >>='
1645 ' [whitespace/operators] [3]')
1646 self.assert_lint('a<Foo*> t>>=&b|c;', 'Missing spaces around >>='
1647 ' [whitespace/operators] [3]')
1648 self.assert_lint('a<Foo*> t<<=*b/c;', 'Missing spaces around <<='
1649 ' [whitespace/operators] [3]')
1650 self.assert_lint('a<Foo> t -= b;', '')
1651 self.assert_lint('a<Foo> t += b;', '')
1652 self.assert_lint('a<Foo*> t *= b;', '')
1653 self.assert_lint('a<Foo*> t /= b;', '')
1654 self.assert_lint('a<Foo*> t |= b;', '')
1655 self.assert_lint('a<Foo*> t &= b;', '')
1656 self.assert_lint('a<Foo*> t <<= b;', '')
1657 self.assert_lint('a<Foo*> t >>= b;', '')
1658 self.assert_lint('a<Foo*> t >>= &b|c;', 'Missing spaces around |'
1659 ' [whitespace/operators] [3]')
1660 self.assert_lint('a<Foo*> t <<= *b/c;', 'Missing spaces around /'
1661 ' [whitespace/operators] [3]')
1662 self.assert_lint('a<Foo*> t <<= b/c; //Test', [
1663 'Should have a space between // and comment '
1664 '[whitespace/comments] [4]', 'Missing'
1665 ' spaces around / [whitespace/operators] [3]'])
1666 self.assert_lint('a<Foo*> t <<= b||c; //Test', ['One space before end'
1667 ' of line comments [whitespace/comments] [5]',
1668 'Should have a space between // and comment '
1669 '[whitespace/comments] [4]',
1670 'Missing spaces around || [whitespace/operators] [3]'])
1671 self.assert_lint('a<Foo*> t <<= b&&c; // Test', 'Missing spaces around'
1672 ' && [whitespace/operators] [3]')
1673 self.assert_lint('a<Foo*> t <<= b&&&c; // Test', 'Missing spaces around'
1674 ' && [whitespace/operators] [3]')
1675 self.assert_lint('a<Foo*> t <<= b&&*c; // Test', 'Missing spaces around'
1676 ' && [whitespace/operators] [3]')
1677 self.assert_lint('a<Foo*> t <<= b && *c; // Test', '')
1678 self.assert_lint('a<Foo*> t <<= b && &c; // Test', '')
1679 self.assert_lint('a<Foo*> t <<= b || &c; /*Test', 'Complex multi-line '
1680 '/*...*/-style comment found. Lint may give bogus '
1681 'warnings. Consider replacing these with //-style'
1682 ' comments, with #if 0...#endif, or with more clearly'
1683 ' structured multi-line comments. [readability/multiline_comment] [5]')
1684 self.assert_lint('a<Foo&> t <<= &b | &c;', '')
1685 self.assert_lint('a<Foo*> t <<= &b & &c; // Test', '')
1686 self.assert_lint('a<Foo*> t <<= *b / &c; // Test', '')
1687 self.assert_lint('if (a=b == 1)', 'Missing spaces around = [whitespace/operators] [4]')
1688 self.assert_lint('a = 1<<20', 'Missing spaces around << [whitespace/operators] [3]')
1689 self.assert_lint('if (a = b == 1)', '')
1690 self.assert_lint('a = 1 << 20', '')
1691 self.assert_multi_line_lint('#include <sys/io.h>\n', '')
1692 self.assert_multi_line_lint('#import <foo/bar.h>\n', '')
1694 def test_operator_methods(self):
1695 self.assert_lint('String operator+(const String&, const String&);', '')
1696 self.assert_lint('bool operator==(const String&, const String&);', '')
1697 self.assert_lint('String& operator-=(const String&, const String&);', '')
1698 self.assert_lint('String& operator+=(const String&, const String&);', '')
1699 self.assert_lint('String& operator*=(const String&, const String&);', '')
1700 self.assert_lint('String& operator%=(const String&, const String&);', '')
1701 self.assert_lint('String& operator&=(const String&, const String&);', '')
1702 self.assert_lint('String& operator<<=(const String&, const String&);', '')
1703 self.assert_lint('String& operator>>=(const String&, const String&);', '')
1704 self.assert_lint('String& operator|=(const String&, const String&);', '')
1705 self.assert_lint('String& operator^=(const String&, const String&);', '')
1707 def test_spacing_before_last_semicolon(self):
1708 self.assert_lint('call_function() ;',
1709 'Extra space before last semicolon. If this should be an '
1710 'empty statement, use { } instead.'
1711 ' [whitespace/semicolon] [5]')
1712 self.assert_lint('while (true) ;',
1713 'Extra space before last semicolon. If this should be an '
1714 'empty statement, use { } instead.'
1715 ' [whitespace/semicolon] [5]')
1716 self.assert_lint('default:;',
1717 'Semicolon defining empty statement. Use { } instead.'
1718 ' [whitespace/semicolon] [5]')
1719 self.assert_lint(' ;',
1720 'Line contains only semicolon. If this should be an empty '
1721 'statement, use { } instead.'
1722 ' [whitespace/semicolon] [5]')
1723 self.assert_lint('for (int i = 0; ;', '')
1725 # Static or global STL strings.
1726 def test_static_or_global_stlstrings(self):
1727 self.assert_lint('string foo;',
1728 'For a static/global string constant, use a C style '
1729 'string instead: "char foo[]".'
1730 ' [runtime/string] [4]')
1731 self.assert_lint('string kFoo = "hello"; // English',
1732 'For a static/global string constant, use a C style '
1733 'string instead: "char kFoo[]".'
1734 ' [runtime/string] [4]')
1735 self.assert_lint('static string foo;',
1736 'For a static/global string constant, use a C style '
1737 'string instead: "static char foo[]".'
1738 ' [runtime/string] [4]')
1739 self.assert_lint('static const string foo;',
1740 'For a static/global string constant, use a C style '
1741 'string instead: "static const char foo[]".'
1742 ' [runtime/string] [4]')
1743 self.assert_lint('string Foo::bar;',
1744 'For a static/global string constant, use a C style '
1745 'string instead: "char Foo::bar[]".'
1746 ' [runtime/string] [4]')
1748 self.assert_lint('string foo("foobar");',
1749 'For a static/global string constant, use a C style '
1750 'string instead: "char foo[]".'
1751 ' [runtime/string] [4]')
1752 # Should not catch local or member variables.
1753 self.assert_lint(' string foo', '')
1754 # Should not catch functions.
1755 self.assert_lint('string EmptyString() { return ""; }', '')
1756 self.assert_lint('string EmptyString () { return ""; }', '')
1757 self.assert_lint('string VeryLongNameFunctionSometimesEndsWith(\n'
1758 ' VeryLongNameType veryLongNameVariable) { }', '')
1759 self.assert_lint('template<>\n'
1760 'string FunctionTemplateSpecialization<SomeType>(\n'
1761 ' int x) { return ""; }', '')
1762 self.assert_lint('template<>\n'
1763 'string FunctionTemplateSpecialization<vector<A::B>* >(\n'
1764 ' int x) { return ""; }', '')
1766 # should not catch methods of template classes.
1767 self.assert_lint('string Class<Type>::Method() const\n'
1771 self.assert_lint('string Class<Type>::Method(\n'
1777 def test_no_spaces_in_function_calls(self):
1778 self.assert_lint('TellStory(1, 3);',
1780 self.assert_lint('TellStory(1, 3 );',
1781 'Extra space before )'
1782 ' [whitespace/parens] [2]')
1783 self.assert_lint('TellStory(1 /* wolf */, 3 /* pigs */);',
1785 self.assert_multi_line_lint('#endif\n );',
1788 def test_one_spaces_between_code_and_comments(self):
1789 self.assert_lint('} // namespace foo',
1791 self.assert_lint('}// namespace foo',
1792 'One space before end of line comments'
1793 ' [whitespace/comments] [5]')
1794 self.assert_lint('printf("foo"); // Outside quotes.',
1796 self.assert_lint('int i = 0; // Having one space is fine.','')
1797 self.assert_lint('int i = 0; // Having two spaces is bad.',
1798 'One space before end of line comments'
1799 ' [whitespace/comments] [5]')
1800 self.assert_lint('int i = 0; // Having three spaces is bad.',
1801 'One space before end of line comments'
1802 ' [whitespace/comments] [5]')
1803 self.assert_lint('// Top level comment', '')
1804 self.assert_lint(' // Line starts with four spaces.', '')
1805 self.assert_lint('foo();\n'
1806 '{ // A scope is opening.', '')
1807 self.assert_lint(' foo();\n'
1808 ' { // An indented scope is opening.', '')
1809 self.assert_lint('if (foo) { // not a pure scope',
1811 self.assert_lint('printf("// In quotes.")', '')
1812 self.assert_lint('printf("\\"%s // In quotes.")', '')
1813 self.assert_lint('printf("%s", "// In quotes.")', '')
1815 def test_one_spaces_after_punctuation_in_comments(self):
1816 self.assert_lint('int a; // This is a sentence.',
1818 self.assert_lint('int a; // This is a sentence. ',
1819 'Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4]')
1820 self.assert_lint('int a; // This is a sentence. This is a another sentence.',
1822 self.assert_lint('int a; // This is a sentence. This is a another sentence.',
1823 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1824 self.assert_lint('int a; // This is a sentence! This is a another sentence.',
1825 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1826 self.assert_lint('int a; // Why did I write this? This is a another sentence.',
1827 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1828 self.assert_lint('int a; // Elementary, my dear.',
1829 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1830 self.assert_lint('int a; // The following should be clear: Is it?',
1831 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1832 self.assert_lint('int a; // Look at the follow semicolon; I hope this gives an error.',
1833 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1835 def test_space_after_comment_marker(self):
1836 self.assert_lint('//', '')
1837 self.assert_lint('//x', 'Should have a space between // and comment'
1838 ' [whitespace/comments] [4]')
1839 self.assert_lint('// x', '')
1840 self.assert_lint('//----', '')
1841 self.assert_lint('//====', '')
1842 self.assert_lint('//////', '')
1843 self.assert_lint('////// x', '')
1844 self.assert_lint('/// x', '')
1845 self.assert_lint('////x', 'Should have a space between // and comment'
1846 ' [whitespace/comments] [4]')
1848 def test_newline_at_eof(self):
1849 def do_test(self, data, is_missing_eof):
1850 error_collector = ErrorCollector(self.assert_)
1851 self.process_file_data('foo.cpp', 'cpp', data.split('\n'),
1853 # The warning appears only once.
1855 int(is_missing_eof),
1856 error_collector.results().count(
1857 'Could not find a newline character at the end of the file.'
1858 ' [whitespace/ending_newline] [5]'))
1860 do_test(self, '// Newline\n// at EOF\n', False)
1861 do_test(self, '// No newline\n// at EOF', True)
1863 def test_invalid_utf8(self):
1864 def do_test(self, raw_bytes, has_invalid_utf8):
1865 error_collector = ErrorCollector(self.assert_)
1866 self.process_file_data('foo.cpp', 'cpp',
1867 unicode(raw_bytes, 'utf8', 'replace').split('\n'),
1869 # The warning appears only once.
1871 int(has_invalid_utf8),
1872 error_collector.results().count(
1873 'Line contains invalid UTF-8'
1874 ' (or Unicode replacement character).'
1875 ' [readability/utf8] [5]'))
1877 do_test(self, 'Hello world\n', False)
1878 do_test(self, '\xe9\x8e\xbd\n', False)
1879 do_test(self, '\xe9x\x8e\xbd\n', True)
1880 # This is the encoding of the replacement character itself (which
1881 # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')).
1882 do_test(self, '\xef\xbf\xbd\n', True)
1884 def test_is_blank_line(self):
1885 self.assert_(cpp_style.is_blank_line(''))
1886 self.assert_(cpp_style.is_blank_line(' '))
1887 self.assert_(cpp_style.is_blank_line(' \t\r\n'))
1888 self.assert_(not cpp_style.is_blank_line('int a;'))
1889 self.assert_(not cpp_style.is_blank_line('{'))
1891 def test_blank_lines_check(self):
1892 self.assert_blank_lines_check(['{\n', '\n', '\n', '}\n'], 1, 1)
1893 self.assert_blank_lines_check([' if (foo) {\n', '\n', ' }\n'], 1, 1)
1894 self.assert_blank_lines_check(
1895 ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0)
1896 self.assert_blank_lines_check(['\n', 'run("{");\n', '\n'], 0, 0)
1897 self.assert_blank_lines_check(['\n', ' if (foo) { return 0; }\n', '\n'], 0, 0)
1899 def test_allow_blank_line_before_closing_namespace(self):
1900 error_collector = ErrorCollector(self.assert_)
1901 self.process_file_data('foo.cpp', 'cpp',
1902 ['namespace {', '', '} // namespace'],
1904 self.assertEquals(0, error_collector.results().count(
1905 'Blank line at the end of a code block. Is this needed?'
1906 ' [whitespace/blank_line] [3]'))
1908 def test_allow_blank_line_before_if_else_chain(self):
1909 error_collector = ErrorCollector(self.assert_)
1910 self.process_file_data('foo.cpp', 'cpp',
1913 '} else if (piyo) {',
1915 '} else if (piyopiyo) {',
1916 ' hoge = true;', # No warning
1918 '', # Warning on this line
1921 self.assertEquals(1, error_collector.results().count(
1922 'Blank line at the end of a code block. Is this needed?'
1923 ' [whitespace/blank_line] [3]'))
1925 def test_else_on_same_line_as_closing_braces(self):
1926 error_collector = ErrorCollector(self.assert_)
1927 self.process_file_data('foo.cpp', 'cpp',
1931 ' else {' # Warning on this line
1935 self.assertEquals(1, error_collector.results().count(
1936 'An else should appear on the same line as the preceding }'
1937 ' [whitespace/newline] [4]'))
1939 def test_else_clause_not_on_same_line_as_else(self):
1940 self.assert_lint(' else DoSomethingElse();',
1941 'Else clause should never be on same line as else '
1942 '(use 2 lines) [whitespace/newline] [4]')
1943 self.assert_lint(' else ifDoSomethingElse();',
1944 'Else clause should never be on same line as else '
1945 '(use 2 lines) [whitespace/newline] [4]')
1946 self.assert_lint(' else if (blah) {', '')
1947 self.assert_lint(' variable_ends_in_else = true;', '')
1949 def test_comma(self):
1950 self.assert_lint('a = f(1,2);',
1951 'Missing space after , [whitespace/comma] [3]')
1952 self.assert_lint('int tmp=a,a=b,b=tmp;',
1953 ['Missing spaces around = [whitespace/operators] [4]',
1954 'Missing space after , [whitespace/comma] [3]'])
1955 self.assert_lint('f(a, /* name */ b);', '')
1956 self.assert_lint('f(a, /* name */b);', '')
1958 def test_declaration(self):
1959 self.assert_lint('int a;', '')
1960 self.assert_lint('int a;', 'Extra space between int and a [whitespace/declaration] [3]')
1961 self.assert_lint('int* a;', 'Extra space between int* and a [whitespace/declaration] [3]')
1962 self.assert_lint('else if { }', '')
1963 self.assert_lint('else if { }', 'Extra space between else and if [whitespace/declaration] [3]')
1965 def test_pointer_reference_marker_location(self):
1966 self.assert_lint('int* b;', '', 'foo.cpp')
1967 self.assert_lint('int *b;',
1968 'Declaration has space between type name and * in int *b [whitespace/declaration] [3]',
1970 self.assert_lint('return *b;', '', 'foo.cpp')
1971 self.assert_lint('delete *b;', '', 'foo.cpp')
1972 self.assert_lint('int *b;', '', 'foo.c')
1973 self.assert_lint('int* b;',
1974 'Declaration has space between * and variable name in int* b [whitespace/declaration] [3]',
1976 self.assert_lint('int& b;', '', 'foo.cpp')
1977 self.assert_lint('int &b;',
1978 'Declaration has space between type name and & in int &b [whitespace/declaration] [3]',
1980 self.assert_lint('return &b;', '', 'foo.cpp')
1982 def test_indent(self):
1983 self.assert_lint('static int noindent;', '')
1984 self.assert_lint(' int fourSpaceIndent;', '')
1985 self.assert_lint(' int oneSpaceIndent;',
1986 'Weird number of spaces at line-start. '
1987 'Are you using a 4-space indent? [whitespace/indent] [3]')
1988 self.assert_lint(' int threeSpaceIndent;',
1989 'Weird number of spaces at line-start. '
1990 'Are you using a 4-space indent? [whitespace/indent] [3]')
1991 self.assert_lint(' char* oneSpaceIndent = "public:";',
1992 'Weird number of spaces at line-start. '
1993 'Are you using a 4-space indent? [whitespace/indent] [3]')
1994 self.assert_lint(' public:', '')
1995 self.assert_lint(' public:', '')
1996 self.assert_lint(' public:', '')
1998 def test_label(self):
1999 self.assert_lint('public:',
2000 'Labels should always be indented at least one space. '
2001 'If this is a member-initializer list in a constructor, '
2002 'the colon should be on the line after the definition '
2003 'header. [whitespace/labels] [4]')
2004 self.assert_lint(' public:', '')
2005 self.assert_lint(' public:', '')
2006 self.assert_lint(' public:', '')
2007 self.assert_lint(' public:', '')
2008 self.assert_lint(' public:', '')
2010 def test_not_alabel(self):
2011 self.assert_lint('MyVeryLongNamespace::MyVeryLongClassName::', '')
2014 self.assert_lint('\tint a;',
2015 'Tab found; better to use spaces [whitespace/tab] [1]')
2016 self.assert_lint('int a = 5;\t// set a to 5',
2017 'Tab found; better to use spaces [whitespace/tab] [1]')
2019 def test_unnamed_namespaces_in_headers(self):
2020 self.assert_language_rules_check(
2021 'foo.h', 'namespace {',
2022 'Do not use unnamed namespaces in header files. See'
2023 ' http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
2024 ' for more information. [build/namespaces] [4]')
2025 # namespace registration macros are OK.
2026 self.assert_language_rules_check('foo.h', 'namespace { \\', '')
2027 # named namespaces are OK.
2028 self.assert_language_rules_check('foo.h', 'namespace foo {', '')
2029 self.assert_language_rules_check('foo.h', 'namespace foonamespace {', '')
2030 self.assert_language_rules_check('foo.cpp', 'namespace {', '')
2031 self.assert_language_rules_check('foo.cpp', 'namespace foo {', '')
2033 def test_build_class(self):
2034 # Test that the linter can parse to the end of class definitions,
2035 # and that it will report when it can't.
2036 # Use multi-line linter because it performs the ClassState check.
2037 self.assert_multi_line_lint(
2039 'Failed to find complete declaration of class Foo'
2040 ' [build/class] [5]')
2041 # Don't warn on forward declarations of various types.
2042 self.assert_multi_line_lint(
2045 self.assert_multi_line_lint(
2049 # Here is an example where the linter gets confused, even though
2050 # the code doesn't violate the style guide.
2051 self.assert_multi_line_lint(
2053 #ifdef DERIVE_FROM_GOO
2059 'Failed to find complete declaration of class Foo'
2060 ' [build/class] [5]')
2062 def test_build_end_comment(self):
2063 # The crosstool compiler we currently use will fail to compile the
2064 # code in this test, so we might consider removing the lint check.
2065 self.assert_lint('#endif Not a comment',
2066 'Uncommented text after #endif is non-standard.'
2068 ' [build/endif_comment] [5]')
2070 def test_build_forward_decl(self):
2071 # The crosstool compiler we currently use will fail to compile the
2072 # code in this test, so we might consider removing the lint check.
2073 self.assert_lint('class Foo::Goo;',
2074 'Inner-style forward declarations are invalid.'
2075 ' Remove this line.'
2076 ' [build/forward_decl] [5]')
2078 def test_build_header_guard(self):
2079 file_path = 'mydir/Foo.h'
2081 # We can't rely on our internal stuff to get a sane path on the open source
2082 # side of things, so just parse out the suggested header guard. This
2083 # doesn't allow us to test the suggested header guard, but it does let us
2084 # test all the other header tests.
2085 error_collector = ErrorCollector(self.assert_)
2086 self.process_file_data(file_path, 'h', [], error_collector)
2088 matcher = re.compile(
2089 'No \#ifndef header guard found\, suggested CPP variable is\: ([A-Za-z_0-9]+) ')
2090 for error in error_collector.result_list():
2091 matches = matcher.match(error)
2093 expected_guard = matches.group(1)
2096 # Make sure we extracted something for our header guard.
2097 self.assertNotEqual(expected_guard, '')
2100 error_collector = ErrorCollector(self.assert_)
2101 self.process_file_data(file_path, 'h',
2102 ['#ifndef FOO_H', '#define FOO_H'], error_collector)
2105 error_collector.result_list().count(
2106 '#ifndef header guard has wrong style, please use: %s'
2107 ' [build/header_guard] [5]' % expected_guard),
2108 error_collector.result_list())
2111 error_collector = ErrorCollector(self.assert_)
2112 self.process_file_data(file_path, 'h',
2113 ['#ifndef %s' % expected_guard], error_collector)
2116 error_collector.result_list().count(
2117 'No #ifndef header guard found, suggested CPP variable is: %s'
2118 ' [build/header_guard] [5]' % expected_guard),
2119 error_collector.result_list())
2122 error_collector = ErrorCollector(self.assert_)
2123 self.process_file_data(file_path, 'h',
2124 ['#ifndef %s' % expected_guard,
2129 error_collector.result_list().count(
2130 'No #ifndef header guard found, suggested CPP variable is: %s'
2131 ' [build/header_guard] [5]' % expected_guard),
2132 error_collector.result_list())
2134 # No header guard errors
2135 error_collector = ErrorCollector(self.assert_)
2136 self.process_file_data(file_path, 'h',
2137 ['#ifndef %s' % expected_guard,
2138 '#define %s' % expected_guard,
2139 '#endif // %s' % expected_guard],
2141 for line in error_collector.result_list():
2142 if line.find('build/header_guard') != -1:
2143 self.fail('Unexpected error: %s' % line)
2145 # Completely incorrect header guard
2146 error_collector = ErrorCollector(self.assert_)
2147 self.process_file_data(file_path, 'h',
2154 error_collector.result_list().count(
2155 '#ifndef header guard has wrong style, please use: %s'
2156 ' [build/header_guard] [5]' % expected_guard),
2157 error_collector.result_list())
2159 # Special case for flymake
2160 error_collector = ErrorCollector(self.assert_)
2161 self.process_file_data('mydir/Foo_flymake.h', 'h',
2162 ['#ifndef %s' % expected_guard,
2163 '#define %s' % expected_guard,
2164 '#endif // %s' % expected_guard],
2166 for line in error_collector.result_list():
2167 if line.find('build/header_guard') != -1:
2168 self.fail('Unexpected error: %s' % line)
2170 error_collector = ErrorCollector(self.assert_)
2171 self.process_file_data('mydir/Foo_flymake.h', 'h', [], error_collector)
2174 error_collector.result_list().count(
2175 'No #ifndef header guard found, suggested CPP variable is: %s'
2176 ' [build/header_guard] [5]' % expected_guard),
2177 error_collector.result_list())
2179 # Verify that we don't blindly suggest the WTF prefix for all headers.
2180 self.assertFalse(expected_guard.startswith('WTF_'))
2182 # Allow the WTF_ prefix for files in that directory.
2183 header_guard_filter = FilterConfiguration(('-', '+build/header_guard'))
2184 error_collector = ErrorCollector(self.assert_, header_guard_filter)
2185 self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h',
2186 ['#ifndef WTF_TestName_h', '#define WTF_TestName_h'],
2188 self.assertEquals(0, len(error_collector.result_list()),
2189 error_collector.result_list())
2191 # Also allow the non WTF_ prefix for files in that directory.
2192 error_collector = ErrorCollector(self.assert_, header_guard_filter)
2193 self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h',
2194 ['#ifndef TestName_h', '#define TestName_h'],
2196 self.assertEquals(0, len(error_collector.result_list()),
2197 error_collector.result_list())
2199 # Verify that we suggest the WTF prefix version.
2200 error_collector = ErrorCollector(self.assert_, header_guard_filter)
2201 self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h',
2202 ['#ifndef BAD_TestName_h', '#define BAD_TestName_h'],
2206 error_collector.result_list().count(
2207 '#ifndef header guard has wrong style, please use: WTF_TestName_h'
2208 ' [build/header_guard] [5]'),
2209 error_collector.result_list())
2211 def test_build_printf_format(self):
2213 r'printf("\%%d", value);',
2214 '%, [, (, and { are undefined character escapes. Unescape them.'
2215 ' [build/printf_format] [3]')
2218 r'snprintf(buffer, sizeof(buffer), "\[%d", value);',
2219 '%, [, (, and { are undefined character escapes. Unescape them.'
2220 ' [build/printf_format] [3]')
2223 r'fprintf(file, "\(%d", value);',
2224 '%, [, (, and { are undefined character escapes. Unescape them.'
2225 ' [build/printf_format] [3]')
2228 r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);',
2229 '%, [, (, and { are undefined character escapes. Unescape them.'
2230 ' [build/printf_format] [3]')
2232 # Don't warn if double-slash precedes the symbol
2233 self.assert_lint(r'printf("\\%%%d", value);',
2236 def test_runtime_printf_format(self):
2238 r'fprintf(file, "%q", value);',
2239 '%q in format strings is deprecated. Use %ll instead.'
2240 ' [runtime/printf_format] [3]')
2243 r'aprintf(file, "The number is %12q", value);',
2244 '%q in format strings is deprecated. Use %ll instead.'
2245 ' [runtime/printf_format] [3]')
2248 r'printf(file, "The number is" "%-12q", value);',
2249 '%q in format strings is deprecated. Use %ll instead.'
2250 ' [runtime/printf_format] [3]')
2253 r'printf(file, "The number is" "%+12q", value);',
2254 '%q in format strings is deprecated. Use %ll instead.'
2255 ' [runtime/printf_format] [3]')
2258 r'printf(file, "The number is" "% 12q", value);',
2259 '%q in format strings is deprecated. Use %ll instead.'
2260 ' [runtime/printf_format] [3]')
2263 r'snprintf(file, "Never mix %d and %1$d parmaeters!", value);',
2264 '%N$ formats are unconventional. Try rewriting to avoid them.'
2265 ' [runtime/printf_format] [2]')
2267 def assert_lintLogCodeOnError(self, code, expected_message):
2268 # Special assert_lint which logs the input code on error.
2269 result = self.perform_single_line_lint(code, 'foo.cpp')
2270 if result != expected_message:
2271 self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"'
2272 % (code, result, expected_message))
2274 def test_build_storage_class(self):
2275 qualifiers = [None, 'const', 'volatile']
2276 signs = [None, 'signed', 'unsigned']
2277 types = ['void', 'char', 'int', 'float', 'double',
2278 'schar', 'int8', 'uint8', 'int16', 'uint16',
2279 'int32', 'uint32', 'int64', 'uint64']
2280 storage_classes = ['auto', 'extern', 'register', 'static', 'typedef']
2282 build_storage_class_error_message = (
2283 'Storage class (static, extern, typedef, etc) should be first.'
2284 ' [build/storage_class] [5]')
2286 # Some explicit cases. Legal in C++, deprecated in C99.
2287 self.assert_lint('const int static foo = 5;',
2288 build_storage_class_error_message)
2290 self.assert_lint('char static foo;',
2291 build_storage_class_error_message)
2293 self.assert_lint('double const static foo = 2.0;',
2294 build_storage_class_error_message)
2296 self.assert_lint('uint64 typedef unsignedLongLong;',
2297 build_storage_class_error_message)
2299 self.assert_lint('int register foo = 0;',
2300 build_storage_class_error_message)
2302 # Since there are a very large number of possibilities, randomly
2303 # construct declarations.
2304 # Make sure that the declaration is logged if there's an error.
2305 # Seed generator with an integer for absolute reproducibility.
2307 for unused_i in range(10):
2308 # Build up random list of non-storage-class declaration specs.
2309 other_decl_specs = [random.choice(qualifiers), random.choice(signs),
2310 random.choice(types)]
2312 other_decl_specs = filter(lambda x: x is not None, other_decl_specs)
2315 random.shuffle(other_decl_specs)
2317 # insert storage class after the first
2318 storage_class = random.choice(storage_classes)
2319 insertion_point = random.randint(1, len(other_decl_specs))
2320 decl_specs = (other_decl_specs[0:insertion_point]
2322 + other_decl_specs[insertion_point:])
2324 self.assert_lintLogCodeOnError(
2325 ' '.join(decl_specs) + ';',
2326 build_storage_class_error_message)
2328 # but no error if storage class is first
2329 self.assert_lintLogCodeOnError(
2330 storage_class + ' ' + ' '.join(other_decl_specs),
2333 def test_legal_copyright(self):
2334 legal_copyright_message = (
2335 'No copyright message found. '
2336 'You should have a line: "Copyright [year] <Copyright Owner>"'
2337 ' [legal/copyright] [5]')
2339 copyright_line = '// Copyright 2008 Google Inc. All Rights Reserved.'
2341 file_path = 'mydir/googleclient/foo.cpp'
2343 # There should be a copyright message in the first 10 lines
2344 error_collector = ErrorCollector(self.assert_)
2345 self.process_file_data(file_path, 'cpp', [], error_collector)
2348 error_collector.result_list().count(legal_copyright_message))
2350 error_collector = ErrorCollector(self.assert_)
2351 self.process_file_data(
2353 ['' for unused_i in range(10)] + [copyright_line],
2357 error_collector.result_list().count(legal_copyright_message))
2359 # Test that warning isn't issued if Copyright line appears early enough.
2360 error_collector = ErrorCollector(self.assert_)
2361 self.process_file_data(file_path, 'cpp', [copyright_line], error_collector)
2362 for message in error_collector.result_list():
2363 if message.find('legal/copyright') != -1:
2364 self.fail('Unexpected error: %s' % message)
2366 error_collector = ErrorCollector(self.assert_)
2367 self.process_file_data(
2369 ['' for unused_i in range(9)] + [copyright_line],
2371 for message in error_collector.result_list():
2372 if message.find('legal/copyright') != -1:
2373 self.fail('Unexpected error: %s' % message)
2375 def test_invalid_increment(self):
2376 self.assert_lint('*count++;',
2377 'Changing pointer instead of value (or unused value of '
2378 'operator*). [runtime/invalid_increment] [5]')
2380 # Integral bitfields must be declared with either signed or unsigned keyword.
2381 def test_plain_integral_bitfields(self):
2382 errmsg = ('Please declare integral type bitfields with either signed or unsigned. [runtime/bitfields] [5]')
2384 self.assert_lint('int a : 30;', errmsg)
2385 self.assert_lint('mutable short a : 14;', errmsg)
2386 self.assert_lint('const char a : 6;', errmsg)
2387 self.assert_lint('long int a : 30;', errmsg)
2388 self.assert_lint('int a = 1 ? 0 : 30;', '')
2390 class CleansedLinesTest(unittest.TestCase):
2391 def test_init(self):
2394 'Line 3 // Comment test',
2397 clean_lines = cpp_style.CleansedLines(lines)
2398 self.assertEquals(lines, clean_lines.raw_lines)
2399 self.assertEquals(4, clean_lines.num_lines())
2401 self.assertEquals(['Line 1',
2407 self.assertEquals(['Line 1',
2413 def test_init_empty(self):
2414 clean_lines = cpp_style.CleansedLines([])
2415 self.assertEquals([], clean_lines.raw_lines)
2416 self.assertEquals(0, clean_lines.num_lines())
2418 def test_collapse_strings(self):
2419 collapse = cpp_style.CleansedLines.collapse_strings
2420 self.assertEquals('""', collapse('""')) # "" (empty)
2421 self.assertEquals('"""', collapse('"""')) # """ (bad)
2422 self.assertEquals('""', collapse('"xyz"')) # "xyz" (string)
2423 self.assertEquals('""', collapse('"\\\""')) # "\"" (string)
2424 self.assertEquals('""', collapse('"\'"')) # "'" (string)
2425 self.assertEquals('"\"', collapse('"\"')) # "\" (bad)
2426 self.assertEquals('""', collapse('"\\\\"')) # "\\" (string)
2427 self.assertEquals('"', collapse('"\\\\\\"')) # "\\\" (bad)
2428 self.assertEquals('""', collapse('"\\\\\\\\"')) # "\\\\" (string)
2430 self.assertEquals('\'\'', collapse('\'\'')) # '' (empty)
2431 self.assertEquals('\'\'', collapse('\'a\'')) # 'a' (char)
2432 self.assertEquals('\'\'', collapse('\'\\\'\'')) # '\'' (char)
2433 self.assertEquals('\'', collapse('\'\\\'')) # '\' (bad)
2434 self.assertEquals('', collapse('\\012')) # '\012' (char)
2435 self.assertEquals('', collapse('\\xfF0')) # '\xfF0' (char)
2436 self.assertEquals('', collapse('\\n')) # '\n' (char)
2437 self.assertEquals('\#', collapse('\\#')) # '\#' (bad)
2439 self.assertEquals('StringReplace(body, "", "");',
2440 collapse('StringReplace(body, "\\\\", "\\\\\\\\");'))
2441 self.assertEquals('\'\' ""',
2442 collapse('\'"\' "foo"'))
2445 class OrderOfIncludesTest(CppStyleTestBase):
2447 self.include_state = cpp_style._IncludeState()
2449 # Cheat os.path.abspath called in FileInfo class.
2450 self.os_path_abspath_orig = os.path.abspath
2451 os.path.abspath = lambda value: value
2454 os.path.abspath = self.os_path_abspath_orig
2456 def test_try_drop_common_suffixes(self):
2457 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h'))
2458 self.assertEqual('foo/bar/foo',
2459 cpp_style._drop_common_suffixes('foo/bar/foo_inl.h'))
2460 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp'))
2461 self.assertEqual('foo/foo_unusualinternal',
2462 cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h'))
2463 self.assertEqual('',
2464 cpp_style._drop_common_suffixes('_test.cpp'))
2465 self.assertEqual('test',
2466 cpp_style._drop_common_suffixes('test.cpp'))
2469 class OrderOfIncludesTest(CppStyleTestBase):
2471 self.include_state = cpp_style._IncludeState()
2473 # Cheat os.path.abspath called in FileInfo class.
2474 self.os_path_abspath_orig = os.path.abspath
2475 self.os_path_isfile_orig = os.path.isfile
2476 os.path.abspath = lambda value: value
2479 os.path.abspath = self.os_path_abspath_orig
2480 os.path.isfile = self.os_path_isfile_orig
2482 def test_check_next_include_order__no_config(self):
2483 self.assertEqual('Header file should not contain WebCore config.h.',
2484 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, True, True))
2486 def test_check_next_include_order__no_self(self):
2487 self.assertEqual('Header file should not contain itself.',
2488 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, True, True))
2489 # Test actual code to make sure that header types are correctly assigned.
2490 self.assert_language_rules_check('Foo.h',
2491 '#include "Foo.h"\n',
2492 'Header file should not contain itself. Should be: alphabetically sorted.'
2493 ' [build/include_order] [4]')
2494 self.assert_language_rules_check('FooBar.h',
2495 '#include "Foo.h"\n',
2498 def test_check_next_include_order__likely_then_config(self):
2499 self.assertEqual('Found header this file implements before WebCore config.h.',
2500 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False, True))
2501 self.assertEqual('Found WebCore config.h after a header this file implements.',
2502 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
2504 def test_check_next_include_order__other_then_config(self):
2505 self.assertEqual('Found other header before WebCore config.h.',
2506 self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False, True))
2507 self.assertEqual('Found WebCore config.h after other header.',
2508 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
2510 def test_check_next_include_order__config_then_other_then_likely(self):
2511 self.assertEqual('', self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
2512 self.assertEqual('Found other header before a header this file implements.',
2513 self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False, True))
2514 self.assertEqual('Found header this file implements after other header.',
2515 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False, True))
2517 def test_check_alphabetical_include_order(self):
2518 self.assert_language_rules_check('foo.h',
2522 'Alphabetical sorting problem. [build/include_order] [4]')
2524 self.assert_language_rules_check('foo.h',
2530 self.assert_language_rules_check('foo.h',
2531 '#include <assert.h>\n'
2532 '#include "bar.h"\n',
2533 'Alphabetical sorting problem. [build/include_order] [4]')
2535 self.assert_language_rules_check('foo.h',
2536 '#include "bar.h"\n'
2537 '#include <assert.h>\n',
2540 def test_check_line_break_after_own_header(self):
2541 self.assert_language_rules_check('foo.cpp',
2542 '#include "config.h"\n'
2543 '#include "foo.h"\n'
2544 '#include "bar.h"\n',
2545 'You should add a blank line after implementation file\'s own header. [build/include_order] [4]')
2547 self.assert_language_rules_check('foo.cpp',
2548 '#include "config.h"\n'
2549 '#include "foo.h"\n'
2551 '#include "bar.h"\n',
2554 def test_check_preprocessor_in_include_section(self):
2555 self.assert_language_rules_check('foo.cpp',
2556 '#include "config.h"\n'
2557 '#include "foo.h"\n'
2560 '#include "baz.h"\n'
2562 '#include "foobar.h"\n'
2564 '#include "bar.h"\n', # No flag because previous is in preprocessor section
2567 self.assert_language_rules_check('foo.cpp',
2568 '#include "config.h"\n'
2569 '#include "foo.h"\n'
2572 '#include "baz.h"\n'
2574 '#include "bar.h"\n'
2575 '#include "a.h"\n', # Should still flag this.
2576 'Alphabetical sorting problem. [build/include_order] [4]')
2578 self.assert_language_rules_check('foo.cpp',
2579 '#include "config.h"\n'
2580 '#include "foo.h"\n'
2583 '#include "baz.h"\n'
2584 '#include "bar.h"\n' #Should still flag this
2586 'Alphabetical sorting problem. [build/include_order] [4]')
2588 self.assert_language_rules_check('foo.cpp',
2589 '#include "config.h"\n'
2590 '#include "foo.h"\n'
2593 '#include "baz.h"\n'
2596 '#include "foobar.h"\n'
2598 '#include "bar.h"\n'
2599 '#include "a.h"\n', # Should still flag this.
2600 'Alphabetical sorting problem. [build/include_order] [4]')
2602 # Check that after an already included error, the sorting rules still work.
2603 self.assert_language_rules_check('foo.cpp',
2604 '#include "config.h"\n'
2605 '#include "foo.h"\n'
2607 '#include "foo.h"\n'
2609 '"foo.h" already included at foo.cpp:2 [build/include] [4]')
2611 def test_primary_header(self):
2612 # File with non-existing primary header should not produce errors.
2613 self.assert_language_rules_check('foo.cpp',
2614 '#include "config.h"\n'
2616 '#include "bar.h"\n',
2618 # Pretend that header files exist.
2619 os.path.isfile = lambda filename: True
2620 # Missing include for existing primary header -> error.
2621 self.assert_language_rules_check('foo.cpp',
2622 '#include "config.h"\n'
2624 '#include "bar.h"\n',
2625 'Found other header before a header this file implements. '
2626 'Should be: config.h, primary header, blank line, and then '
2627 'alphabetically sorted. [build/include_order] [4]')
2628 # Having include for existing primary header -> no error.
2629 self.assert_language_rules_check('foo.cpp',
2630 '#include "config.h"\n'
2631 '#include "foo.h"\n'
2633 '#include "bar.h"\n',
2636 os.path.isfile = self.os_path_isfile_orig
2639 def test_check_wtf_includes(self):
2640 self.assert_language_rules_check('foo.cpp',
2641 '#include "config.h"\n'
2642 '#include "foo.h"\n'
2644 '#include <wtf/Assertions.h>\n',
2646 self.assert_language_rules_check('foo.cpp',
2647 '#include "config.h"\n'
2648 '#include "foo.h"\n'
2650 '#include "wtf/Assertions.h"\n',
2651 'wtf includes should be <wtf/file.h> instead of "wtf/file.h".'
2652 ' [build/include] [4]')
2654 def test_classify_include(self):
2655 classify_include = cpp_style._classify_include
2656 include_state = cpp_style._IncludeState()
2657 self.assertEqual(cpp_style._CONFIG_HEADER,
2658 classify_include('foo/foo.cpp',
2660 False, include_state))
2661 self.assertEqual(cpp_style._PRIMARY_HEADER,
2662 classify_include('foo/internal/foo.cpp',
2664 False, include_state))
2665 self.assertEqual(cpp_style._PRIMARY_HEADER,
2666 classify_include('foo/internal/foo.cpp',
2667 'foo/other/public/foo.h',
2668 False, include_state))
2669 self.assertEqual(cpp_style._OTHER_HEADER,
2670 classify_include('foo/internal/foo.cpp',
2671 'foo/other/public/foop.h',
2672 False, include_state))
2673 self.assertEqual(cpp_style._OTHER_HEADER,
2674 classify_include('foo/foo.cpp',
2676 True, include_state))
2677 self.assertEqual(cpp_style._PRIMARY_HEADER,
2678 classify_include('fooCustom.cpp',
2680 False, include_state))
2681 self.assertEqual(cpp_style._PRIMARY_HEADER,
2682 classify_include('PrefixFooCustom.cpp',
2684 False, include_state))
2685 self.assertEqual(cpp_style._MOC_HEADER,
2686 classify_include('foo.cpp',
2688 False, include_state))
2689 self.assertEqual(cpp_style._MOC_HEADER,
2690 classify_include('foo.cpp',
2692 False, include_state))
2693 # Tricky example where both includes might be classified as primary.
2694 self.assert_language_rules_check('ScrollbarThemeWince.cpp',
2695 '#include "config.h"\n'
2696 '#include "ScrollbarThemeWince.h"\n'
2698 '#include "Scrollbar.h"\n',
2700 self.assert_language_rules_check('ScrollbarThemeWince.cpp',
2701 '#include "config.h"\n'
2702 '#include "Scrollbar.h"\n'
2704 '#include "ScrollbarThemeWince.h"\n',
2705 'Found header this file implements after a header this file implements.'
2706 ' Should be: config.h, primary header, blank line, and then alphabetically sorted.'
2707 ' [build/include_order] [4]')
2708 self.assert_language_rules_check('ResourceHandleWin.cpp',
2709 '#include "config.h"\n'
2710 '#include "ResourceHandle.h"\n'
2712 '#include "ResourceHandleWin.h"\n',
2715 def test_try_drop_common_suffixes(self):
2716 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h'))
2717 self.assertEqual('foo/bar/foo',
2718 cpp_style._drop_common_suffixes('foo/bar/foo_inl.h'))
2719 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp'))
2720 self.assertEqual('foo/foo_unusualinternal',
2721 cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h'))
2722 self.assertEqual('',
2723 cpp_style._drop_common_suffixes('_test.cpp'))
2724 self.assertEqual('test',
2725 cpp_style._drop_common_suffixes('test.cpp'))
2726 self.assertEqual('test',
2727 cpp_style._drop_common_suffixes('test.cpp'))
2729 class CheckForFunctionLengthsTest(CppStyleTestBase):
2731 # Reducing these thresholds for the tests speeds up tests significantly.
2732 self.old_normal_trigger = cpp_style._FunctionState._NORMAL_TRIGGER
2733 self.old_test_trigger = cpp_style._FunctionState._TEST_TRIGGER
2735 cpp_style._FunctionState._NORMAL_TRIGGER = 10
2736 cpp_style._FunctionState._TEST_TRIGGER = 25
2739 cpp_style._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger
2740 cpp_style._FunctionState._TEST_TRIGGER = self.old_test_trigger
2742 # FIXME: Eliminate the need for this function.
2743 def set_min_confidence(self, min_confidence):
2744 """Set new test confidence and return old test confidence."""
2745 old_min_confidence = self.min_confidence
2746 self.min_confidence = min_confidence
2747 return old_min_confidence
2749 def assert_function_lengths_check(self, code, expected_message):
2750 """Check warnings for long function bodies are as expected.
2753 code: C++ source code expected to generate a warning message.
2754 expected_message: Message expected to be generated by the C++ code.
2756 self.assertEquals(expected_message,
2757 self.perform_function_lengths_check(code))
2759 def trigger_lines(self, error_level):
2760 """Return number of lines needed to trigger a function length warning.
2763 error_level: --v setting for cpp_style.
2766 Number of lines needed to trigger a function length warning.
2768 return cpp_style._FunctionState._NORMAL_TRIGGER * 2 ** error_level
2770 def trigger_test_lines(self, error_level):
2771 """Return number of lines needed to trigger a test function length warning.
2774 error_level: --v setting for cpp_style.
2777 Number of lines needed to trigger a test function length warning.
2779 return cpp_style._FunctionState._TEST_TRIGGER * 2 ** error_level
2781 def assert_function_length_check_definition(self, lines, error_level):
2782 """Generate long function definition and check warnings are as expected.
2785 lines: Number of lines to generate.
2786 error_level: --v setting for cpp_style.
2788 trigger_level = self.trigger_lines(self.min_confidence)
2789 self.assert_function_lengths_check(
2790 'void test(int x)' + self.function_body(lines),
2791 ('Small and focused functions are preferred: '
2792 'test() has %d non-comment lines '
2793 '(error triggered by exceeding %d lines).'
2794 ' [readability/fn_size] [%d]'
2795 % (lines, trigger_level, error_level)))
2797 def assert_function_length_check_definition_ok(self, lines):
2798 """Generate shorter function definition and check no warning is produced.
2801 lines: Number of lines to generate.
2803 self.assert_function_lengths_check(
2804 'void test(int x)' + self.function_body(lines),
2807 def assert_function_length_check_at_error_level(self, error_level):
2808 """Generate and check function at the trigger level for --v setting.
2811 error_level: --v setting for cpp_style.
2813 self.assert_function_length_check_definition(self.trigger_lines(error_level),
2816 def assert_function_length_check_below_error_level(self, error_level):
2817 """Generate and check function just below the trigger level for --v setting.
2820 error_level: --v setting for cpp_style.
2822 self.assert_function_length_check_definition(self.trigger_lines(error_level) - 1,
2825 def assert_function_length_check_above_error_level(self, error_level):
2826 """Generate and check function just above the trigger level for --v setting.
2829 error_level: --v setting for cpp_style.
2831 self.assert_function_length_check_definition(self.trigger_lines(error_level) + 1,
2834 def function_body(self, number_of_lines):
2835 return ' {\n' + ' this_is_just_a_test();\n' * number_of_lines + '}'
2837 def function_body_with_blank_lines(self, number_of_lines):
2838 return ' {\n' + ' this_is_just_a_test();\n\n' * number_of_lines + '}'
2840 def function_body_with_no_lints(self, number_of_lines):
2841 return ' {\n' + ' this_is_just_a_test(); // NOLINT\n' * number_of_lines + '}'
2843 # Test line length checks.
2844 def test_function_length_check_declaration(self):
2845 self.assert_function_lengths_check(
2846 'void test();', # Not a function definition
2849 def test_function_length_check_declaration_with_block_following(self):
2850 self.assert_function_lengths_check(
2852 + self.function_body(66)), # Not a function definition
2855 def test_function_length_check_class_definition(self):
2856 self.assert_function_lengths_check( # Not a function definition
2857 'class Test' + self.function_body(66) + ';',
2860 def test_function_length_check_trivial(self):
2861 self.assert_function_lengths_check(
2862 'void test() {}', # Not counted
2865 def test_function_length_check_empty(self):
2866 self.assert_function_lengths_check(
2870 def test_function_length_check_definition_below_severity0(self):
2871 old_min_confidence = self.set_min_confidence(0)
2872 self.assert_function_length_check_definition_ok(self.trigger_lines(0) - 1)
2873 self.set_min_confidence(old_min_confidence)
2875 def test_function_length_check_definition_at_severity0(self):
2876 old_min_confidence = self.set_min_confidence(0)
2877 self.assert_function_length_check_definition_ok(self.trigger_lines(0))
2878 self.set_min_confidence(old_min_confidence)
2880 def test_function_length_check_definition_above_severity0(self):
2881 old_min_confidence = self.set_min_confidence(0)
2882 self.assert_function_length_check_above_error_level(0)
2883 self.set_min_confidence(old_min_confidence)
2885 def test_function_length_check_definition_below_severity1v0(self):
2886 old_min_confidence = self.set_min_confidence(0)
2887 self.assert_function_length_check_below_error_level(1)
2888 self.set_min_confidence(old_min_confidence)
2890 def test_function_length_check_definition_at_severity1v0(self):
2891 old_min_confidence = self.set_min_confidence(0)
2892 self.assert_function_length_check_at_error_level(1)
2893 self.set_min_confidence(old_min_confidence)
2895 def test_function_length_check_definition_below_severity1(self):
2896 self.assert_function_length_check_definition_ok(self.trigger_lines(1) - 1)
2898 def test_function_length_check_definition_at_severity1(self):
2899 self.assert_function_length_check_definition_ok(self.trigger_lines(1))
2901 def test_function_length_check_definition_above_severity1(self):
2902 self.assert_function_length_check_above_error_level(1)
2904 def test_function_length_check_definition_severity1_plus_indented(self):
2906 error_lines = self.trigger_lines(error_level) + 1
2907 trigger_level = self.trigger_lines(self.min_confidence)
2909 self.assert_function_lengths_check(
2910 re.sub(r'(?m)^(.)', indent_spaces + r'\1',
2911 'void test_indent(int x)\n' + self.function_body(error_lines)),
2912 ('Small and focused functions are preferred: '
2913 'test_indent() has %d non-comment lines '
2914 '(error triggered by exceeding %d lines).'
2915 ' [readability/fn_size] [%d]')
2916 % (error_lines, trigger_level, error_level))
2918 def test_function_length_check_definition_severity1_plus_blanks(self):
2920 error_lines = self.trigger_lines(error_level) + 1
2921 trigger_level = self.trigger_lines(self.min_confidence)
2922 self.assert_function_lengths_check(
2923 'void test_blanks(int x)' + self.function_body(error_lines),
2924 ('Small and focused functions are preferred: '
2925 'test_blanks() has %d non-comment lines '
2926 '(error triggered by exceeding %d lines).'
2927 ' [readability/fn_size] [%d]')
2928 % (error_lines, trigger_level, error_level))
2930 def test_function_length_check_complex_definition_severity1(self):
2932 error_lines = self.trigger_lines(error_level) + 1
2933 trigger_level = self.trigger_lines(self.min_confidence)
2934 self.assert_function_lengths_check(
2935 ('my_namespace::my_other_namespace::MyVeryLongTypeName<Type1, bool func(const Element*)>*\n'
2936 'my_namespace::my_other_namespace<Type3, Type4>::~MyFunction<Type5<Type6, Type7> >(int arg1, char* arg2)'
2937 + self.function_body(error_lines)),
2938 ('Small and focused functions are preferred: '
2939 'my_namespace::my_other_namespace<Type3, Type4>::~MyFunction<Type5<Type6, Type7> >()'
2940 ' has %d non-comment lines '
2941 '(error triggered by exceeding %d lines).'
2942 ' [readability/fn_size] [%d]')
2943 % (error_lines, trigger_level, error_level))
2945 def test_function_length_check_definition_severity1_for_test(self):
2947 error_lines = self.trigger_test_lines(error_level) + 1
2948 trigger_level = self.trigger_test_lines(self.min_confidence)
2949 self.assert_function_lengths_check(
2950 'TEST_F(Test, Mutator)' + self.function_body(error_lines),
2951 ('Small and focused functions are preferred: '
2952 'TEST_F(Test, Mutator) has %d non-comment lines '
2953 '(error triggered by exceeding %d lines).'
2954 ' [readability/fn_size] [%d]')
2955 % (error_lines, trigger_level, error_level))
2957 def test_function_length_check_definition_severity1_for_split_line_test(self):
2959 error_lines = self.trigger_test_lines(error_level) + 1
2960 trigger_level = self.trigger_test_lines(self.min_confidence)
2961 self.assert_function_lengths_check(
2962 ('TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,\n'
2963 ' FixGoogleUpdate_AllValues_MachineApp)' # note: 4 spaces
2964 + self.function_body(error_lines)),
2965 ('Small and focused functions are preferred: '
2966 'TEST_F(GoogleUpdateRecoveryRegistryProtectedTest, ' # 1 space
2967 'FixGoogleUpdate_AllValues_MachineApp) has %d non-comment lines '
2968 '(error triggered by exceeding %d lines).'
2969 ' [readability/fn_size] [%d]')
2970 % (error_lines, trigger_level, error_level))
2972 def test_function_length_check_definition_severity1_for_bad_test_doesnt_break(self):
2974 error_lines = self.trigger_test_lines(error_level) + 1
2975 trigger_level = self.trigger_test_lines(self.min_confidence)
2976 # Since the function name isn't valid, the function detection algorithm
2977 # will skip it, so no error is produced.
2978 self.assert_function_lengths_check(
2980 + self.function_body(error_lines)),
2983 def test_function_length_check_definition_severity1_with_embedded_no_lints(self):
2985 error_lines = self.trigger_lines(error_level) + 1
2986 trigger_level = self.trigger_lines(self.min_confidence)
2987 self.assert_function_lengths_check(
2988 'void test(int x)' + self.function_body_with_no_lints(error_lines),
2989 ('Small and focused functions are preferred: '
2990 'test() has %d non-comment lines '
2991 '(error triggered by exceeding %d lines).'
2992 ' [readability/fn_size] [%d]')
2993 % (error_lines, trigger_level, error_level))
2995 def test_function_length_check_definition_severity1_with_no_lint(self):
2996 self.assert_function_lengths_check(
2997 ('void test(int x)' + self.function_body(self.trigger_lines(1))
2998 + ' // NOLINT -- long function'),
3001 def test_function_length_check_definition_below_severity2(self):
3002 self.assert_function_length_check_below_error_level(2)
3004 def test_function_length_check_definition_severity2(self):
3005 self.assert_function_length_check_at_error_level(2)
3007 def test_function_length_check_definition_above_severity2(self):
3008 self.assert_function_length_check_above_error_level(2)
3010 def test_function_length_check_definition_below_severity3(self):
3011 self.assert_function_length_check_below_error_level(3)
3013 def test_function_length_check_definition_severity3(self):
3014 self.assert_function_length_check_at_error_level(3)
3016 def test_function_length_check_definition_above_severity3(self):
3017 self.assert_function_length_check_above_error_level(3)
3019 def test_function_length_check_definition_below_severity4(self):
3020 self.assert_function_length_check_below_error_level(4)
3022 def test_function_length_check_definition_severity4(self):
3023 self.assert_function_length_check_at_error_level(4)
3025 def test_function_length_check_definition_above_severity4(self):
3026 self.assert_function_length_check_above_error_level(4)
3028 def test_function_length_check_definition_below_severity5(self):
3029 self.assert_function_length_check_below_error_level(5)
3031 def test_function_length_check_definition_at_severity5(self):
3032 self.assert_function_length_check_at_error_level(5)
3034 def test_function_length_check_definition_above_severity5(self):
3035 self.assert_function_length_check_above_error_level(5)
3037 def test_function_length_check_definition_huge_lines(self):
3039 self.assert_function_length_check_definition(self.trigger_lines(10), 5)
3041 def test_function_length_not_determinable(self):
3042 # Macro invocation without terminating semicolon.
3043 self.assert_function_lengths_check(
3047 # Macro with underscores
3048 self.assert_function_lengths_check(
3049 'MACRO_WITH_UNDERSCORES(arg1, arg2, arg3)',
3052 self.assert_function_lengths_check(
3054 'Lint failed to find start of function body.'
3055 ' [readability/fn_size] [5]')
3058 class NoNonVirtualDestructorsTest(CppStyleTestBase):
3060 def test_no_error(self):
3061 self.assert_multi_line_lint(
3068 self.assert_multi_line_lint(
3070 virtual inline ~Foo();
3075 self.assert_multi_line_lint(
3077 inline virtual ~Foo();
3082 self.assert_multi_line_lint(
3088 self.assert_multi_line_lint(
3089 'class Foo { void foo(); };',
3090 'More than one command on the same line [whitespace/newline] [4]')
3091 self.assert_multi_line_lint(
3093 ' int getIntValue() { ASSERT(m_ptr); return *m_ptr; }\n'
3096 self.assert_multi_line_lint(
3098 ' int getIntValue()\n'
3100 ' ASSERT(m_ptr); return *m_ptr;\n'
3103 'More than one command on the same line [whitespace/newline] [4]')
3105 self.assert_multi_line_lint(
3106 '''class Qualified::Goo : public Foo {
3111 self.assert_multi_line_lint(
3117 'Labels should always be indented at least one space. If this is a '
3118 'member-initializer list in a constructor, the colon should be on the '
3119 'line after the definition header. [whitespace/labels] [4]')
3121 def test_no_destructor_when_virtual_needed(self):
3122 self.assert_multi_line_lint_re(
3126 'The class Foo probably needs a virtual destructor')
3128 def test_destructor_non_virtual_when_virtual_needed(self):
3129 self.assert_multi_line_lint_re(
3134 'The class Foo probably needs a virtual destructor')
3136 def test_no_warn_when_derived(self):
3137 self.assert_multi_line_lint(
3138 '''class Foo : public Goo {
3143 def test_internal_braces(self):
3144 self.assert_multi_line_lint_re(
3151 'The class Foo probably needs a virtual destructor')
3153 def test_inner_class_needs_virtual_destructor(self):
3154 self.assert_multi_line_lint_re(
3160 'The class Goo probably needs a virtual destructor')
3162 def test_outer_class_needs_virtual_destructor(self):
3163 self.assert_multi_line_lint_re(
3169 'The class Foo probably needs a virtual destructor')
3171 def test_qualified_class_needs_virtual_destructor(self):
3172 self.assert_multi_line_lint_re(
3173 '''class Qualified::Foo {
3176 'The class Qualified::Foo probably needs a virtual destructor')
3178 def test_multi_line_declaration_no_error(self):
3179 self.assert_multi_line_lint_re(
3186 def test_multi_line_declaration_with_error(self):
3187 self.assert_multi_line_lint(
3192 ['This { should be at the end of the previous line '
3193 '[whitespace/braces] [4]',
3194 'The class Foo probably needs a virtual destructor due to having '
3195 'virtual method(s), one declared at line 3. [runtime/virtual] [4]'])
3198 class PassPtrTest(CppStyleTestBase):
3199 # For http://webkit.org/coding/RefPtr.html
3201 def assert_pass_ptr_check(self, code, expected_message):
3202 """Check warnings for Pass*Ptr are as expected.
3205 code: C++ source code expected to generate a warning message.
3206 expected_message: Message expected to be generated by the C++ code.
3208 self.assertEquals(expected_message,
3209 self.perform_pass_ptr_check(code))
3211 def test_pass_ref_ptr_in_function(self):
3212 self.assert_pass_ptr_check(
3213 'int myFunction()\n'
3215 ' PassRefPtr<Type1> variable = variable2;\n'
3217 'Local variables should never be PassRefPtr (see '
3218 'http://webkit.org/coding/RefPtr.html). [readability/pass_ptr] [5]')
3220 def test_pass_own_ptr_in_function(self):
3221 self.assert_pass_ptr_check(
3222 'int myFunction()\n'
3224 ' PassOwnPtr<Type1> variable = variable2;\n'
3226 'Local variables should never be PassOwnPtr (see '
3227 'http://webkit.org/coding/RefPtr.html). [readability/pass_ptr] [5]')
3229 def test_pass_other_type_ptr_in_function(self):
3230 self.assert_pass_ptr_check(
3231 'int myFunction()\n'
3233 ' PassOtherTypePtr<Type1> variable;\n'
3235 'Local variables should never be PassOtherTypePtr (see '
3236 'http://webkit.org/coding/RefPtr.html). [readability/pass_ptr] [5]')
3238 def test_pass_ref_ptr_return_value(self):
3239 self.assert_pass_ptr_check(
3240 'PassRefPtr<Type1>\n'
3245 self.assert_pass_ptr_check(
3246 'PassRefPtr<Type1> myFunction(int)\n'
3250 self.assert_pass_ptr_check(
3251 'PassRefPtr<Type1> myFunction();\n',
3253 self.assert_pass_ptr_check(
3254 'OwnRefPtr<Type1> myFunction();\n',
3256 self.assert_pass_ptr_check(
3257 'RefPtr<Type1> myFunction(int)\n'
3260 'The return type should use PassRefPtr instead of RefPtr. [readability/pass_ptr] [5]')
3261 self.assert_pass_ptr_check(
3262 'OwnPtr<Type1> myFunction(int)\n'
3265 'The return type should use PassOwnPtr instead of OwnPtr. [readability/pass_ptr] [5]')
3267 def test_ref_ptr_parameter_value(self):
3268 self.assert_pass_ptr_check(
3269 'int myFunction(PassRefPtr<Type1>)\n'
3273 self.assert_pass_ptr_check(
3274 'int myFunction(RefPtr<Type1>)\n'
3277 'The parameter type should use PassRefPtr instead of RefPtr. [readability/pass_ptr] [5]')
3278 self.assert_pass_ptr_check(
3279 'int myFunction(RefPtr<Type1>&)\n'
3284 def test_own_ptr_parameter_value(self):
3285 self.assert_pass_ptr_check(
3286 'int myFunction(PassOwnPtr<Type1>)\n'
3290 self.assert_pass_ptr_check(
3291 'int myFunction(OwnPtr<Type1>)\n'
3294 'The parameter type should use PassOwnPtr instead of OwnPtr. [readability/pass_ptr] [5]')
3295 self.assert_pass_ptr_check(
3296 'int myFunction(OwnPtr<Type1>& simple)\n'
3301 def test_ref_ptr_member_variable(self):
3302 self.assert_pass_ptr_check(
3304 ' RefPtr<Type1> m_other;\n'
3309 class WebKitStyleTest(CppStyleTestBase):
3311 # for http://webkit.org/coding/coding-style.html
3312 def test_indentation(self):
3313 # 1. Use spaces, not tabs. Tabs should only appear in files that
3314 # require them for semantic meaning, like Makefiles.
3315 self.assert_multi_line_lint(
3320 self.assert_multi_line_lint(
3324 'Tab found; better to use spaces [whitespace/tab] [1]')
3326 # 2. The indent size is 4 spaces.
3327 self.assert_multi_line_lint(
3332 self.assert_multi_line_lint(
3336 'Weird number of spaces at line-start. Are you using a 4-space indent? [whitespace/indent] [3]')
3337 # FIXME: No tests for 8-spaces.
3339 # 3. In a header, code inside a namespace should not be indented.
3340 self.assert_multi_line_lint(
3341 'namespace WebCore {\n\n'
3342 'class Document {\n'
3343 ' int myVariable;\n'
3348 self.assert_multi_line_lint(
3349 'namespace OuterNamespace {\n'
3350 ' namespace InnerNamespace {\n'
3351 ' class Document {\n'
3355 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3357 self.assert_multi_line_lint(
3358 'namespace OuterNamespace {\n'
3359 ' class Document {\n'
3360 ' namespace InnerNamespace {\n'
3364 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3366 self.assert_multi_line_lint(
3367 'namespace WebCore {\n'
3369 ' class Document {\n'
3373 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3375 self.assert_multi_line_lint(
3376 'namespace WebCore {\n'
3377 'class Document {\n'
3383 # 4. In an implementation file (files with the extension .cpp, .c
3384 # or .mm), code inside a namespace should not be indented.
3385 self.assert_multi_line_lint(
3386 'namespace WebCore {\n\n'
3395 self.assert_multi_line_lint(
3396 'namespace OuterNamespace {\n'
3397 'namespace InnerNamespace {\n'
3398 'Document::Foo() { }\n'
3402 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3404 self.assert_multi_line_lint(
3405 'namespace OuterNamespace {\n'
3406 'namespace InnerNamespace {\n'
3407 'Document::Foo() { }\n'
3411 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3413 self.assert_multi_line_lint(
3414 'namespace WebCore {\n\n'
3415 ' const char* foo = "start:;"\n'
3418 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3420 self.assert_multi_line_lint(
3421 'namespace WebCore {\n\n'
3422 'const char* foo(void* a = ";", // ;\n'
3426 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3428 self.assert_multi_line_lint(
3429 'namespace WebCore {\n\n'
3430 'const char* foo[] = {\n'
3431 ' "void* b);", // ;\n'
3436 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3438 self.assert_multi_line_lint(
3439 'namespace WebCore {\n\n'
3440 'const char* foo[] = {\n'
3441 ' "void* b);", // }\n'
3447 self.assert_multi_line_lint(
3448 ' namespace WebCore {\n\n'
3449 ' void Document::Foo()\n'
3451 'start: // infinite loops are fun!\n'
3454 'namespace should never be indented. [whitespace/indent] [4]',
3456 self.assert_multi_line_lint(
3457 'namespace WebCore {\n'
3458 ' Document::Foo() { }\n'
3460 'Code inside a namespace should not be indented.'
3461 ' [whitespace/indent] [4]',
3463 self.assert_multi_line_lint(
3464 'namespace WebCore {\n'
3465 '#define abc(x) x; \\\n'
3470 self.assert_multi_line_lint(
3471 'namespace WebCore {\n'
3472 '#define abc(x) x; \\\n'
3476 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3479 # 5. A case label should line up with its switch statement. The
3480 # case statement is indented.
3481 self.assert_multi_line_lint(
3482 ' switch (condition) {\n'
3483 ' case fooCondition:\n'
3484 ' case barCondition:\n'
3491 self.assert_multi_line_lint(
3492 ' switch (condition) {\n'
3493 ' case fooCondition:\n'
3494 ' switch (otherCondition) {\n'
3502 self.assert_multi_line_lint(
3503 ' switch (condition) {\n'
3504 ' case fooCondition: break;\n'
3505 ' default: return;\n'
3508 self.assert_multi_line_lint(
3509 ' switch (condition) {\n'
3510 ' case fooCondition:\n'
3511 ' case barCondition:\n'
3517 'A case label should not be indented, but line up with its switch statement.'
3518 ' [whitespace/indent] [4]')
3519 self.assert_multi_line_lint(
3520 ' switch (condition) {\n'
3521 ' case fooCondition:\n'
3526 'A case label should not be indented, but line up with its switch statement.'
3527 ' [whitespace/indent] [4]')
3528 self.assert_multi_line_lint(
3529 ' switch (condition) {\n'
3530 ' case fooCondition:\n'
3531 ' case barCondition:\n'
3532 ' switch (otherCondition) {\n'
3539 'A case label should not be indented, but line up with its switch statement.'
3540 ' [whitespace/indent] [4]')
3541 self.assert_multi_line_lint(
3542 ' switch (condition) {\n'
3543 ' case fooCondition:\n'
3544 ' case barCondition:\n'
3550 'Non-label code inside switch statements should be indented.'
3551 ' [whitespace/indent] [4]')
3552 self.assert_multi_line_lint(
3553 ' switch (condition) {\n'
3554 ' case fooCondition:\n'
3555 ' case barCondition:\n'
3556 ' switch (otherCondition) {\n'
3563 'Non-label code inside switch statements should be indented.'
3564 ' [whitespace/indent] [4]')
3566 # 6. Boolean expressions at the same nesting level that span
3567 # multiple lines should have their operators on the left side of
3568 # the line instead of the right side.
3569 self.assert_multi_line_lint(
3570 ' return attr->name() == srcAttr\n'
3571 ' || attr->name() == lowsrcAttr;\n',
3573 self.assert_multi_line_lint(
3574 ' return attr->name() == srcAttr ||\n'
3575 ' attr->name() == lowsrcAttr;\n',
3576 'Boolean expressions that span multiple lines should have their '
3577 'operators on the left side of the line instead of the right side.'
3578 ' [whitespace/operators] [4]')
3580 def test_spacing(self):
3581 # 1. Do not place spaces around unary operators.
3582 self.assert_multi_line_lint(
3585 self.assert_multi_line_lint(
3587 'Extra space for operator ++; [whitespace/operators] [4]')
3589 # 2. Do place spaces around binary and ternary operators.
3590 self.assert_multi_line_lint(
3593 self.assert_multi_line_lint(
3596 self.assert_multi_line_lint(
3599 self.assert_multi_line_lint(
3600 'return condition ? 1 : 0;',
3602 self.assert_multi_line_lint(
3604 'Missing spaces around = [whitespace/operators] [4]')
3605 self.assert_multi_line_lint(
3607 'Missing space after , [whitespace/comma] [3]')
3608 self.assert_multi_line_lint(
3610 'Missing spaces around | [whitespace/operators] [3]')
3611 # FIXME: We cannot catch this lint error.
3612 # self.assert_multi_line_lint(
3613 # 'return condition ? 1:0;',
3616 # 3. Place spaces between control statements and their parentheses.
3617 self.assert_multi_line_lint(
3621 self.assert_multi_line_lint(
3624 'Missing space before ( in if( [whitespace/parens] [5]')
3626 # 4. Do not place spaces between a function and its parentheses,
3627 # or between a parenthesis and its content.
3628 self.assert_multi_line_lint(
3631 self.assert_multi_line_lint(
3633 'Extra space before ( in function call [whitespace/parens] [4]')
3634 self.assert_multi_line_lint(
3636 ['Extra space after ( in function call [whitespace/parens] [4]',
3637 'Extra space before ) [whitespace/parens] [2]'])
3639 def test_line_breaking(self):
3640 # 1. Each statement should get its own line.
3641 self.assert_multi_line_lint(
3644 ' if (condition);\n'
3647 self.assert_multi_line_lint(
3648 ' if (condition) \\\n'
3651 self.assert_multi_line_lint(
3653 'More than one command on the same line [whitespace/newline] [4]')
3654 self.assert_multi_line_lint(
3655 ' if (condition) doIt();\n',
3656 'More than one command on the same line in if [whitespace/parens] [4]')
3657 # Ensure that having a # in the line doesn't hide the error.
3658 self.assert_multi_line_lint(
3659 ' x++; char a[] = "#";',
3660 'More than one command on the same line [whitespace/newline] [4]')
3661 # Ignore preprocessor if's.
3662 self.assert_multi_line_lint(
3663 ' #if (condition) || (condition2)\n',
3666 # 2. An else statement should go on the same line as a preceding
3667 # close brace if one is present, else it should line up with the
3669 self.assert_multi_line_lint(
3670 'if (condition) {\n'
3672 ' doSomethingAgain();\n'
3674 ' doSomethingElse();\n'
3675 ' doSomethingElseAgain();\n'
3678 self.assert_multi_line_lint(
3682 ' doSomethingElse();\n',
3684 self.assert_multi_line_lint(
3688 ' doSomethingElse();\n'
3689 ' doSomethingElseAgain();\n'
3692 self.assert_multi_line_lint(
3693 '#define TEST_ASSERT(expression) do { if (!(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0)\n',
3695 self.assert_multi_line_lint(
3696 '#define TEST_ASSERT(expression) do { if ( !(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0)\n',
3697 'Extra space after ( in if [whitespace/parens] [5]')
3698 # FIXME: currently we only check first conditional, so we cannot detect errors in next ones.
3699 # self.assert_multi_line_lint(
3700 # '#define TEST_ASSERT(expression) do { if (!(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0 )\n',
3701 # 'Mismatching spaces inside () in if [whitespace/parens] [5]')
3702 self.assert_multi_line_lint(
3703 'if (condition) {\n'
3705 ' doSomethingAgain();\n'
3708 ' doSomethingElse();\n'
3709 ' doSomethingElseAgain();\n'
3711 'An else should appear on the same line as the preceding } [whitespace/newline] [4]')
3712 self.assert_multi_line_lint(
3713 'if (condition) doSomething(); else doSomethingElse();\n',
3714 ['More than one command on the same line [whitespace/newline] [4]',
3715 'Else clause should never be on same line as else (use 2 lines) [whitespace/newline] [4]',
3716 'More than one command on the same line in if [whitespace/parens] [4]'])
3717 self.assert_multi_line_lint(
3718 'if (condition) doSomething(); else {\n'
3719 ' doSomethingElse();\n'
3721 ['More than one command on the same line in if [whitespace/parens] [4]',
3722 'One line control clauses should not use braces. [whitespace/braces] [4]'])
3723 self.assert_multi_line_lint(
3727 ' doSomethingElse();\n'
3729 'One line control clauses should not use braces. [whitespace/braces] [4]')
3730 self.assert_multi_line_lint(
3731 'if (condition) {\n'
3732 ' doSomething1();\n'
3733 ' doSomething2();\n'
3735 ' doSomethingElse();\n'
3737 'One line control clauses should not use braces. [whitespace/braces] [4]')
3738 self.assert_multi_line_lint(
3741 ' while (condition) { }\n'
3745 self.assert_multi_line_lint(
3748 ' for (i = 0; i < 42; i++) { foobar(); }\n'
3751 'More than one command on the same line in for [whitespace/parens] [4]')
3753 # 3. An else if statement should be written as an if statement
3754 # when the prior if concludes with a return statement.
3755 self.assert_multi_line_lint(
3756 'if (motivated) {\n'
3759 '} else if (tired)\n'
3762 self.assert_multi_line_lint(
3765 'else if (otherCondition)\n'
3766 ' doSomethingElse();\n',
3768 self.assert_multi_line_lint(
3772 ' doSomethingElse();\n',
3774 self.assert_multi_line_lint(
3776 ' returnValue = foo;\n'
3777 'else if (otherCondition)\n'
3778 ' returnValue = bar;\n',
3780 self.assert_multi_line_lint(
3782 ' returnValue = foo;\n'
3784 ' returnValue = bar;\n',
3786 self.assert_multi_line_lint(
3789 'else if (liquid)\n'
3796 self.assert_multi_line_lint(
3800 '} else if (greedy) {\n'
3802 ' return nothing;\n'
3804 'An else if statement should be written as an if statement when the '
3805 'prior "if" concludes with a return, break, continue or goto statement.'
3806 ' [readability/control_flow] [4]')
3807 self.assert_multi_line_lint(
3810 ' goto infiniteLoop;\n'
3811 ' } else if (evil)\n'
3813 'An else if statement should be written as an if statement when the '
3814 'prior "if" concludes with a return, break, continue or goto statement.'
3815 ' [readability/control_flow] [4]')
3816 self.assert_multi_line_lint(
3822 'else if (greedy)\n'
3824 ['This { should be at the end of the previous line [whitespace/braces] [4]',
3825 'An else should appear on the same line as the preceding } [whitespace/newline] [4]',
3826 'An else if statement should be written as an if statement when the '
3827 'prior "if" concludes with a return, break, continue or goto statement.'
3828 ' [readability/control_flow] [4]'])
3829 self.assert_multi_line_lint(
3834 'An else if statement should be written as an if statement when the '
3835 'prior "if" concludes with a return, break, continue or goto statement.'
3836 ' [readability/control_flow] [4]')
3837 self.assert_multi_line_lint(
3842 'An else statement can be removed when the prior "if" concludes '
3843 'with a return, break, continue or goto statement.'
3844 ' [readability/control_flow] [4]')
3845 self.assert_multi_line_lint(
3846 'if (motivated) {\n'
3853 'An else statement can be removed when the prior "if" concludes '
3854 'with a return, break, continue or goto statement.'
3855 ' [readability/control_flow] [4]')
3856 self.assert_multi_line_lint(
3863 'An else statement can be removed when the prior "if" concludes '
3864 'with a return, break, continue or goto statement.'
3865 ' [readability/control_flow] [4]')
3867 def test_braces(self):
3868 # 1. Function definitions: place each brace on its own line.
3869 self.assert_multi_line_lint(
3875 self.assert_multi_line_lint(
3879 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
3881 # 2. Other braces: place the open brace on the line preceding the
3882 # code block; place the close brace on its own line.
3883 self.assert_multi_line_lint(
3888 self.assert_multi_line_lint(
3889 'namespace WebCore {\n'
3893 self.assert_multi_line_lint(
3894 'for (int i = 0; i < 10; i++) {\n'
3898 self.assert_multi_line_lint(
3903 'This { should be at the end of the previous line [whitespace/braces] [4]')
3904 self.assert_multi_line_lint(
3909 'This { should be at the end of the previous line [whitespace/braces] [4]')
3910 self.assert_multi_line_lint(
3911 'for (int i = 0; i < 10; i++)\n'
3915 'This { should be at the end of the previous line [whitespace/braces] [4]')
3916 self.assert_multi_line_lint(
3921 'This { should be at the end of the previous line [whitespace/braces] [4]')
3922 self.assert_multi_line_lint(
3923 'foreach (Foo* foo, foos)\n'
3927 'This { should be at the end of the previous line [whitespace/braces] [4]')
3928 self.assert_multi_line_lint(
3931 'case foo: return;\n'
3933 'This { should be at the end of the previous line [whitespace/braces] [4]')
3934 self.assert_multi_line_lint(
3939 'This { should be at the end of the previous line [whitespace/braces] [4]')
3940 self.assert_multi_line_lint(
3941 'for (int i = 0; i < 10; i++)\n'
3945 'This { should be at the end of the previous line [whitespace/braces] [4]')
3946 self.assert_multi_line_lint(
3951 'This { should be at the end of the previous line [whitespace/braces] [4]')
3952 self.assert_multi_line_lint(
3955 'case foo: return;\n'
3957 'This { should be at the end of the previous line [whitespace/braces] [4]')
3958 self.assert_multi_line_lint(
3961 'case foo: return;\n'
3963 'This { should be at the end of the previous line [whitespace/braces] [4]')
3965 # 3. One-line control clauses should not use braces unless
3966 # comments are included or a single statement spans multiple
3968 self.assert_multi_line_lint(
3972 'One line control clauses should not use braces. [whitespace/braces] [4]')
3974 self.assert_multi_line_lint(
3975 'for (; foo; bar) {\n'
3978 'One line control clauses should not use braces. [whitespace/braces] [4]')
3980 self.assert_multi_line_lint(
3981 'foreach (foo, foos) {\n'
3984 'One line control clauses should not use braces. [whitespace/braces] [4]')
3986 self.assert_multi_line_lint(
3990 'One line control clauses should not use braces. [whitespace/braces] [4]')
3992 self.assert_multi_line_lint(
3998 'One line control clauses should not use braces. [whitespace/braces] [4]')
4000 self.assert_multi_line_lint(
4005 'One line control clauses should not use braces. [whitespace/braces] [4]')
4007 self.assert_multi_line_lint(
4009 ' // Some comment\n'
4014 self.assert_multi_line_lint(
4016 ' myFunction(reallyLongParam1, reallyLongParam2,\n'
4017 ' reallyLongParam3);\n'
4021 # 4. Control clauses without a body should use empty braces.
4022 self.assert_multi_line_lint(
4023 'for ( ; current; current = current->next) { }\n',
4025 self.assert_multi_line_lint(
4026 'for ( ; current;\n'
4027 ' current = current->next) { }\n',
4029 self.assert_multi_line_lint(
4030 'for ( ; current; current = current->next);\n',
4031 'Semicolon defining empty statement for this loop. Use { } instead. [whitespace/semicolon] [5]')
4032 self.assert_multi_line_lint(
4034 'Semicolon defining empty statement for this loop. Use { } instead. [whitespace/semicolon] [5]')
4035 self.assert_multi_line_lint(
4036 '} while (true);\n',
4039 def test_null_false_zero(self):
4040 # 1. In C++, the null pointer value should be written as 0. In C,
4041 # it should be written as NULL. In Objective-C and Objective-C++,
4042 # follow the guideline for C or C++, respectively, but use nil to
4043 # represent a null Objective-C object.
4045 'functionCall(NULL)',
4046 'Use 0 instead of NULL.'
4047 ' [readability/null] [5]',
4050 "// Don't use NULL in comments since it isn't in code.",
4051 'Use 0 or null instead of NULL (even in *comments*).'
4052 ' [readability/null] [4]',
4055 '"A string with NULL" // and a comment with NULL is tricky to flag correctly in cpp_style.',
4056 'Use 0 or null instead of NULL (even in *comments*).'
4057 ' [readability/null] [4]',
4060 '"A string containing NULL is ok"',
4068 'myVariable = NULLify',
4071 # Make sure that the NULL check does not apply to C and Objective-C files.
4073 'functionCall(NULL)',
4077 'functionCall(NULL)',
4081 # Make sure that the NULL check does not apply to g_object_{set,get} and
4082 # g_str{join,concat}
4084 'g_object_get(foo, "prop", &bar, NULL);',
4087 'g_object_set(foo, "prop", bar, NULL);',
4090 'g_build_filename(foo, bar, NULL);',
4093 'gst_bin_add_many(foo, bar, boo, NULL);',
4096 'gst_bin_remove_many(foo, bar, boo, NULL);',
4099 'gst_element_link_many(foo, bar, boo, NULL);',
4102 'gst_element_unlink_many(foo, bar, boo, NULL);',
4105 'gst_structure_get(foo, "value", G_TYPE_INT, &value, NULL);',
4108 'gst_structure_set(foo, "value", G_TYPE_INT, value, NULL);',
4111 'gst_structure_remove_fields(foo, "value", "bar", NULL);',
4114 'gst_structure_new("foo", "value", G_TYPE_INT, value, NULL);',
4117 'gst_structure_id_new(FOO, VALUE, G_TYPE_INT, value, NULL);',
4120 'gst_structure_id_set(FOO, VALUE, G_TYPE_INT, value, NULL);',
4123 'gst_structure_id_get(FOO, VALUE, G_TYPE_INT, &value, NULL);',
4126 'gchar* result = g_strconcat("part1", "part2", "part3", NULL);',
4129 'gchar* result = g_strconcat("part1", NULL);',
4132 'gchar* result = g_strjoin(",", "part1", "part2", "part3", NULL);',
4135 'gchar* result = g_strjoin(",", "part1", NULL);',
4138 'gchar* result = gdk_pixbuf_save_to_callback(pixbuf, function, data, type, error, NULL);',
4141 'gchar* result = gdk_pixbuf_save_to_buffer(pixbuf, function, data, type, error, NULL);',
4144 'gchar* result = gdk_pixbuf_save_to_stream(pixbuf, function, data, type, error, NULL);',
4147 'gtk_widget_style_get(style, "propertyName", &value, "otherName", &otherValue, NULL);',
4150 'gtk_widget_style_get_property(style, NULL, NULL);',
4151 'Use 0 instead of NULL. [readability/null] [5]',
4154 'gtk_widget_style_get_valist(style, NULL, NULL);',
4155 'Use 0 instead of NULL. [readability/null] [5]',
4158 # 2. C++ and C bool values should be written as true and
4159 # false. Objective-C BOOL values should be written as YES and NO.
4160 # FIXME: Implement this.
4162 # 3. Tests for true/false, null/non-null, and zero/non-zero should
4163 # all be done without equality comparisons.
4166 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
4167 ' [readability/comparison_to_zero] [5]')
4168 self.assert_lint_one_of_many_errors_re(
4169 'if (string != NULL)',
4170 r'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons\.')
4172 'if (condition == true)',
4173 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
4174 ' [readability/comparison_to_zero] [5]')
4176 'if (myVariable != /* Why would anyone put a comment here? */ false)',
4177 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
4178 ' [readability/comparison_to_zero] [5]')
4181 'if (0 /* This comment also looks odd to me. */ != aLongerVariableName)',
4182 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
4183 ' [readability/comparison_to_zero] [5]')
4184 self.assert_lint_one_of_many_errors_re(
4185 'if (NULL == thisMayBeNull)',
4186 r'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons\.')
4188 'if (true != anotherCondition)',
4189 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
4190 ' [readability/comparison_to_zero] [5]')
4192 'if (false == myBoolValue)',
4193 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
4194 ' [readability/comparison_to_zero] [5]')
4197 'if (fontType == trueType)',
4200 'if (othertrue == fontType)',
4203 'if (LIKELY(foo == 0))',
4206 'if (UNLIKELY(foo == 0))',
4209 'if (LIKELY(foo == NULL))',
4210 'Use 0 instead of NULL. [readability/null] [5]')
4212 'if (UNLIKELY(foo == NULL))',
4213 'Use 0 instead of NULL. [readability/null] [5]')
4216 def test_using_std(self):
4219 "Use 'using namespace std;' instead of 'using std::min;'."
4220 " [build/using_std] [4]",
4223 def test_max_macro(self):
4225 'int i = MAX(0, 1);',
4230 'int i = MAX(0, 1);',
4231 'Use std::max() or std::max<type>() instead of the MAX() macro.'
4232 ' [runtime/max_min_macros] [4]',
4236 'inline int foo() { return MAX(0, 1); }',
4237 'Use std::max() or std::max<type>() instead of the MAX() macro.'
4238 ' [runtime/max_min_macros] [4]',
4241 def test_min_macro(self):
4243 'int i = MIN(0, 1);',
4248 'int i = MIN(0, 1);',
4249 'Use std::min() or std::min<type>() instead of the MIN() macro.'
4250 ' [runtime/max_min_macros] [4]',
4254 'inline int foo() { return MIN(0, 1); }',
4255 'Use std::min() or std::min<type>() instead of the MIN() macro.'
4256 ' [runtime/max_min_macros] [4]',
4259 def test_names(self):
4260 name_underscore_error_message = " is incorrectly named. Don't use underscores in your identifier names. [readability/naming] [4]"
4261 name_tooshort_error_message = " is incorrectly named. Don't use the single letter 'l' as an identifier name. [readability/naming] [4]"
4263 # Basic cases from WebKit style guide.
4264 self.assert_lint('struct Data;', '')
4265 self.assert_lint('size_t bufferSize;', '')
4266 self.assert_lint('class HTMLDocument;', '')
4267 self.assert_lint('String mimeType();', '')
4268 self.assert_lint('size_t buffer_size;',
4269 'buffer_size' + name_underscore_error_message)
4270 self.assert_lint('short m_length;', '')
4271 self.assert_lint('short _length;',
4272 '_length' + name_underscore_error_message)
4273 self.assert_lint('short length_;',
4274 'length_' + name_underscore_error_message)
4275 self.assert_lint('unsigned _length;',
4276 '_length' + name_underscore_error_message)
4277 self.assert_lint('unsigned int _length;',
4278 '_length' + name_underscore_error_message)
4279 self.assert_lint('unsigned long long _length;',
4280 '_length' + name_underscore_error_message)
4282 # Allow underscores in Objective C files.
4283 self.assert_lint('unsigned long long _length;',
4286 self.assert_lint('unsigned long long _length;',
4289 self.assert_lint('#import "header_file.h"\n'
4290 'unsigned long long _length;',
4293 self.assert_lint('unsigned long long _length;\n'
4294 '@interface WebFullscreenWindow;',
4297 self.assert_lint('unsigned long long _length;\n'
4298 '@implementation WebFullscreenWindow;',
4301 self.assert_lint('unsigned long long _length;\n'
4302 '@class WebWindowFadeAnimation;',
4306 # Variable name 'l' is easy to confuse with '1'
4307 self.assert_lint('int l;', 'l' + name_tooshort_error_message)
4308 self.assert_lint('size_t l;', 'l' + name_tooshort_error_message)
4309 self.assert_lint('long long l;', 'l' + name_tooshort_error_message)
4311 # Pointers, references, functions, templates, and adjectives.
4312 self.assert_lint('char* under_score;',
4313 'under_score' + name_underscore_error_message)
4314 self.assert_lint('const int UNDER_SCORE;',
4315 'UNDER_SCORE' + name_underscore_error_message)
4316 self.assert_lint('static inline const char const& const under_score;',
4317 'under_score' + name_underscore_error_message)
4318 self.assert_lint('WebCore::RenderObject* under_score;',
4319 'under_score' + name_underscore_error_message)
4320 self.assert_lint('int func_name();',
4321 'func_name' + name_underscore_error_message)
4322 self.assert_lint('RefPtr<RenderObject*> under_score;',
4323 'under_score' + name_underscore_error_message)
4324 self.assert_lint('WTF::Vector<WTF::RefPtr<const RenderObject* const> > under_score;',
4325 'under_score' + name_underscore_error_message)
4326 self.assert_lint('int under_score[];',
4327 'under_score' + name_underscore_error_message)
4328 self.assert_lint('struct dirent* under_score;',
4329 'under_score' + name_underscore_error_message)
4330 self.assert_lint('long under_score;',
4331 'under_score' + name_underscore_error_message)
4332 self.assert_lint('long long under_score;',
4333 'under_score' + name_underscore_error_message)
4334 self.assert_lint('long double under_score;',
4335 'under_score' + name_underscore_error_message)
4336 self.assert_lint('long long int under_score;',
4337 'under_score' + name_underscore_error_message)
4339 # Declarations in control statement.
4340 self.assert_lint('if (int under_score = 42) {',
4341 'under_score' + name_underscore_error_message)
4342 self.assert_lint('else if (int under_score = 42) {',
4343 'under_score' + name_underscore_error_message)
4344 self.assert_lint('for (int under_score = 42; cond; i++) {',
4345 'under_score' + name_underscore_error_message)
4346 self.assert_lint('while (foo & under_score = bar) {',
4347 'under_score' + name_underscore_error_message)
4348 self.assert_lint('for (foo * under_score = p; cond; i++) {',
4349 'under_score' + name_underscore_error_message)
4350 self.assert_lint('for (foo * under_score; cond; i++) {',
4351 'under_score' + name_underscore_error_message)
4352 self.assert_lint('while (foo & value_in_thirdparty_library) {', '')
4353 self.assert_lint('while (foo * value_in_thirdparty_library) {', '')
4354 self.assert_lint('if (mli && S_OK == mli->foo()) {', '')
4356 # More member variables and functions.
4357 self.assert_lint('int SomeClass::s_validName', '')
4358 self.assert_lint('int m_under_score;',
4359 'm_under_score' + name_underscore_error_message)
4360 self.assert_lint('int SomeClass::s_under_score = 0;',
4361 'SomeClass::s_under_score' + name_underscore_error_message)
4362 self.assert_lint('int SomeClass::under_score = 0;',
4363 'SomeClass::under_score' + name_underscore_error_message)
4366 self.assert_lint('return INT_MAX;', '')
4367 self.assert_lint('return_t under_score;',
4368 'under_score' + name_underscore_error_message)
4369 self.assert_lint('goto under_score;',
4370 'under_score' + name_underscore_error_message)
4371 self.assert_lint('delete static_cast<Foo*>(p);', '')
4373 # Multiple variables in one line.
4374 self.assert_lint('void myFunction(int variable1, int another_variable);',
4375 'another_variable' + name_underscore_error_message)
4376 self.assert_lint('int variable1, another_variable;',
4377 'another_variable' + name_underscore_error_message)
4378 self.assert_lint('int first_variable, secondVariable;',
4379 'first_variable' + name_underscore_error_message)
4380 self.assert_lint('void my_function(int variable_1, int variable_2);',
4381 ['my_function' + name_underscore_error_message,
4382 'variable_1' + name_underscore_error_message,
4383 'variable_2' + name_underscore_error_message])
4384 self.assert_lint('for (int variable_1, variable_2;;) {',
4385 ['variable_1' + name_underscore_error_message,
4386 'variable_2' + name_underscore_error_message])
4388 # There is an exception for op code functions but only in the JavaScriptCore directory.
4389 self.assert_lint('void this_op_code(int var1, int var2)', '', 'Source/JavaScriptCore/foo.cpp')
4390 self.assert_lint('void op_code(int var1, int var2)', '', 'Source/JavaScriptCore/foo.cpp')
4391 self.assert_lint('void this_op_code(int var1, int var2)', 'this_op_code' + name_underscore_error_message)
4393 # GObject requires certain magical names in class declarations.
4394 self.assert_lint('void webkit_dom_object_init();', '')
4395 self.assert_lint('void webkit_dom_object_class_init();', '')
4397 # There is an exception for some unit tests that begin with "tst_".
4398 self.assert_lint('void tst_QWebFrame::arrayObjectEnumerable(int var1, int var2)', '')
4400 # The Qt API uses names that begin with "qt_".
4401 self.assert_lint('void QTFrame::qt_drt_is_awesome(int var1, int var2)', '')
4402 self.assert_lint('void qt_drt_is_awesome(int var1, int var2);', '')
4404 # Cairo forward-declarations should not be a failure.
4405 self.assert_lint('typedef struct _cairo cairo_t;', '')
4406 self.assert_lint('typedef struct _cairo_surface cairo_surface_t;', '')
4407 self.assert_lint('typedef struct _cairo_scaled_font cairo_scaled_font_t;', '')
4409 # EFL forward-declarations should not be a failure.
4410 self.assert_lint('typedef struct _Ecore_Evas Ecore_Evas;', '')
4411 self.assert_lint('typedef struct _Ecore_Pipe Ecore_Pipe;', '')
4412 self.assert_lint('typedef struct _Eina_Rectangle Eina_Rectangle;', '')
4413 self.assert_lint('typedef struct _Evas_Object Evas_Object;', '')
4415 # NPAPI functions that start with NPN_, NPP_ or NP_ are allowed.
4416 self.assert_lint('void NPN_Status(NPP, const char*)', '')
4417 self.assert_lint('NPError NPP_SetWindow(NPP instance, NPWindow *window)', '')
4418 self.assert_lint('NPObject* NP_Allocate(NPP, NPClass*)', '')
4420 # const_iterator is allowed as well.
4421 self.assert_lint('typedef VectorType::const_iterator const_iterator;', '')
4423 # vm_throw is allowed as well.
4424 self.assert_lint('int vm_throw;', '')
4427 self.assert_lint('unsigned _fillRule : 1;',
4428 '_fillRule' + name_underscore_error_message)
4430 # new operators in initialization.
4431 self.assert_lint('OwnPtr<uint32_t> variable(new uint32_t);', '')
4432 self.assert_lint('OwnPtr<uint32_t> variable(new (expr) uint32_t);', '')
4433 self.assert_lint('OwnPtr<uint32_t> under_score(new uint32_t);',
4434 'under_score' + name_underscore_error_message)
4436 def test_parameter_names(self):
4437 # Leave meaningless variable names out of function declarations.
4438 meaningless_variable_name_error_message = 'The parameter name "%s" adds no information, so it should be removed. [readability/parameter_name] [5]'
4440 parameter_error_rules = ('-',
4441 '+readability/parameter_name')
4442 # No variable name, so no error.
4443 self.assertEquals('',
4444 self.perform_lint('void func(int);', 'test.cpp', parameter_error_rules))
4446 # Verify that copying the name of the set function causes the error (with some odd casing).
4447 self.assertEquals(meaningless_variable_name_error_message % 'itemCount',
4448 self.perform_lint('void setItemCount(size_t itemCount);', 'test.cpp', parameter_error_rules))
4449 self.assertEquals(meaningless_variable_name_error_message % 'abcCount',
4450 self.perform_lint('void setABCCount(size_t abcCount);', 'test.cpp', parameter_error_rules))
4452 # Verify that copying a type name will trigger the warning (even if the type is a template parameter).
4453 self.assertEquals(meaningless_variable_name_error_message % 'context',
4454 self.perform_lint('void funct(PassRefPtr<ScriptExecutionContext> context);', 'test.cpp', parameter_error_rules))
4456 # Verify that acronyms as variable names trigger the error (for both set functions and type names).
4457 self.assertEquals(meaningless_variable_name_error_message % 'ec',
4458 self.perform_lint('void setExceptionCode(int ec);', 'test.cpp', parameter_error_rules))
4459 self.assertEquals(meaningless_variable_name_error_message % 'ec',
4460 self.perform_lint('void funct(ExceptionCode ec);', 'test.cpp', parameter_error_rules))
4462 # 'object' alone, appended, or as part of an acronym is meaningless.
4463 self.assertEquals(meaningless_variable_name_error_message % 'object',
4464 self.perform_lint('void funct(RenderView object);', 'test.cpp', parameter_error_rules))
4465 self.assertEquals(meaningless_variable_name_error_message % 'viewObject',
4466 self.perform_lint('void funct(RenderView viewObject);', 'test.cpp', parameter_error_rules))
4467 self.assertEquals(meaningless_variable_name_error_message % 'rvo',
4468 self.perform_lint('void funct(RenderView rvo);', 'test.cpp', parameter_error_rules))
4470 # Check that r, g, b, and a are allowed.
4471 self.assertEquals('',
4472 self.perform_lint('void setRGBAValues(int r, int g, int b, int a);', 'test.cpp', parameter_error_rules))
4474 # Verify that a simple substring match isn't done which would cause false positives.
4475 self.assertEquals('',
4476 self.perform_lint('void setNateLateCount(size_t elate);', 'test.cpp', parameter_error_rules))
4477 self.assertEquals('',
4478 self.perform_lint('void funct(NateLate elate);', 'test.cpp', parameter_error_rules))
4480 # Don't have generate warnings for functions (only declarations).
4481 self.assertEquals('',
4482 self.perform_lint('void funct(PassRefPtr<ScriptExecutionContext> context)\n'
4484 '}\n', 'test.cpp', parameter_error_rules))
4486 def test_comments(self):
4487 # A comment at the beginning of a line is ok.
4488 self.assert_lint('// comment', '')
4489 self.assert_lint(' // comment', '')
4491 self.assert_lint('} // namespace WebCore',
4492 'One space before end of line comments'
4493 ' [whitespace/comments] [5]')
4495 def test_webkit_export_check(self):
4496 webkit_export_error_rules = ('-',
4497 '+readability/webkit_export')
4498 self.assertEquals('',
4499 self.perform_lint('WEBKIT_EXPORT int foo();\n',
4500 'WebKit/chromium/public/test.h',
4501 webkit_export_error_rules))
4502 self.assertEquals('WEBKIT_EXPORT should only be used in header files. [readability/webkit_export] [5]',
4503 self.perform_lint('WEBKIT_EXPORT int foo();\n',
4504 'WebKit/chromium/public/test.cpp',
4505 webkit_export_error_rules))
4506 self.assertEquals('WEBKIT_EXPORT should only appear in the chromium public directory. [readability/webkit_export] [5]',
4507 self.perform_lint('WEBKIT_EXPORT int foo();\n',
4508 'WebKit/chromium/src/test.h',
4509 webkit_export_error_rules))
4510 self.assertEquals('WEBKIT_EXPORT should not be used on a function with a body. [readability/webkit_export] [5]',
4511 self.perform_lint('WEBKIT_EXPORT int foo() { }\n',
4512 'WebKit/chromium/public/test.h',
4513 webkit_export_error_rules))
4514 self.assertEquals('WEBKIT_EXPORT should not be used on a function with a body. [readability/webkit_export] [5]',
4515 self.perform_lint('WEBKIT_EXPORT inline int foo()\n'
4518 'WebKit/chromium/public/test.h',
4519 webkit_export_error_rules))
4520 self.assertEquals('WEBKIT_EXPORT should not be used with a pure virtual function. [readability/webkit_export] [5]',
4521 self.perform_lint('{}\n'
4526 'WebKit/chromium/public/test.h',
4527 webkit_export_error_rules))
4528 self.assertEquals('',
4529 self.perform_lint('{}\n'
4535 webkit_export_error_rules))
4537 def test_other(self):
4538 # FIXME: Implement this.
4542 class CppCheckerTest(unittest.TestCase):
4544 """Tests CppChecker class."""
4546 def mock_handle_style_error(self):
4550 return CppChecker("foo", "h", self.mock_handle_style_error, 3)
4552 def test_init(self):
4553 """Test __init__ constructor."""
4554 checker = self._checker()
4555 self.assertEquals(checker.file_extension, "h")
4556 self.assertEquals(checker.file_path, "foo")
4557 self.assertEquals(checker.handle_style_error, self.mock_handle_style_error)
4558 self.assertEquals(checker.min_confidence, 3)
4561 """Test __eq__ equality function."""
4562 checker1 = self._checker()
4563 checker2 = self._checker()
4566 self.assertTrue(checker1 == checker2)
4568 def mock_handle_style_error2(self):
4571 # Verify that a difference in any argument cause equality to fail.
4572 checker = CppChecker("foo", "h", self.mock_handle_style_error, 3)
4573 self.assertFalse(checker == CppChecker("bar", "h", self.mock_handle_style_error, 3))
4574 self.assertFalse(checker == CppChecker("foo", "c", self.mock_handle_style_error, 3))
4575 self.assertFalse(checker == CppChecker("foo", "h", mock_handle_style_error2, 3))
4576 self.assertFalse(checker == CppChecker("foo", "h", self.mock_handle_style_error, 4))
4579 """Test __ne__ inequality function."""
4580 checker1 = self._checker()
4581 checker2 = self._checker()
4584 # By default, __ne__ always returns true on different objects.
4585 # Thus, just check the distinguishing case to verify that the
4586 # code defines __ne__.
4587 self.assertFalse(checker1 != checker2)
4591 """A global check to make sure all error-categories have been tested.
4593 The main tearDown() routine is the only code we can guarantee will be
4594 run after all other tests have been executed.
4597 if _run_verifyallcategoriesseen:
4598 ErrorCollector(None).verify_all_categories_are_seen()
4600 # If nobody set the global _run_verifyallcategoriesseen, then
4601 # we assume we shouldn't run the test
4604 if __name__ == '__main__':
4606 # We don't want to run the verify_all_categories_are_seen() test unless
4607 # we're running the full test suite: if we only run one test,
4608 # obviously we're not going to see all the error categories. So we
4609 # only run verify_all_categories_are_seen() when no commandline flags
4611 global _run_verifyallcategoriesseen
4612 _run_verifyallcategoriesseen = (len(sys.argv) == 1)