1 # -*- coding: utf-8; -*-
3 # Copyright (C) 2011 Google Inc. All rights reserved.
4 # Copyright (C) 2009 Torch Mobile Inc.
5 # Copyright (C) 2009, 2013 Apple Inc. All rights reserved.
6 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are
12 # * Redistributions of source code must retain the above copyright
13 # notice, this list of conditions and the following disclaimer.
14 # * Redistributions in binary form must reproduce the above
15 # copyright notice, this list of conditions and the following disclaimer
16 # in the documentation and/or other materials provided with the
18 # * Neither the name of Google Inc. nor the names of its
19 # contributors may be used to endorse or promote products derived from
20 # this software without specific prior written permission.
22 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 """Unit test for cpp_style.py."""
36 # FIXME: Add a good test that tests UpdateIncludeState.
42 import unittest2 as unittest
43 import cpp as cpp_style
44 from cpp import CppChecker
45 from ..filter import FilterConfiguration
47 # This class works as an error collector and replaces cpp_style.Error
48 # function for the unit tests. We also verify each category we see
49 # is in STYLE_CATEGORIES, to help keep that list up to date.
51 _all_style_categories = CppChecker.categories
52 # This is a list including all categories seen in any unit test.
53 _seen_style_categories = {}
55 def __init__(self, assert_fn, filter=None, lines_to_check=None):
56 """assert_fn: a function to call when we notice a problem.
57 filter: filters the errors that we are concerned about."""
58 self._assert_fn = assert_fn
60 self._lines_to_check = lines_to_check
62 filter = FilterConfiguration()
65 def __call__(self, line_number, category, confidence, message):
66 self._assert_fn(category in self._all_style_categories,
67 'Message "%s" has category "%s",'
68 ' which is not in STYLE_CATEGORIES' % (message, category))
70 if self._lines_to_check and not line_number in self._lines_to_check:
73 if self._filter.should_check(category, ""):
74 self._seen_style_categories[category] = 1
75 self._errors.append('%s [%s] [%d]' % (message, category, confidence))
79 if len(self._errors) < 2:
80 return ''.join(self._errors) # Most tests expect to have a string.
82 return self._errors # Let's give a list if there is more than one.
84 def result_list(self):
87 def verify_all_categories_are_seen(self):
88 """Fails if there's a category in _all_style_categories - _seen_style_categories.
90 This should only be called after all tests are run, so
91 _seen_style_categories has had a chance to fully populate. Since
92 this isn't called from within the normal unittest framework, we
93 can't use the normal unittest assert macros. Instead we just exit
94 when we see an error. Good thing this test is always run last!
96 for category in self._all_style_categories:
97 if category not in self._seen_style_categories:
99 sys.exit('FATAL ERROR: There are no tests for category "%s"' % category)
102 # This class is a lame mock of codecs. We do not verify filename, mode, or
103 # encoding, but for the current use case it is not needed.
105 def __init__(self, mock_file):
106 self.mock_file = mock_file
108 def open(self, unused_filename, unused_mode, unused_encoding, _): # NOLINT
109 # (lint doesn't like open as a method name)
110 return self.mock_file
113 class CppFunctionsTest(unittest.TestCase):
115 """Supports testing functions that do not need CppStyleTestBase."""
117 def test_convert_to_lower_with_underscores(self):
118 self.assertEqual(cpp_style._convert_to_lower_with_underscores('ABC'), 'abc')
119 self.assertEqual(cpp_style._convert_to_lower_with_underscores('aB'), 'a_b')
120 self.assertEqual(cpp_style._convert_to_lower_with_underscores('isAName'), 'is_a_name')
121 self.assertEqual(cpp_style._convert_to_lower_with_underscores('AnotherTest'), 'another_test')
122 self.assertEqual(cpp_style._convert_to_lower_with_underscores('PassRefPtr<MyClass>'), 'pass_ref_ptr<my_class>')
123 self.assertEqual(cpp_style._convert_to_lower_with_underscores('_ABC'), '_abc')
125 def test_create_acronym(self):
126 self.assertEqual(cpp_style._create_acronym('ABC'), 'ABC')
127 self.assertEqual(cpp_style._create_acronym('IsAName'), 'IAN')
128 self.assertEqual(cpp_style._create_acronym('PassRefPtr<MyClass>'), 'PRP<MC>')
130 def test_is_c_or_objective_c(self):
131 clean_lines = cpp_style.CleansedLines([''])
132 clean_objc_lines = cpp_style.CleansedLines(['#import "header.h"'])
133 self.assertTrue(cpp_style._FileState(clean_lines, 'c').is_c_or_objective_c())
134 self.assertTrue(cpp_style._FileState(clean_lines, 'm').is_c_or_objective_c())
135 self.assertFalse(cpp_style._FileState(clean_lines, 'cpp').is_c_or_objective_c())
136 self.assertFalse(cpp_style._FileState(clean_lines, 'cc').is_c_or_objective_c())
137 self.assertFalse(cpp_style._FileState(clean_lines, 'h').is_c_or_objective_c())
138 self.assertTrue(cpp_style._FileState(clean_objc_lines, 'h').is_c_or_objective_c())
140 def test_parameter(self):
142 parameter = cpp_style.Parameter('ExceptionCode', 13, 1)
143 self.assertEqual(parameter.type, 'ExceptionCode')
144 self.assertEqual(parameter.name, '')
145 self.assertEqual(parameter.row, 1)
147 # Test type and name.
148 parameter = cpp_style.Parameter('PassRefPtr<MyClass> parent', 19, 1)
149 self.assertEqual(parameter.type, 'PassRefPtr<MyClass>')
150 self.assertEqual(parameter.name, 'parent')
151 self.assertEqual(parameter.row, 1)
153 # Test type, no name, with default value.
154 parameter = cpp_style.Parameter('MyClass = 0', 7, 0)
155 self.assertEqual(parameter.type, 'MyClass')
156 self.assertEqual(parameter.name, '')
157 self.assertEqual(parameter.row, 0)
159 # Test type, name, and default value.
160 parameter = cpp_style.Parameter('MyClass a = 0', 7, 0)
161 self.assertEqual(parameter.type, 'MyClass')
162 self.assertEqual(parameter.name, 'a')
163 self.assertEqual(parameter.row, 0)
165 def test_single_line_view(self):
166 start_position = cpp_style.Position(row=1, column=1)
167 end_position = cpp_style.Position(row=3, column=1)
168 single_line_view = cpp_style.SingleLineView(['0', 'abcde', 'fgh', 'i'], start_position, end_position)
169 self.assertEqual(single_line_view.single_line, 'bcde fgh i')
170 self.assertEqual(single_line_view.convert_column_to_row(0), 1)
171 self.assertEqual(single_line_view.convert_column_to_row(4), 1)
172 self.assertEqual(single_line_view.convert_column_to_row(5), 2)
173 self.assertEqual(single_line_view.convert_column_to_row(8), 2)
174 self.assertEqual(single_line_view.convert_column_to_row(9), 3)
175 self.assertEqual(single_line_view.convert_column_to_row(100), 3)
177 start_position = cpp_style.Position(row=0, column=3)
178 end_position = cpp_style.Position(row=0, column=4)
179 single_line_view = cpp_style.SingleLineView(['abcdef'], start_position, end_position)
180 self.assertEqual(single_line_view.single_line, 'd')
182 def test_create_skeleton_parameters(self):
183 self.assertEqual(cpp_style.create_skeleton_parameters(''), '')
184 self.assertEqual(cpp_style.create_skeleton_parameters(' '), ' ')
185 self.assertEqual(cpp_style.create_skeleton_parameters('long'), 'long,')
186 self.assertEqual(cpp_style.create_skeleton_parameters('const unsigned long int'), ' int,')
187 self.assertEqual(cpp_style.create_skeleton_parameters('long int*'), ' int ,')
188 self.assertEqual(cpp_style.create_skeleton_parameters('PassRefPtr<Foo> a'), 'PassRefPtr a,')
189 self.assertEqual(cpp_style.create_skeleton_parameters(
190 'ComplexTemplate<NestedTemplate1<MyClass1, MyClass2>, NestedTemplate1<MyClass1, MyClass2> > param, int second'),
191 'ComplexTemplate param, int second,')
192 self.assertEqual(cpp_style.create_skeleton_parameters('int = 0, Namespace::Type& a'), 'int , Type a,')
193 # Create skeleton parameters is a bit too aggressive with function variables, but
194 # it allows for parsing other parameters and declarations like this are rare.
195 self.assertEqual(cpp_style.create_skeleton_parameters('void (*fn)(int a, int b), Namespace::Type& a'),
198 # This doesn't look like functions declarations but the simplifications help to eliminate false positives.
199 self.assertEqual(cpp_style.create_skeleton_parameters('b{d}'), 'b ,')
201 def test_find_parameter_name_index(self):
202 self.assertEqual(cpp_style.find_parameter_name_index(' int a '), 5)
203 self.assertEqual(cpp_style.find_parameter_name_index(' PassRefPtr '), 16)
204 self.assertEqual(cpp_style.find_parameter_name_index('double'), 6)
206 def test_parameter_list(self):
207 elided_lines = ['int blah(PassRefPtr<MyClass> paramName,',
208 'const Other1Class& foo,',
209 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const * param = new ComplexTemplate<Class1, NestedTemplate<P1, P2> >(34, 42),',
210 'int* myCount = 0);']
211 start_position = cpp_style.Position(row=0, column=8)
212 end_position = cpp_style.Position(row=3, column=16)
214 expected_parameters = ({'type': 'PassRefPtr<MyClass>', 'name': 'paramName', 'row': 0},
215 {'type': 'const Other1Class&', 'name': 'foo', 'row': 1},
216 {'type': 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const *', 'name': 'param', 'row': 2},
217 {'type': 'int*', 'name': 'myCount', 'row': 3})
219 for parameter in cpp_style.parameter_list(elided_lines, start_position, end_position):
220 expected_parameter = expected_parameters[index]
221 self.assertEqual(parameter.type, expected_parameter['type'])
222 self.assertEqual(parameter.name, expected_parameter['name'])
223 self.assertEqual(parameter.row, expected_parameter['row'])
225 self.assertEqual(index, len(expected_parameters))
227 def test_check_parameter_against_text(self):
228 error_collector = ErrorCollector(self.assertTrue)
229 parameter = cpp_style.Parameter('FooF ooF', 4, 1)
230 self.assertFalse(cpp_style._check_parameter_name_against_text(parameter, 'FooF', error_collector))
231 self.assertEqual(error_collector.results(),
232 'The parameter name "ooF" adds no information, so it should be removed. [readability/parameter_name] [5]')
234 class CppStyleTestBase(unittest.TestCase):
235 """Provides some useful helper functions for cpp_style tests.
238 min_confidence: An integer that is the current minimum confidence
243 # FIXME: Refactor the unit tests so the confidence level is passed
244 # explicitly, just like it is in the real code.
247 # Helper function to avoid needing to explicitly pass confidence
248 # in all the unit test calls to cpp_style.process_file_data().
249 def process_file_data(self, filename, file_extension, lines, error, unit_test_config={}):
250 checker = CppChecker(filename, file_extension, error, self.min_confidence, unit_test_config)
253 def perform_lint(self, code, filename, basic_error_rules, unit_test_config={}, lines_to_check=None):
254 error_collector = ErrorCollector(self.assertTrue, FilterConfiguration(basic_error_rules), lines_to_check)
255 lines = code.split('\n')
256 extension = filename.split('.')[1]
257 self.process_file_data(filename, extension, lines, error_collector, unit_test_config)
258 return error_collector.results()
260 # Perform lint on single line of input and return the error message.
261 def perform_single_line_lint(self, code, filename):
262 basic_error_rules = ('-build/header_guard',
264 '-readability/fn_size',
265 '-readability/parameter_name',
266 '-readability/pass_ptr',
267 '-whitespace/ending_newline')
268 return self.perform_lint(code, filename, basic_error_rules)
270 # Perform lint over multiple lines and return the error message.
271 def perform_multi_line_lint(self, code, file_extension):
272 basic_error_rules = ('-build/header_guard',
274 '-readability/parameter_name',
275 '-whitespace/ending_newline')
276 return self.perform_lint(code, 'test.' + file_extension, basic_error_rules)
278 # Only keep some errors related to includes, namespaces and rtti.
279 def perform_language_rules_check(self, filename, code, lines_to_check=None):
280 basic_error_rules = ('-',
282 '+build/include_order',
285 return self.perform_lint(code, filename, basic_error_rules, lines_to_check=lines_to_check)
287 # Only keep function length errors.
288 def perform_function_lengths_check(self, code):
289 basic_error_rules = ('-',
290 '+readability/fn_size')
291 return self.perform_lint(code, 'test.cpp', basic_error_rules)
293 # Only keep pass ptr errors.
294 def perform_pass_ptr_check(self, code):
295 basic_error_rules = ('-',
296 '+readability/pass_ptr')
297 return self.perform_lint(code, 'test.cpp', basic_error_rules)
299 # Only keep leaky pattern errors.
300 def perform_leaky_pattern_check(self, code):
301 basic_error_rules = ('-',
302 '+runtime/leaky_pattern')
303 return self.perform_lint(code, 'test.cpp', basic_error_rules)
305 # Only include what you use errors.
306 def perform_include_what_you_use(self, code, filename='foo.h', io=codecs):
307 basic_error_rules = ('-',
308 '+build/include_what_you_use')
309 unit_test_config = {cpp_style.INCLUDE_IO_INJECTION_KEY: io}
310 return self.perform_lint(code, filename, basic_error_rules, unit_test_config)
312 # Perform lint and compare the error message with "expected_message".
313 def assert_lint(self, code, expected_message, file_name='foo.cpp'):
314 self.assertEqual(expected_message, self.perform_single_line_lint(code, file_name))
316 def assert_lint_one_of_many_errors_re(self, code, expected_message_re, file_name='foo.cpp'):
317 messages = self.perform_single_line_lint(code, file_name)
318 for message in messages:
319 if re.search(expected_message_re, message):
322 self.assertEqual(expected_message_re, messages)
324 def assert_multi_line_lint(self, code, expected_message, file_name='foo.h'):
325 file_extension = file_name[file_name.rfind('.') + 1:]
326 self.assertEqual(expected_message, self.perform_multi_line_lint(code, file_extension))
328 def assert_multi_line_lint_re(self, code, expected_message_re, file_name='foo.h'):
329 file_extension = file_name[file_name.rfind('.') + 1:]
330 message = self.perform_multi_line_lint(code, file_extension)
331 if not re.search(expected_message_re, message):
332 self.fail('Message was:\n' + message + 'Expected match to "' + expected_message_re + '"')
334 def assert_language_rules_check(self, file_name, code, expected_message, lines_to_check=None):
335 self.assertEqual(expected_message,
336 self.perform_language_rules_check(file_name, code, lines_to_check))
338 def assert_include_what_you_use(self, code, expected_message):
339 self.assertEqual(expected_message,
340 self.perform_include_what_you_use(code))
342 def assert_blank_lines_check(self, lines, start_errors, end_errors):
343 error_collector = ErrorCollector(self.assertTrue)
344 self.process_file_data('foo.cpp', 'cpp', lines, error_collector)
347 error_collector.results().count(
348 'Blank line at the start of a code block. Is this needed?'
349 ' [whitespace/blank_line] [2]'))
352 error_collector.results().count(
353 'Blank line at the end of a code block. Is this needed?'
354 ' [whitespace/blank_line] [3]'))
356 def assert_positions_equal(self, position, tuple_position):
357 """Checks if the two positions are equal.
359 position: a cpp_style.Position object.
360 tuple_position: a tuple (row, column) to compare against."""
361 self.assertEqual(position, cpp_style.Position(tuple_position[0], tuple_position[1]),
362 'position %s, tuple_position %s' % (position, tuple_position))
365 class FunctionDetectionTest(CppStyleTestBase):
366 def perform_function_detection(self, lines, function_information, detection_line=0):
367 clean_lines = cpp_style.CleansedLines(lines)
368 function_state = cpp_style._FunctionState(5)
369 error_collector = ErrorCollector(self.assertTrue)
370 cpp_style.detect_functions(clean_lines, detection_line, function_state, error_collector)
371 if not function_information:
372 self.assertEqual(function_state.in_a_function, False)
374 self.assertEqual(function_state.in_a_function, True)
375 self.assertEqual(function_state.current_function, function_information['name'] + '()')
376 self.assertEqual(function_state.modifiers_and_return_type(), function_information['modifiers_and_return_type'])
377 self.assertEqual(function_state.is_pure, function_information['is_pure'])
378 self.assertEqual(function_state.is_declaration, function_information['is_declaration'])
379 self.assert_positions_equal(function_state.function_name_start_position, function_information['function_name_start_position'])
380 self.assert_positions_equal(function_state.parameter_start_position, function_information['parameter_start_position'])
381 self.assert_positions_equal(function_state.parameter_end_position, function_information['parameter_end_position'])
382 self.assert_positions_equal(function_state.body_start_position, function_information['body_start_position'])
383 self.assert_positions_equal(function_state.end_position, function_information['end_position'])
384 expected_parameters = function_information.get('parameter_list')
385 if expected_parameters:
386 actual_parameters = function_state.parameter_list()
387 self.assertEqual(len(actual_parameters), len(expected_parameters))
388 for index in range(len(expected_parameters)):
389 actual_parameter = actual_parameters[index]
390 expected_parameter = expected_parameters[index]
391 self.assertEqual(actual_parameter.type, expected_parameter['type'])
392 self.assertEqual(actual_parameter.name, expected_parameter['name'])
393 self.assertEqual(actual_parameter.row, expected_parameter['row'])
395 def test_basic_function_detection(self):
396 self.perform_function_detection(
397 ['void theTestFunctionName(int) {',
399 {'name': 'theTestFunctionName',
400 'modifiers_and_return_type': 'void',
401 'function_name_start_position': (0, 5),
402 'parameter_start_position': (0, 24),
403 'parameter_end_position': (0, 29),
404 'body_start_position': (0, 30),
405 'end_position': (1, 1),
407 'is_declaration': False})
409 def test_function_declaration_detection(self):
410 self.perform_function_detection(
411 ['void aFunctionName(int);'],
412 {'name': 'aFunctionName',
413 'modifiers_and_return_type': 'void',
414 'function_name_start_position': (0, 5),
415 'parameter_start_position': (0, 18),
416 'parameter_end_position': (0, 23),
417 'body_start_position': (0, 23),
418 'end_position': (0, 24),
420 'is_declaration': True})
422 self.perform_function_detection(
423 ['CheckedInt<T> operator /(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
424 {'name': 'operator /',
425 'modifiers_and_return_type': 'CheckedInt<T>',
426 'function_name_start_position': (0, 14),
427 'parameter_start_position': (0, 24),
428 'parameter_end_position': (0, 76),
429 'body_start_position': (0, 76),
430 'end_position': (0, 77),
432 'is_declaration': True})
434 self.perform_function_detection(
435 ['CheckedInt<T> operator -(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
436 {'name': 'operator -',
437 'modifiers_and_return_type': 'CheckedInt<T>',
438 'function_name_start_position': (0, 14),
439 'parameter_start_position': (0, 24),
440 'parameter_end_position': (0, 76),
441 'body_start_position': (0, 76),
442 'end_position': (0, 77),
444 'is_declaration': True})
446 self.perform_function_detection(
447 ['CheckedInt<T> operator !=(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
448 {'name': 'operator !=',
449 'modifiers_and_return_type': 'CheckedInt<T>',
450 'function_name_start_position': (0, 14),
451 'parameter_start_position': (0, 25),
452 'parameter_end_position': (0, 77),
453 'body_start_position': (0, 77),
454 'end_position': (0, 78),
456 'is_declaration': True})
458 self.perform_function_detection(
459 ['CheckedInt<T> operator +(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
460 {'name': 'operator +',
461 'modifiers_and_return_type': 'CheckedInt<T>',
462 'function_name_start_position': (0, 14),
463 'parameter_start_position': (0, 24),
464 'parameter_end_position': (0, 76),
465 'body_start_position': (0, 76),
466 'end_position': (0, 77),
468 'is_declaration': True})
470 def test_pure_function_detection(self):
471 self.perform_function_detection(
472 ['virtual void theTestFunctionName(int = 0);'],
473 {'name': 'theTestFunctionName',
474 'modifiers_and_return_type': 'virtual void',
475 'function_name_start_position': (0, 13),
476 'parameter_start_position': (0, 32),
477 'parameter_end_position': (0, 41),
478 'body_start_position': (0, 41),
479 'end_position': (0, 42),
481 'is_declaration': True})
483 self.perform_function_detection(
484 ['virtual void theTestFunctionName(int) = 0;'],
485 {'name': 'theTestFunctionName',
486 'modifiers_and_return_type': 'virtual void',
487 'function_name_start_position': (0, 13),
488 'parameter_start_position': (0, 32),
489 'parameter_end_position': (0, 37),
490 'body_start_position': (0, 41),
491 'end_position': (0, 42),
493 'is_declaration': True})
495 # Hopefully, no one writes code like this but it is a tricky case.
496 self.perform_function_detection(
497 ['virtual void theTestFunctionName(int)',
500 {'name': 'theTestFunctionName',
501 'modifiers_and_return_type': 'virtual void',
502 'function_name_start_position': (0, 13),
503 'parameter_start_position': (0, 32),
504 'parameter_end_position': (0, 37),
505 'body_start_position': (2, 3),
506 'end_position': (2, 4),
508 'is_declaration': True})
510 def test_ignore_macros(self):
511 self.perform_function_detection(['void aFunctionName(int); \\'], None)
513 def test_non_functions(self):
514 # This case exposed an error because the open brace was in quotes.
515 self.perform_function_detection(
517 ' "stmdb sp!, {r1-r3}" "\n"',
519 # This isn't a function but it looks like one to our simple
520 # algorithm and that is ok.
522 'modifiers_and_return_type': '',
523 'function_name_start_position': (0, 0),
524 'parameter_start_position': (0, 3),
525 'parameter_end_position': (2, 1),
526 'body_start_position': (2, 1),
527 'end_position': (2, 2),
529 'is_declaration': True})
531 # Simple test case with something that is not a function.
532 self.perform_function_detection(['class Stuff;'], None)
534 def test_parameter_list(self):
535 # A function with no arguments.
536 function_state = self.perform_function_detection(
537 ['void functionName();'],
538 {'name': 'functionName',
539 'modifiers_and_return_type': 'void',
540 'function_name_start_position': (0, 5),
541 'parameter_start_position': (0, 17),
542 'parameter_end_position': (0, 19),
543 'body_start_position': (0, 19),
544 'end_position': (0, 20),
546 'is_declaration': True,
547 'parameter_list': ()})
549 # A function with one argument.
550 function_state = self.perform_function_detection(
551 ['void functionName(int);'],
552 {'name': 'functionName',
553 'modifiers_and_return_type': 'void',
554 'function_name_start_position': (0, 5),
555 'parameter_start_position': (0, 17),
556 'parameter_end_position': (0, 22),
557 'body_start_position': (0, 22),
558 'end_position': (0, 23),
560 'is_declaration': True,
562 ({'type': 'int', 'name': '', 'row': 0},)})
564 # A function with unsigned and short arguments
565 function_state = self.perform_function_detection(
566 ['void functionName(unsigned a, short b, long c, long long short unsigned int);'],
567 {'name': 'functionName',
568 'modifiers_and_return_type': 'void',
569 'function_name_start_position': (0, 5),
570 'parameter_start_position': (0, 17),
571 'parameter_end_position': (0, 76),
572 'body_start_position': (0, 76),
573 'end_position': (0, 77),
575 'is_declaration': True,
577 ({'type': 'unsigned', 'name': 'a', 'row': 0},
578 {'type': 'short', 'name': 'b', 'row': 0},
579 {'type': 'long', 'name': 'c', 'row': 0},
580 {'type': 'long long short unsigned int', 'name': '', 'row': 0})})
582 # Some parameter type with modifiers and no parameter names.
583 function_state = self.perform_function_detection(
584 ['virtual void determineARIADropEffects(Vector<String>*&, const unsigned long int*&, const MediaPlayer::Preload, Other<Other2, Other3<P1, P2> >, int);'],
585 {'name': 'determineARIADropEffects',
586 'modifiers_and_return_type': 'virtual void',
587 'parameter_start_position': (0, 37),
588 'function_name_start_position': (0, 13),
589 'parameter_end_position': (0, 147),
590 'body_start_position': (0, 147),
591 'end_position': (0, 148),
593 'is_declaration': True,
595 ({'type': 'Vector<String>*&', 'name': '', 'row': 0},
596 {'type': 'const unsigned long int*&', 'name': '', 'row': 0},
597 {'type': 'const MediaPlayer::Preload', 'name': '', 'row': 0},
598 {'type': 'Other<Other2, Other3<P1, P2> >', 'name': '', 'row': 0},
599 {'type': 'int', 'name': '', 'row': 0})})
601 # Try parsing a function with a very complex definition.
602 function_state = self.perform_function_detection(
603 ['#define MyMacro(a) a',
605 'AnotherTemplate<Class1, Class2> aFunctionName(PassRefPtr<MyClass> paramName,',
606 'const Other1Class& foo,',
607 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const * param = new ComplexTemplate<Class1, NestedTemplate<P1, P2> >(34, 42),',
608 'int* myCount = 0);'],
609 {'name': 'aFunctionName',
610 'modifiers_and_return_type': 'virtual AnotherTemplate<Class1, Class2>',
611 'function_name_start_position': (2, 32),
612 'parameter_start_position': (2, 45),
613 'parameter_end_position': (5, 17),
614 'body_start_position': (5, 17),
615 'end_position': (5, 18),
617 'is_declaration': True,
619 ({'type': 'PassRefPtr<MyClass>', 'name': 'paramName', 'row': 2},
620 {'type': 'const Other1Class&', 'name': 'foo', 'row': 3},
621 {'type': 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const *', 'name': 'param', 'row': 4},
622 {'type': 'int*', 'name': 'myCount', 'row': 5})},
626 class Cpp11StyleTest(CppStyleTestBase):
627 def test_rvaule_reference_at_end_of_line(self):
628 self.assert_lint('T&&', '')
630 def test_rvaule_reference_in_parameter_pack(self):
631 self.assert_lint('void requestCompleted(Arguments&&... arguments)', '')
633 class CppStyleTest(CppStyleTestBase):
635 def test_asm_lines_ignored(self):
637 '__asm mov [registration], eax',
640 # Test get line width.
641 def test_get_line_width(self):
642 self.assertEqual(0, cpp_style.get_line_width(''))
643 self.assertEqual(10, cpp_style.get_line_width(u'x' * 10))
644 self.assertEqual(16, cpp_style.get_line_width(u'都|道|府|県|支庁'))
646 def test_find_next_multi_line_comment_start(self):
647 self.assertEqual(1, cpp_style.find_next_multi_line_comment_start([''], 0))
649 lines = ['a', 'b', '/* c']
650 self.assertEqual(2, cpp_style.find_next_multi_line_comment_start(lines, 0))
652 lines = ['char a[] = "/*";'] # not recognized as comment.
653 self.assertEqual(1, cpp_style.find_next_multi_line_comment_start(lines, 0))
655 def test_find_next_multi_line_comment_end(self):
656 self.assertEqual(1, cpp_style.find_next_multi_line_comment_end([''], 0))
657 lines = ['a', 'b', ' c */']
658 self.assertEqual(2, cpp_style.find_next_multi_line_comment_end(lines, 0))
660 def test_remove_multi_line_comments_from_range(self):
661 lines = ['a', ' /* comment ', ' * still comment', ' comment */ ', 'b']
662 cpp_style.remove_multi_line_comments_from_range(lines, 1, 4)
663 self.assertEqual(['a', '// dummy', '// dummy', '// dummy', 'b'], lines)
665 def test_position(self):
666 position = cpp_style.Position(3, 4)
667 self.assert_positions_equal(position, (3, 4))
668 self.assertEqual(position.row, 3)
669 self.assertTrue(position > cpp_style.Position(position.row - 1, position.column + 1))
670 self.assertTrue(position > cpp_style.Position(position.row, position.column - 1))
671 self.assertTrue(position < cpp_style.Position(position.row, position.column + 1))
672 self.assertTrue(position < cpp_style.Position(position.row + 1, position.column - 1))
673 self.assertEqual(position.__str__(), '(3, 4)')
675 def test_rfind_in_lines(self):
676 not_found_position = cpp_style.Position(10, 11)
677 start_position = cpp_style.Position(2, 2)
678 lines = ['ab', 'ace', 'test']
679 self.assertEqual(not_found_position, cpp_style._rfind_in_lines('st', lines, start_position, not_found_position))
680 self.assertTrue(cpp_style.Position(1, 1) == cpp_style._rfind_in_lines('a', lines, start_position, not_found_position))
681 self.assertEqual(cpp_style.Position(2, 2), cpp_style._rfind_in_lines('(te|a)', lines, start_position, not_found_position))
683 def test_close_expression(self):
684 self.assertEqual(cpp_style.Position(1, -1), cpp_style.close_expression([')('], cpp_style.Position(0, 1)))
685 self.assertEqual(cpp_style.Position(1, -1), cpp_style.close_expression([') ()'], cpp_style.Position(0, 1)))
686 self.assertEqual(cpp_style.Position(0, 4), cpp_style.close_expression([')[)]'], cpp_style.Position(0, 1)))
687 self.assertEqual(cpp_style.Position(0, 5), cpp_style.close_expression(['}{}{}'], cpp_style.Position(0, 3)))
688 self.assertEqual(cpp_style.Position(1, 1), cpp_style.close_expression(['}{}{', '}'], cpp_style.Position(0, 3)))
689 self.assertEqual(cpp_style.Position(2, -1), cpp_style.close_expression(['][][', ' '], cpp_style.Position(0, 3)))
691 def test_spaces_at_end_of_line(self):
694 'Line ends in whitespace. Consider deleting these extra spaces.'
695 ' [whitespace/end_of_line] [4]')
697 # Test C-style cast cases.
698 def test_cstyle_cast(self):
701 'Using C-style cast. Use static_cast<int>(...) instead'
702 ' [readability/casting] [4]')
704 'int *a = (int *)DEFINED_VALUE;',
705 'Using C-style cast. Use reinterpret_cast<int *>(...) instead'
706 ' [readability/casting] [4]', 'foo.c')
708 'uint16 a = (uint16)1.0;',
709 'Using C-style cast. Use static_cast<uint16>(...) instead'
710 ' [readability/casting] [4]')
712 'int32 a = (int32)1.0;',
713 'Using C-style cast. Use static_cast<int32>(...) instead'
714 ' [readability/casting] [4]')
716 'uint64 a = (uint64)1.0;',
717 'Using C-style cast. Use static_cast<uint64>(...) instead'
718 ' [readability/casting] [4]')
720 # Test taking address of casts (runtime/casting)
721 def test_runtime_casting(self):
723 'int* x = &static_cast<int*>(foo);',
724 'Are you taking an address of a cast? '
725 'This is dangerous: could be a temp var. '
726 'Take the address before doing the cast, rather than after'
727 ' [runtime/casting] [4]')
730 'int* x = &dynamic_cast<int *>(foo);',
731 ['Are you taking an address of a cast? '
732 'This is dangerous: could be a temp var. '
733 'Take the address before doing the cast, rather than after'
734 ' [runtime/casting] [4]',
735 'Do not use dynamic_cast<>. If you need to cast within a class '
736 'hierarchy, use static_cast<> to upcast. Google doesn\'t support '
737 'RTTI. [runtime/rtti] [5]'])
740 'int* x = &reinterpret_cast<int *>(foo);',
741 'Are you taking an address of a cast? '
742 'This is dangerous: could be a temp var. '
743 'Take the address before doing the cast, rather than after'
744 ' [runtime/casting] [4]')
746 # It's OK to cast an address.
748 'int* x = reinterpret_cast<int *>(&foo);',
751 def test_runtime_selfinit(self):
752 self.assert_multi_line_lint(
754 Foo::Foo(Bar raa, Bel laa)
757 ['You seem to be initializing a member variable with itself.'
758 ' [runtime/init] [4]',
759 'You seem to be initializing a member variable with itself.'
760 ' [runtime/init] [4]'])
761 self.assert_multi_line_lint(
763 Foo::Foo(Bar raa, Bel laa)
767 self.assert_multi_line_lint(
772 , llaa_(laa_) { }''',
775 def test_runtime_rtti(self):
776 statement = 'int* x = dynamic_cast<int*>(&foo);'
778 'Do not use dynamic_cast<>. If you need to cast within a class '
779 'hierarchy, use static_cast<> to upcast. Google doesn\'t support '
780 'RTTI. [runtime/rtti] [5]')
781 # dynamic_cast is disallowed in most files.
782 self.assert_language_rules_check('foo.cpp', statement, error_message)
783 self.assert_language_rules_check('foo.h', statement, error_message)
785 # Test for static_cast readability.
786 def test_static_cast_readability(self):
788 'Text* x = static_cast<Text*>(foo);',
789 'Consider using toText helper function in WebCore/dom/Text.h '
790 'instead of static_cast<Text*>'
791 ' [readability/check] [4]')
793 # We cannot test this functionality because of difference of
794 # function definitions. Anyway, we may never enable this.
796 # # Test for unnamed arguments in a method.
797 # def test_check_for_unnamed_params(self):
798 # message = ('All parameters should be named in a function'
799 # ' [readability/function] [3]')
800 # self.assert_lint('virtual void A(int*) const;', message)
801 # self.assert_lint('virtual void B(void (*fn)(int*));', message)
802 # self.assert_lint('virtual void C(int*);', message)
803 # self.assert_lint('void *(*f)(void *) = x;', message)
804 # self.assert_lint('void Method(char*) {', message)
805 # self.assert_lint('void Method(char*);', message)
806 # self.assert_lint('void Method(char* /*x*/);', message)
807 # self.assert_lint('typedef void (*Method)(int32);', message)
808 # self.assert_lint('static void operator delete[](void*) throw();', message)
810 # self.assert_lint('virtual void D(int* p);', '')
811 # self.assert_lint('void operator delete(void* x) throw();', '')
812 # self.assert_lint('void Method(char* x)\n{', '')
813 # self.assert_lint('void Method(char* /*x*/)\n{', '')
814 # self.assert_lint('void Method(char* x);', '')
815 # self.assert_lint('typedef void (*Method)(int32 x);', '')
816 # self.assert_lint('static void operator delete[](void* x) throw();', '')
817 # self.assert_lint('static void operator delete[](void* /*x*/) throw();', '')
819 # # This one should technically warn, but doesn't because the function
820 # # pointer is confusing.
821 # self.assert_lint('virtual void E(void (*fn)(int* p));', '')
823 # Test deprecated casts such as int(d)
824 def test_deprecated_cast(self):
827 'Using deprecated casting style. '
828 'Use static_cast<int>(...) instead'
829 ' [readability/casting] [4]')
830 # Checks for false positives...
832 'int a = int(); // Constructor, o.k.',
834 self.assert_multi_line_lint(
837 : a(int()) { } // default Constructor, o.k.''',
840 'operator bool(); // Conversion operator, o.k.',
843 # The second parameter to a gMock method definition is a function signature
844 # that often looks like a bad cast but should not picked up by lint.
845 def test_mock_method(self):
847 'MOCK_METHOD0(method, int());',
850 'MOCK_CONST_METHOD1(method, float(string));',
853 'MOCK_CONST_METHOD2_T(method, double(float, float));',
856 # Test sizeof(type) cases.
857 def test_sizeof_type(self):
860 'Using sizeof(type). Use sizeof(varname) instead if possible'
861 ' [runtime/sizeof] [1]')
864 'Using sizeof(type). Use sizeof(varname) instead if possible'
865 ' [runtime/sizeof] [1]')
867 # Test typedef cases. There was a bug that cpp_style misidentified
868 # typedef for pointer to function as C-style cast and produced
869 # false-positive error messages.
870 def test_typedef_for_pointer_to_function(self):
872 'typedef void (*Func)(int x);',
875 'typedef void (*Func)(int *x);',
878 'typedef void Func(int x);',
881 'typedef void Func(int *x);',
884 def test_include_what_you_use_no_implementation_files(self):
885 code = 'std::vector<int> foo;'
886 self.assertEqual('Add #include <vector> for vector<>'
887 ' [build/include_what_you_use] [4]',
888 self.perform_include_what_you_use(code, 'foo.h'))
890 self.perform_include_what_you_use(code, 'foo.cpp'))
892 def test_include_what_you_use(self):
893 self.assert_include_what_you_use(
895 std::vector<int> foo;
898 self.assert_include_what_you_use(
900 std::pair<int,int> foo;
903 self.assert_include_what_you_use(
904 '''#include <multimap>
905 std::pair<int,int> foo;
908 self.assert_include_what_you_use(
909 '''#include <hash_map>
910 std::pair<int,int> foo;
913 self.assert_include_what_you_use(
914 '''#include <utility>
915 std::pair<int,int> foo;
918 self.assert_include_what_you_use(
920 DECLARE_string(foobar);
923 self.assert_include_what_you_use(
925 DEFINE_string(foobar, "", "");
928 self.assert_include_what_you_use(
930 std::pair<int,int> foo;
932 'Add #include <utility> for pair<>'
933 ' [build/include_what_you_use] [4]')
934 self.assert_include_what_you_use(
935 '''#include "base/foobar.h"
936 std::vector<int> foo;
938 'Add #include <vector> for vector<>'
939 ' [build/include_what_you_use] [4]')
940 self.assert_include_what_you_use(
944 'Add #include <set> for set<>'
945 ' [build/include_what_you_use] [4]')
946 self.assert_include_what_you_use(
947 '''#include "base/foobar.h"
948 hash_map<int, int> foobar;
950 'Add #include <hash_map> for hash_map<>'
951 ' [build/include_what_you_use] [4]')
952 self.assert_include_what_you_use(
953 '''#include "base/foobar.h"
954 bool foobar = std::less<int>(0,1);
956 'Add #include <functional> for less<>'
957 ' [build/include_what_you_use] [4]')
958 self.assert_include_what_you_use(
959 '''#include "base/foobar.h"
960 bool foobar = min<int>(0,1);
962 'Add #include <algorithm> for min [build/include_what_you_use] [4]')
963 self.assert_include_what_you_use(
964 'void a(const string &foobar);',
965 'Add #include <string> for string [build/include_what_you_use] [4]')
966 self.assert_include_what_you_use(
967 '''#include "base/foobar.h"
968 bool foobar = swap(0,1);
970 'Add #include <algorithm> for swap [build/include_what_you_use] [4]')
971 self.assert_include_what_you_use(
972 '''#include "base/foobar.h"
973 bool foobar = transform(a.begin(), a.end(), b.start(), Foo);
975 'Add #include <algorithm> for transform '
976 '[build/include_what_you_use] [4]')
977 self.assert_include_what_you_use(
978 '''#include "base/foobar.h"
979 bool foobar = min_element(a.begin(), a.end());
981 'Add #include <algorithm> for min_element '
982 '[build/include_what_you_use] [4]')
983 self.assert_include_what_you_use(
988 self.assert_include_what_you_use(
990 void a(const std::multimap<int,string> &foobar);
992 'Add #include <map> for multimap<>'
993 ' [build/include_what_you_use] [4]')
994 self.assert_include_what_you_use(
996 void a(const std::priority_queue<int> &foobar);
999 self.assert_include_what_you_use(
1000 '''#include "base/basictypes.h"
1001 #include "base/port.h"
1005 vector<string> hajoa;''', '')
1006 self.assert_include_what_you_use(
1007 '''#include <string>
1008 int i = numeric_limits<int>::max()
1010 'Add #include <limits> for numeric_limits<>'
1011 ' [build/include_what_you_use] [4]')
1012 self.assert_include_what_you_use(
1013 '''#include <limits>
1014 int i = numeric_limits<int>::max()
1018 # Test the UpdateIncludeState code path.
1019 mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"']
1020 message = self.perform_include_what_you_use(
1021 '#include "config.h"\n'
1022 '#include "blah/a.h"\n',
1023 filename='blah/a.cpp',
1024 io=MockIo(mock_header_contents))
1025 self.assertEqual(message, '')
1027 mock_header_contents = ['#include <set>']
1028 message = self.perform_include_what_you_use(
1029 '''#include "config.h"
1032 std::set<int> foo;''',
1033 filename='blah/a.cpp',
1034 io=MockIo(mock_header_contents))
1035 self.assertEqual(message, '')
1037 # If there's just a .cpp and the header can't be found then it's ok.
1038 message = self.perform_include_what_you_use(
1039 '''#include "config.h"
1042 std::set<int> foo;''',
1043 filename='blah/a.cpp')
1044 self.assertEqual(message, '')
1046 # Make sure we find the headers with relative paths.
1047 mock_header_contents = ['']
1048 message = self.perform_include_what_you_use(
1049 '''#include "config.h"
1052 std::set<int> foo;''' % (os.path.basename(os.getcwd()), os.path.sep),
1054 io=MockIo(mock_header_contents))
1055 self.assertEqual(message, 'Add #include <set> for set<> '
1056 '[build/include_what_you_use] [4]')
1058 def test_files_belong_to_same_module(self):
1059 f = cpp_style.files_belong_to_same_module
1060 self.assertEqual((True, ''), f('a.cpp', 'a.h'))
1061 self.assertEqual((True, ''), f('base/google.cpp', 'base/google.h'))
1062 self.assertEqual((True, ''), f('base/google_test.cpp', 'base/google.h'))
1063 self.assertEqual((True, ''),
1064 f('base/google_unittest.cpp', 'base/google.h'))
1065 self.assertEqual((True, ''),
1066 f('base/internal/google_unittest.cpp',
1067 'base/public/google.h'))
1068 self.assertEqual((True, 'xxx/yyy/'),
1069 f('xxx/yyy/base/internal/google_unittest.cpp',
1070 'base/public/google.h'))
1071 self.assertEqual((True, 'xxx/yyy/'),
1072 f('xxx/yyy/base/google_unittest.cpp',
1073 'base/public/google.h'))
1074 self.assertEqual((True, ''),
1075 f('base/google_unittest.cpp', 'base/google-inl.h'))
1076 self.assertEqual((True, '/home/build/google3/'),
1077 f('/home/build/google3/base/google.cpp', 'base/google.h'))
1079 self.assertEqual((False, ''),
1080 f('/home/build/google3/base/google.cpp', 'basu/google.h'))
1081 self.assertEqual((False, ''), f('a.cpp', 'b.h'))
1083 def test_cleanse_line(self):
1084 self.assertEqual('int foo = 0; ',
1085 cpp_style.cleanse_comments('int foo = 0; // danger!'))
1086 self.assertEqual('int o = 0;',
1087 cpp_style.cleanse_comments('int /* foo */ o = 0;'))
1088 self.assertEqual('foo(int a, int b);',
1089 cpp_style.cleanse_comments('foo(int a /* abc */, int b);'))
1090 self.assertEqual('f(a, b);',
1091 cpp_style.cleanse_comments('f(a, /* name */ b);'))
1092 self.assertEqual('f(a, b);',
1093 cpp_style.cleanse_comments('f(a /* name */, b);'))
1094 self.assertEqual('f(a, b);',
1095 cpp_style.cleanse_comments('f(a, /* name */b);'))
1097 def test_multi_line_comments(self):
1098 # missing explicit is bad
1099 self.assert_multi_line_lint(
1103 Foo(int f); // should cause a lint warning in code
1107 self.assert_multi_line_lint(
1109 /* int a = 0; multi-liner
1110 static const int b = 0;''',
1111 ['Could not find end of multi-line comment'
1112 ' [readability/multiline_comment] [5]',
1113 'Complex multi-line /*...*/-style comment found. '
1114 'Lint may give bogus warnings. Consider replacing these with '
1115 '//-style comments, with #if 0...#endif, or with more clearly '
1116 'structured multi-line comments. [readability/multiline_comment] [5]'])
1117 self.assert_multi_line_lint(r''' /* multi-line comment''',
1118 ['Could not find end of multi-line comment'
1119 ' [readability/multiline_comment] [5]',
1120 'Complex multi-line /*...*/-style comment found. '
1121 'Lint may give bogus warnings. Consider replacing these with '
1122 '//-style comments, with #if 0...#endif, or with more clearly '
1123 'structured multi-line comments. [readability/multiline_comment] [5]'])
1124 self.assert_multi_line_lint(r''' // /* comment, but not multi-line''', '')
1126 def test_multiline_strings(self):
1127 multiline_string_error_message = (
1128 'Multi-line string ("...") found. This lint script doesn\'t '
1129 'do well with such strings, and may give bogus warnings. They\'re '
1130 'ugly and unnecessary, and you should use concatenation instead".'
1131 ' [readability/multiline_string] [5]')
1133 file_path = 'mydir/foo.cpp'
1135 error_collector = ErrorCollector(self.assertTrue)
1136 self.process_file_data(file_path, 'cpp',
1137 ['const char* str = "This is a\\',
1138 ' multiline string.";'],
1142 error_collector.result_list().count(multiline_string_error_message))
1144 # Test non-explicit single-argument constructors
1145 def test_explicit_single_argument_constructors(self):
1146 # missing explicit is bad
1147 self.assert_multi_line_lint(
1152 'Single-argument constructors should be marked explicit.'
1153 ' [runtime/explicit] [5]')
1154 # missing explicit is bad, even with whitespace
1155 self.assert_multi_line_lint(
1160 ['Extra space before ( in function call [whitespace/parens] [4]',
1161 'Single-argument constructors should be marked explicit.'
1162 ' [runtime/explicit] [5]'])
1163 # missing explicit, with distracting comment, is still bad
1164 self.assert_multi_line_lint(
1167 Foo(int f); // simpler than Foo(blargh, blarg)
1169 'Single-argument constructors should be marked explicit.'
1170 ' [runtime/explicit] [5]')
1171 # missing explicit, with qualified classname
1172 self.assert_multi_line_lint(
1174 class Qualifier::AnotherOne::Foo {
1177 'Single-argument constructors should be marked explicit.'
1178 ' [runtime/explicit] [5]')
1179 # structs are caught as well.
1180 self.assert_multi_line_lint(
1185 'Single-argument constructors should be marked explicit.'
1186 ' [runtime/explicit] [5]')
1187 # Templatized classes are caught as well.
1188 self.assert_multi_line_lint(
1190 template<typename T> class Foo {
1193 'Single-argument constructors should be marked explicit.'
1194 ' [runtime/explicit] [5]')
1195 # proper style is okay
1196 self.assert_multi_line_lint(
1199 explicit Foo(int f);
1202 # two argument constructor is okay
1203 self.assert_multi_line_lint(
1209 # two argument constructor, across two lines, is okay
1210 self.assert_multi_line_lint(
1217 # non-constructor (but similar name), is okay
1218 self.assert_multi_line_lint(
1224 # constructor with void argument is okay
1225 self.assert_multi_line_lint(
1231 # single argument method is okay
1232 self.assert_multi_line_lint(
1238 # comments should be ignored
1239 self.assert_multi_line_lint(
1245 # single argument function following class definition is okay
1246 # (okay, it's not actually valid, but we don't want a false positive)
1247 self.assert_multi_line_lint(
1254 # single argument function is okay
1255 self.assert_multi_line_lint(
1256 '''static Foo(int f);''',
1258 # single argument copy constructor is okay.
1259 self.assert_multi_line_lint(
1265 self.assert_multi_line_lint(
1272 def test_slash_star_comment_on_single_line(self):
1273 self.assert_multi_line_lint(
1274 '''/* static */ Foo(int f);''',
1276 self.assert_multi_line_lint(
1277 '''/*/ static */ Foo(int f);''',
1279 self.assert_multi_line_lint(
1280 '''/*/ static Foo(int f);''',
1281 'Could not find end of multi-line comment'
1282 ' [readability/multiline_comment] [5]')
1283 self.assert_multi_line_lint(
1284 ''' /*/ static Foo(int f);''',
1285 'Could not find end of multi-line comment'
1286 ' [readability/multiline_comment] [5]')
1288 # Test suspicious usage of "if" like this:
1291 # } if (a == c) { // Should be "else if".
1292 # DoSomething(); // This gets called twice if a == b && a == c.
1294 def test_suspicious_usage_of_if(self):
1300 'Did you mean "else if"? If not, start a new line for "if".'
1301 ' [readability/braces] [4]')
1303 # Test suspicious usage of memset. Specifically, a 0
1304 # as the final argument is almost certainly an error.
1305 def test_suspicious_usage_of_memset(self):
1306 # Normal use is okay.
1308 ' memset(buf, 0, sizeof(buf))',
1311 # A 0 as the final argument is almost certainly an error.
1313 ' memset(buf, sizeof(buf), 0)',
1314 'Did you mean "memset(buf, 0, sizeof(buf))"?'
1315 ' [runtime/memset] [4]')
1317 ' memset(buf, xsize * ysize, 0)',
1318 'Did you mean "memset(buf, 0, xsize * ysize)"?'
1319 ' [runtime/memset] [4]')
1321 # There is legitimate test code that uses this form.
1322 # This is okay since the second argument is a literal.
1324 " memset(buf, 'y', 0)",
1327 ' memset(buf, 4, 0)',
1330 ' memset(buf, -1, 0)',
1333 ' memset(buf, 0xF1, 0)',
1336 ' memset(buf, 0xcd, 0)',
1339 def test_check_posix_threading(self):
1340 self.assert_lint('sctime_r()', '')
1341 self.assert_lint('strtok_r()', '')
1342 self.assert_lint(' strtok_r(foo, ba, r)', '')
1343 self.assert_lint('brand()', '')
1344 self.assert_lint('_rand()', '')
1345 self.assert_lint('.rand()', '')
1346 self.assert_lint('>rand()', '')
1347 self.assert_lint('rand()',
1348 'Consider using rand_r(...) instead of rand(...)'
1349 ' for improved thread safety.'
1350 ' [runtime/threadsafe_fn] [2]')
1351 self.assert_lint('strtok()',
1352 'Consider using strtok_r(...) '
1353 'instead of strtok(...)'
1354 ' for improved thread safety.'
1355 ' [runtime/threadsafe_fn] [2]')
1357 # Test potential format string bugs like printf(foo).
1358 def test_format_strings(self):
1359 self.assert_lint('printf("foo")', '')
1360 self.assert_lint('printf("foo: %s", foo)', '')
1361 self.assert_lint('DocidForPrintf(docid)', '') # Should not trigger.
1364 'Potential format string bug. Do printf("%s", foo) instead.'
1365 ' [runtime/printf] [4]')
1367 'printf(foo.c_str())',
1368 'Potential format string bug. '
1369 'Do printf("%s", foo.c_str()) instead.'
1370 ' [runtime/printf] [4]')
1372 'printf(foo->c_str())',
1373 'Potential format string bug. '
1374 'Do printf("%s", foo->c_str()) instead.'
1375 ' [runtime/printf] [4]')
1377 'StringPrintf(foo)',
1378 'Potential format string bug. Do StringPrintf("%s", foo) instead.'
1380 ' [runtime/printf] [4]')
1382 # Variable-length arrays are not permitted.
1383 def test_variable_length_array_detection(self):
1384 errmsg = ('Do not use variable-length arrays. Use an appropriately named '
1385 "('k' followed by CamelCase) compile-time constant for the size."
1386 ' [runtime/arrays] [1]')
1388 self.assert_lint('int a[any_old_variable];', errmsg)
1389 self.assert_lint('int doublesize[some_var * 2];', errmsg)
1390 self.assert_lint('int a[afunction()];', errmsg)
1391 self.assert_lint('int a[function(kMaxFooBars)];', errmsg)
1392 self.assert_lint('bool aList[items_->size()];', errmsg)
1393 self.assert_lint('namespace::Type buffer[len+1];', errmsg)
1395 self.assert_lint('int a[64];', '')
1396 self.assert_lint('int a[0xFF];', '')
1397 self.assert_lint('int first[256], second[256];', '')
1398 self.assert_lint('int arrayName[kCompileTimeConstant];', '')
1399 self.assert_lint('char buf[somenamespace::kBufSize];', '')
1400 self.assert_lint('int arrayName[ALL_CAPS];', '')
1401 self.assert_lint('AClass array1[foo::bar::ALL_CAPS];', '')
1402 self.assert_lint('int a[kMaxStrLen + 1];', '')
1403 self.assert_lint('int a[sizeof(foo)];', '')
1404 self.assert_lint('int a[sizeof(*foo)];', '')
1405 self.assert_lint('int a[sizeof foo];', '')
1406 self.assert_lint('int a[sizeof(struct Foo)];', '')
1407 self.assert_lint('int a[128 - sizeof(const bar)];', '')
1408 self.assert_lint('int a[(sizeof(foo) * 4)];', '')
1409 self.assert_lint('int a[(arraysize(fixed_size_array)/2) << 1];', 'Missing spaces around / [whitespace/operators] [3]')
1410 self.assert_lint('delete a[some_var];', '')
1411 self.assert_lint('return a[some_var];', '')
1414 def test_braces(self):
1415 # Braces shouldn't be followed by a ; unless they're defining a struct
1416 # or initializing an array
1417 self.assert_lint('int a[3] = { 1, 2, 3 };', '')
1423 # For single line, unmatched '}' with a ';' is ignored (not enough context)
1424 self.assert_multi_line_lint(
1430 self.assert_multi_line_lint(
1432 int a[2][3] = { { 1, 2 },
1435 self.assert_multi_line_lint(
1442 # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements
1443 def test_check_check(self):
1444 self.assert_lint('CHECK(x == 42)',
1445 'Consider using CHECK_EQ instead of CHECK(a == b)'
1446 ' [readability/check] [2]')
1447 self.assert_lint('CHECK(x != 42)',
1448 'Consider using CHECK_NE instead of CHECK(a != b)'
1449 ' [readability/check] [2]')
1450 self.assert_lint('CHECK(x >= 42)',
1451 'Consider using CHECK_GE instead of CHECK(a >= b)'
1452 ' [readability/check] [2]')
1453 self.assert_lint('CHECK(x > 42)',
1454 'Consider using CHECK_GT instead of CHECK(a > b)'
1455 ' [readability/check] [2]')
1456 self.assert_lint('CHECK(x <= 42)',
1457 'Consider using CHECK_LE instead of CHECK(a <= b)'
1458 ' [readability/check] [2]')
1459 self.assert_lint('CHECK(x < 42)',
1460 'Consider using CHECK_LT instead of CHECK(a < b)'
1461 ' [readability/check] [2]')
1463 self.assert_lint('DCHECK(x == 42)',
1464 'Consider using DCHECK_EQ instead of DCHECK(a == b)'
1465 ' [readability/check] [2]')
1466 self.assert_lint('DCHECK(x != 42)',
1467 'Consider using DCHECK_NE instead of DCHECK(a != b)'
1468 ' [readability/check] [2]')
1469 self.assert_lint('DCHECK(x >= 42)',
1470 'Consider using DCHECK_GE instead of DCHECK(a >= b)'
1471 ' [readability/check] [2]')
1472 self.assert_lint('DCHECK(x > 42)',
1473 'Consider using DCHECK_GT instead of DCHECK(a > b)'
1474 ' [readability/check] [2]')
1475 self.assert_lint('DCHECK(x <= 42)',
1476 'Consider using DCHECK_LE instead of DCHECK(a <= b)'
1477 ' [readability/check] [2]')
1478 self.assert_lint('DCHECK(x < 42)',
1479 'Consider using DCHECK_LT instead of DCHECK(a < b)'
1480 ' [readability/check] [2]')
1483 'EXPECT_TRUE("42" == x)',
1484 'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)'
1485 ' [readability/check] [2]')
1487 'EXPECT_TRUE("42" != x)',
1488 'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)'
1489 ' [readability/check] [2]')
1491 'EXPECT_TRUE(+42 >= x)',
1492 'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)'
1493 ' [readability/check] [2]')
1495 'EXPECT_TRUE_M(-42 > x)',
1496 'Consider using EXPECT_GT_M instead of EXPECT_TRUE_M(a > b)'
1497 ' [readability/check] [2]')
1499 'EXPECT_TRUE_M(42U <= x)',
1500 'Consider using EXPECT_LE_M instead of EXPECT_TRUE_M(a <= b)'
1501 ' [readability/check] [2]')
1503 'EXPECT_TRUE_M(42L < x)',
1504 'Consider using EXPECT_LT_M instead of EXPECT_TRUE_M(a < b)'
1505 ' [readability/check] [2]')
1508 'EXPECT_FALSE(x == 42)',
1509 'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)'
1510 ' [readability/check] [2]')
1512 'EXPECT_FALSE(x != 42)',
1513 'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)'
1514 ' [readability/check] [2]')
1516 'EXPECT_FALSE(x >= 42)',
1517 'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)'
1518 ' [readability/check] [2]')
1520 'ASSERT_FALSE(x > 42)',
1521 'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)'
1522 ' [readability/check] [2]')
1524 'ASSERT_FALSE(x <= 42)',
1525 'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)'
1526 ' [readability/check] [2]')
1528 'ASSERT_FALSE_M(x < 42)',
1529 'Consider using ASSERT_GE_M instead of ASSERT_FALSE_M(a < b)'
1530 ' [readability/check] [2]')
1532 self.assert_lint('CHECK(some_iterator == obj.end())', '')
1533 self.assert_lint('EXPECT_TRUE(some_iterator == obj.end())', '')
1534 self.assert_lint('EXPECT_FALSE(some_iterator == obj.end())', '')
1536 self.assert_lint('CHECK(CreateTestFile(dir, (1 << 20)));', '')
1537 self.assert_lint('CHECK(CreateTestFile(dir, (1 >> 20)));', '')
1539 self.assert_lint('CHECK(x<42)',
1540 ['Missing spaces around <'
1541 ' [whitespace/operators] [3]',
1542 'Consider using CHECK_LT instead of CHECK(a < b)'
1543 ' [readability/check] [2]'])
1544 self.assert_lint('CHECK(x>42)',
1545 'Consider using CHECK_GT instead of CHECK(a > b)'
1546 ' [readability/check] [2]')
1549 ' EXPECT_TRUE(42 < x) // Random comment.',
1550 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1551 ' [readability/check] [2]')
1553 'EXPECT_TRUE( 42 < x )',
1554 ['Extra space after ( in function call'
1555 ' [whitespace/parens] [4]',
1556 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1557 ' [readability/check] [2]'])
1559 'CHECK("foo" == "foo")',
1560 'Consider using CHECK_EQ instead of CHECK(a == b)'
1561 ' [readability/check] [2]')
1563 self.assert_lint('CHECK_EQ("foo", "foo")', '')
1565 def test_brace_at_begin_of_line(self):
1566 self.assert_lint('{',
1567 'This { should be at the end of the previous line'
1568 ' [whitespace/braces] [4]')
1569 self.assert_multi_line_lint(
1574 self.assert_multi_line_lint(
1577 self.assert_multi_line_lint(
1578 ' MACRO1(macroArg) {',
1580 self.assert_multi_line_lint(
1581 'ACCESSOR_GETTER(MessageEventPorts) {',
1582 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
1583 self.assert_multi_line_lint(
1585 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
1586 self.assert_multi_line_lint(
1587 'int foo() const {',
1588 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
1589 self.assert_multi_line_lint(
1590 'int foo() const override {',
1591 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
1592 self.assert_multi_line_lint(
1593 'int foo() override {',
1594 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
1595 self.assert_multi_line_lint(
1600 self.assert_multi_line_lint(
1601 'int foo() override\n'
1605 self.assert_multi_line_lint(
1608 ' && condition3) {\n'
1611 self.assert_multi_line_lint(
1612 'auto Foo:bar() -> Baz\n'
1617 def test_mismatching_spaces_in_parens(self):
1618 self.assert_lint('if (foo ) {', 'Extra space before ) in if'
1619 ' [whitespace/parens] [5]')
1620 self.assert_lint('switch ( foo) {', 'Extra space after ( in switch'
1621 ' [whitespace/parens] [5]')
1622 self.assert_lint('for (foo; ba; bar ) {', 'Extra space before ) in for'
1623 ' [whitespace/parens] [5]')
1624 self.assert_lint('for ((foo); (ba); (bar) ) {', 'Extra space before ) in for'
1625 ' [whitespace/parens] [5]')
1626 self.assert_lint('for (; foo; bar) {', '')
1627 self.assert_lint('for (; (foo); (bar)) {', '')
1628 self.assert_lint('for ( ; foo; bar) {', '')
1629 self.assert_lint('for ( ; (foo); (bar)) {', '')
1630 self.assert_lint('for ( ; foo; bar ) {', 'Extra space before ) in for'
1631 ' [whitespace/parens] [5]')
1632 self.assert_lint('for ( ; (foo); (bar) ) {', 'Extra space before ) in for'
1633 ' [whitespace/parens] [5]')
1634 self.assert_lint('for (foo; bar; ) {', '')
1635 self.assert_lint('for ((foo); (bar); ) {', '')
1636 self.assert_lint('while ( foo) {', 'Extra space after ( in while'
1637 ' [whitespace/parens] [5]')
1639 def test_spacing_for_fncall(self):
1640 self.assert_lint('if (foo) {', '')
1641 self.assert_lint('for (foo;bar;baz) {', '')
1642 self.assert_lint('while (foo) {', '')
1643 self.assert_lint('switch (foo) {', '')
1644 self.assert_lint('new (RenderArena()) RenderInline(document())', '')
1645 self.assert_lint('foo( bar)', 'Extra space after ( in function call'
1646 ' [whitespace/parens] [4]')
1647 self.assert_lint('foobar( \\', '')
1648 self.assert_lint('foobar( \\', '')
1649 self.assert_lint('( a + b)', 'Extra space after ('
1650 ' [whitespace/parens] [2]')
1651 self.assert_lint('((a+b))', '')
1652 self.assert_lint('foo (foo)', 'Extra space before ( in function call'
1653 ' [whitespace/parens] [4]')
1654 self.assert_lint('@property (readonly) NSUInteger count;', '')
1655 self.assert_lint('#elif (foo(bar))', '')
1656 self.assert_lint('#elif (foo(bar) && foo(baz))', '')
1657 self.assert_lint('typedef foo (*foo)(foo)', '')
1658 self.assert_lint('typedef foo (*foo12bar_)(foo)', '')
1659 self.assert_lint('typedef foo (Foo::*bar)(foo)', '')
1660 self.assert_lint('foo (Foo::*bar)(',
1661 'Extra space before ( in function call'
1662 ' [whitespace/parens] [4]')
1663 self.assert_lint('typedef foo (Foo::*bar)(', '')
1664 self.assert_lint('(foo)(bar)', '')
1665 self.assert_lint('Foo (*foo)(bar)', '')
1666 self.assert_lint('Foo (*foo)(Bar bar,', '')
1667 self.assert_lint('char (*p)[sizeof(foo)] = &foo', '')
1668 self.assert_lint('char (&ref)[sizeof(foo)] = &foo', '')
1669 self.assert_lint('const char32 (*table[])[6];', '')
1670 self.assert_lint('@interface Foo (Category)', '')
1671 self.assert_lint('@interface Foo ()', '')
1672 self.assert_lint('@implementation Foo (Category)', '')
1673 self.assert_lint('@implementation Foo ()', '')
1675 def test_spacing_before_braces(self):
1676 self.assert_lint('if (foo){', 'Missing space before {'
1677 ' [whitespace/braces] [5]')
1678 self.assert_lint('for{', 'Missing space before {'
1679 ' [whitespace/braces] [5]')
1680 self.assert_lint('for {', '')
1681 self.assert_lint('EXPECT_DEBUG_DEATH({', '')
1683 def test_spacing_between_braces(self):
1684 self.assert_lint(' { }', '')
1685 self.assert_lint(' {}', 'Missing space inside { }. [whitespace/braces] [5]')
1686 self.assert_lint(' { }', 'Too many spaces inside { }. [whitespace/braces] [5]')
1688 def test_spacing_around_else(self):
1689 self.assert_lint('}else {', 'Missing space before else'
1690 ' [whitespace/braces] [5]')
1691 self.assert_lint('} else{', 'Missing space before {'
1692 ' [whitespace/braces] [5]')
1693 self.assert_lint('} else {', '')
1694 self.assert_lint('} else if', '')
1696 def test_spacing_for_binary_ops(self):
1697 self.assert_lint('if (foo<=bar) {', 'Missing spaces around <='
1698 ' [whitespace/operators] [3]')
1699 self.assert_lint('if (foo<bar) {', 'Missing spaces around <'
1700 ' [whitespace/operators] [3]')
1701 self.assert_lint('if (foo<bar->baz) {', 'Missing spaces around <'
1702 ' [whitespace/operators] [3]')
1703 self.assert_lint('if (foo<bar->bar) {', 'Missing spaces around <'
1704 ' [whitespace/operators] [3]')
1705 self.assert_lint('typedef hash_map<Foo, Bar', 'Missing spaces around <'
1706 ' [whitespace/operators] [3]')
1707 self.assert_lint('typedef hash_map<FoooooType, BaaaaarType,', '')
1708 self.assert_lint('a<Foo> t+=b;', 'Missing spaces around +='
1709 ' [whitespace/operators] [3]')
1710 self.assert_lint('a<Foo> t-=b;', 'Missing spaces around -='
1711 ' [whitespace/operators] [3]')
1712 self.assert_lint('a<Foo*> t*=b;', 'Missing spaces around *='
1713 ' [whitespace/operators] [3]')
1714 self.assert_lint('a<Foo*> t/=b;', 'Missing spaces around /='
1715 ' [whitespace/operators] [3]')
1716 self.assert_lint('a<Foo*> t|=b;', 'Missing spaces around |='
1717 ' [whitespace/operators] [3]')
1718 self.assert_lint('a<Foo*> t&=b;', 'Missing spaces around &='
1719 ' [whitespace/operators] [3]')
1720 self.assert_lint('a<Foo*> t<<=b;', 'Missing spaces around <<='
1721 ' [whitespace/operators] [3]')
1722 self.assert_lint('a<Foo*> t>>=b;', 'Missing spaces around >>='
1723 ' [whitespace/operators] [3]')
1724 self.assert_lint('a<Foo*> t>>=&b|c;', 'Missing spaces around >>='
1725 ' [whitespace/operators] [3]')
1726 self.assert_lint('a<Foo*> t<<=*b/c;', 'Missing spaces around <<='
1727 ' [whitespace/operators] [3]')
1728 self.assert_lint('a<Foo> t -= b;', '')
1729 self.assert_lint('a<Foo> t += b;', '')
1730 self.assert_lint('a<Foo*> t *= b;', '')
1731 self.assert_lint('a<Foo*> t /= b;', '')
1732 self.assert_lint('a<Foo*> t |= b;', '')
1733 self.assert_lint('a<Foo*> t &= b;', '')
1734 self.assert_lint('a<Foo*> t <<= b;', '')
1735 self.assert_lint('a<Foo*> t >>= b;', '')
1736 self.assert_lint('a<Foo*> t >>= &b|c;', 'Missing spaces around |'
1737 ' [whitespace/operators] [3]')
1738 self.assert_lint('a<Foo*> t <<= *b/c;', 'Missing spaces around /'
1739 ' [whitespace/operators] [3]')
1740 self.assert_lint('a<Foo*> t <<= b/c; //Test', [
1741 'Should have a space between // and comment '
1742 '[whitespace/comments] [4]', 'Missing'
1743 ' spaces around / [whitespace/operators] [3]'])
1744 self.assert_lint('a<Foo*> t <<= b||c; //Test', ['One space before end'
1745 ' of line comments [whitespace/comments] [5]',
1746 'Should have a space between // and comment '
1747 '[whitespace/comments] [4]',
1748 'Missing spaces around || [whitespace/operators] [3]'])
1749 self.assert_lint('a<Foo*> t <<= b||c; // Test', 'Missing spaces around'
1750 ' || [whitespace/operators] [3]')
1751 self.assert_lint('a<Foo*> t <<= b||&c; // Test', 'Missing spaces around'
1752 ' || [whitespace/operators] [3]')
1753 self.assert_lint('a<Foo*> t <<= b||*c; // Test', 'Missing spaces around'
1754 ' || [whitespace/operators] [3]')
1755 self.assert_lint('a<Foo*> t <<= b && *c; // Test', '')
1756 self.assert_lint('a<Foo*> t <<= b && &c; // Test', '')
1757 self.assert_lint('a<Foo*> t <<= b || &c; /*Test', 'Complex multi-line '
1758 '/*...*/-style comment found. Lint may give bogus '
1759 'warnings. Consider replacing these with //-style'
1760 ' comments, with #if 0...#endif, or with more clearly'
1761 ' structured multi-line comments. [readability/multiline_comment] [5]')
1762 self.assert_lint('a<Foo&> t <<= &b | &c;', '')
1763 self.assert_lint('a<Foo*> t <<= &b & &c; // Test', '')
1764 self.assert_lint('a<Foo*> t <<= *b / &c; // Test', '')
1765 self.assert_lint('if (a=b == 1)', 'Missing spaces around = [whitespace/operators] [4]')
1766 self.assert_lint('if (a = b == 1)', '')
1767 self.assert_multi_line_lint('#include <sys/io.h>\n', '')
1768 self.assert_multi_line_lint('#import <foo/bar.h>\n', '')
1769 self.assert_multi_line_lint('#if __has_include(<ApplicationServices/ApplicationServicesPriv.h>)\n', '')
1770 self.assert_lint('Foo&& a = bar();', '')
1772 def test_operator_methods(self):
1773 self.assert_lint('String operator+(const String&, const String&);', '')
1774 self.assert_lint('String operator/(const String&, const String&);', '')
1775 self.assert_lint('bool operator==(const String&, const String&);', '')
1776 self.assert_lint('String& operator-=(const String&, const String&);', '')
1777 self.assert_lint('String& operator+=(const String&, const String&);', '')
1778 self.assert_lint('String& operator*=(const String&, const String&);', '')
1779 self.assert_lint('String& operator%=(const String&, const String&);', '')
1780 self.assert_lint('String& operator&=(const String&, const String&);', '')
1781 self.assert_lint('String& operator<<=(const String&, const String&);', '')
1782 self.assert_lint('String& operator>>=(const String&, const String&);', '')
1783 self.assert_lint('String& operator|=(const String&, const String&);', '')
1784 self.assert_lint('String& operator^=(const String&, const String&);', '')
1786 def test_spacing_before_last_semicolon(self):
1787 self.assert_lint('call_function() ;',
1788 'Extra space before last semicolon. If this should be an '
1789 'empty statement, use { } instead.'
1790 ' [whitespace/semicolon] [5]')
1791 self.assert_lint('while (true) ;',
1792 'Extra space before last semicolon. If this should be an '
1793 'empty statement, use { } instead.'
1794 ' [whitespace/semicolon] [5]')
1795 self.assert_lint('default:;',
1796 'Semicolon defining empty statement. Use { } instead.'
1797 ' [whitespace/semicolon] [5]')
1798 self.assert_lint(' ;',
1799 'Line contains only semicolon. If this should be an empty '
1800 'statement, use { } instead.'
1801 ' [whitespace/semicolon] [5]')
1802 self.assert_lint('for (int i = 0; ;', '')
1804 # Static or global STL strings.
1805 def test_static_or_global_stlstrings(self):
1806 self.assert_lint('string foo;',
1807 'For a static/global string constant, use a C style '
1808 'string instead: "char foo[]".'
1809 ' [runtime/string] [4]')
1810 self.assert_lint('string kFoo = "hello"; // English',
1811 'For a static/global string constant, use a C style '
1812 'string instead: "char kFoo[]".'
1813 ' [runtime/string] [4]')
1814 self.assert_lint('static string foo;',
1815 'For a static/global string constant, use a C style '
1816 'string instead: "static char foo[]".'
1817 ' [runtime/string] [4]')
1818 self.assert_lint('static const string foo;',
1819 'For a static/global string constant, use a C style '
1820 'string instead: "static const char foo[]".'
1821 ' [runtime/string] [4]')
1822 self.assert_lint('string Foo::bar;',
1823 'For a static/global string constant, use a C style '
1824 'string instead: "char Foo::bar[]".'
1825 ' [runtime/string] [4]')
1827 self.assert_lint('string foo("foobar");',
1828 'For a static/global string constant, use a C style '
1829 'string instead: "char foo[]".'
1830 ' [runtime/string] [4]')
1831 # Should not catch local or member variables.
1832 self.assert_lint(' string foo', '')
1833 # Should not catch functions.
1834 self.assert_lint('string EmptyString() { return ""; }', '')
1835 self.assert_lint('string EmptyString () { return ""; }', '')
1836 self.assert_lint('string VeryLongNameFunctionSometimesEndsWith(\n'
1837 ' VeryLongNameType veryLongNameVariable) { }', '')
1838 self.assert_lint('template<>\n'
1839 'string FunctionTemplateSpecialization<SomeType>(\n'
1840 ' int x) { return ""; }', '')
1841 self.assert_lint('template<>\n'
1842 'string FunctionTemplateSpecialization<vector<A::B>* >(\n'
1843 ' int x) { return ""; }', '')
1845 # should not catch methods of template classes.
1846 self.assert_lint('string Class<Type>::Method() const\n'
1850 self.assert_lint('string Class<Type>::Method(\n'
1856 def test_no_spaces_in_function_calls(self):
1857 self.assert_lint('TellStory(1, 3);',
1859 self.assert_lint('TellStory(1, 3 );',
1860 'Extra space before )'
1861 ' [whitespace/parens] [2]')
1862 self.assert_lint('TellStory(1 /* wolf */, 3 /* pigs */);',
1864 self.assert_multi_line_lint('#endif\n );',
1867 def test_one_spaces_between_code_and_comments(self):
1868 self.assert_lint('} // namespace foo',
1870 self.assert_lint('}// namespace foo',
1871 'One space before end of line comments'
1872 ' [whitespace/comments] [5]')
1873 self.assert_lint('printf("foo"); // Outside quotes.',
1875 self.assert_lint('int i = 0; // Having one space is fine.','')
1876 self.assert_lint('int i = 0; // Having two spaces is bad.',
1877 'One space before end of line comments'
1878 ' [whitespace/comments] [5]')
1879 self.assert_lint('int i = 0; // Having three spaces is bad.',
1880 'One space before end of line comments'
1881 ' [whitespace/comments] [5]')
1882 self.assert_lint('// Top level comment', '')
1883 self.assert_lint(' // Line starts with four spaces.', '')
1884 self.assert_lint('foo();\n'
1885 '{ // A scope is opening.', '')
1886 self.assert_lint(' foo();\n'
1887 ' { // An indented scope is opening.', '')
1888 self.assert_lint('if (foo) { // not a pure scope',
1890 self.assert_lint('printf("// In quotes.")', '')
1891 self.assert_lint('printf("\\"%s // In quotes.")', '')
1892 self.assert_lint('printf("%s", "// In quotes.")', '')
1894 def test_one_spaces_after_punctuation_in_comments(self):
1895 self.assert_lint('int a; // This is a sentence.',
1897 self.assert_lint('int a; // This is a sentence. ',
1898 'Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4]')
1899 self.assert_lint('int a; // This is a sentence. This is a another sentence.',
1901 self.assert_lint('int a; // This is a sentence. This is a another sentence.',
1902 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1903 self.assert_lint('int a; // This is a sentence! This is a another sentence.',
1904 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1905 self.assert_lint('int a; // Why did I write this? This is a another sentence.',
1906 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1907 self.assert_lint('int a; // Elementary, my dear.',
1908 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1909 self.assert_lint('int a; // The following should be clear: Is it?',
1910 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1911 self.assert_lint('int a; // Look at the follow semicolon; I hope this gives an error.',
1912 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1914 def test_space_after_comment_marker(self):
1915 self.assert_lint('//', '')
1916 self.assert_lint('//x', 'Should have a space between // and comment'
1917 ' [whitespace/comments] [4]')
1918 self.assert_lint('// x', '')
1919 self.assert_lint('//----', '')
1920 self.assert_lint('//====', '')
1921 self.assert_lint('//////', '')
1922 self.assert_lint('////// x', '')
1923 self.assert_lint('/// x', '')
1924 self.assert_lint('////x', 'Should have a space between // and comment'
1925 ' [whitespace/comments] [4]')
1927 def test_newline_at_eof(self):
1928 def do_test(self, data, is_missing_eof):
1929 error_collector = ErrorCollector(self.assertTrue)
1930 self.process_file_data('foo.cpp', 'cpp', data.split('\n'),
1932 # The warning appears only once.
1934 int(is_missing_eof),
1935 error_collector.results().count(
1936 'Could not find a newline character at the end of the file.'
1937 ' [whitespace/ending_newline] [5]'))
1939 do_test(self, '// Newline\n// at EOF\n', False)
1940 do_test(self, '// Newline2\n\n// at EOF\n', False)
1941 do_test(self, '// No newline\n// at EOF', True)
1942 do_test(self, '// No newline2\n\n// at EOF', True)
1944 def test_extra_newlines_at_eof(self):
1945 def do_test(self, data, too_many_newlines):
1946 error_collector = ErrorCollector(self.assertTrue)
1947 self.process_file_data('foo.cpp', 'cpp', data.split('\n'),
1949 # The warning appears only once.
1951 int(too_many_newlines),
1952 error_collector.results().count(
1953 'There was more than one newline at the end of the file.'
1954 ' [whitespace/ending_newline] [5]'))
1956 do_test(self, '// No Newline\n// at EOF', False)
1957 do_test(self, '// No Newline2\n\n// at EOF', False)
1958 do_test(self, '// One Newline\n// at EOF\n', False)
1959 do_test(self, '// One Newline2\n\n// at EOF\n', False)
1960 do_test(self, '// Two Newlines\n// at EOF\n\n', True)
1961 do_test(self, '// Three Newlines\n// at EOF\n\n\n', True)
1963 def test_invalid_utf8(self):
1964 def do_test(self, raw_bytes, has_invalid_utf8):
1965 error_collector = ErrorCollector(self.assertTrue)
1966 self.process_file_data('foo.cpp', 'cpp',
1967 unicode(raw_bytes, 'utf8', 'replace').split('\n'),
1969 # The warning appears only once.
1971 int(has_invalid_utf8),
1972 error_collector.results().count(
1973 'Line contains invalid UTF-8'
1974 ' (or Unicode replacement character).'
1975 ' [readability/utf8] [5]'))
1977 do_test(self, 'Hello world\n', False)
1978 do_test(self, '\xe9\x8e\xbd\n', False)
1979 do_test(self, '\xe9x\x8e\xbd\n', True)
1980 # This is the encoding of the replacement character itself (which
1981 # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')).
1982 do_test(self, '\xef\xbf\xbd\n', True)
1984 def test_is_blank_line(self):
1985 self.assertTrue(cpp_style.is_blank_line(''))
1986 self.assertTrue(cpp_style.is_blank_line(' '))
1987 self.assertTrue(cpp_style.is_blank_line(' \t\r\n'))
1988 self.assertTrue(not cpp_style.is_blank_line('int a;'))
1989 self.assertTrue(not cpp_style.is_blank_line('{'))
1991 def test_blank_lines_check(self):
1992 self.assert_blank_lines_check(['{\n', '\n', '\n', '}\n'], 1, 1)
1993 self.assert_blank_lines_check([' if (foo) {\n', '\n', ' }\n'], 1, 1)
1994 self.assert_blank_lines_check(
1995 ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0)
1996 self.assert_blank_lines_check(['\n', 'run("{");\n', '\n'], 0, 0)
1997 self.assert_blank_lines_check(['\n', ' if (foo) { return 0; }\n', '\n'], 0, 0)
1999 def test_allow_blank_line_before_closing_namespace(self):
2000 error_collector = ErrorCollector(self.assertTrue)
2001 self.process_file_data('foo.cpp', 'cpp',
2002 ['namespace {', '', '} // namespace'],
2004 self.assertEqual(0, error_collector.results().count(
2005 'Blank line at the end of a code block. Is this needed?'
2006 ' [whitespace/blank_line] [3]'))
2008 def test_allow_blank_line_before_if_else_chain(self):
2009 error_collector = ErrorCollector(self.assertTrue)
2010 self.process_file_data('foo.cpp', 'cpp',
2013 '} else if (piyo) {',
2015 '} else if (piyopiyo) {',
2016 ' hoge = true;', # No warning
2018 '', # Warning on this line
2021 self.assertEqual(1, error_collector.results().count(
2022 'Blank line at the end of a code block. Is this needed?'
2023 ' [whitespace/blank_line] [3]'))
2025 def test_else_on_same_line_as_closing_braces(self):
2026 error_collector = ErrorCollector(self.assertTrue)
2027 self.process_file_data('foo.cpp', 'cpp',
2031 ' else {' # Warning on this line
2035 self.assertEqual(1, error_collector.results().count(
2036 'An else should appear on the same line as the preceding }'
2037 ' [whitespace/newline] [4]'))
2039 def test_else_clause_not_on_same_line_as_else(self):
2040 self.assert_lint(' else DoSomethingElse();',
2041 'Else clause should never be on same line as else '
2042 '(use 2 lines) [whitespace/newline] [4]')
2043 self.assert_lint(' else ifDoSomethingElse();',
2044 'Else clause should never be on same line as else '
2045 '(use 2 lines) [whitespace/newline] [4]')
2046 self.assert_lint(' else if (blah) {', '')
2047 self.assert_lint(' variable_ends_in_else = true;', '')
2049 def test_comma(self):
2050 self.assert_lint('a = f(1,2);',
2051 'Missing space after , [whitespace/comma] [3]')
2052 self.assert_lint('int tmp=a,a=b,b=tmp;',
2053 ['Missing spaces around = [whitespace/operators] [4]',
2054 'Missing space after , [whitespace/comma] [3]'])
2055 self.assert_lint('f(a, /* name */ b);', '')
2056 self.assert_lint('f(a, /* name */b);', '')
2058 def test_declaration(self):
2059 self.assert_lint('int a;', '')
2060 self.assert_lint('int a;', 'Extra space between int and a [whitespace/declaration] [3]')
2061 self.assert_lint('int* a;', 'Extra space between int* and a [whitespace/declaration] [3]')
2062 self.assert_lint('else if { }', '')
2063 self.assert_lint('else if { }', 'Extra space between else and if [whitespace/declaration] [3]')
2065 def test_pointer_reference_marker_location(self):
2066 self.assert_lint('int* b;', '', 'foo.cpp')
2067 self.assert_lint('int *b;',
2068 'Declaration has space between type name and * in int *b [whitespace/declaration] [3]',
2070 self.assert_lint('int * b;',
2071 'Declaration has space between type name and * in int * b [whitespace/declaration] [3]',
2073 self.assert_lint('return *b;', '', 'foo.cpp')
2074 self.assert_lint('return a * b;', '', 'foo.cpp')
2075 self.assert_lint('delete *b;', '', 'foo.cpp')
2076 self.assert_lint('int *b;', '', 'foo.c')
2077 self.assert_lint('int* b;',
2078 'Declaration has space between * and variable name in int* b [whitespace/declaration] [3]',
2080 self.assert_lint('int& b;', '', 'foo.cpp')
2081 self.assert_lint('int &b;',
2082 'Declaration has space between type name and & in int &b [whitespace/declaration] [3]',
2084 self.assert_lint('return &b;', '', 'foo.cpp')
2085 self.assert_lint('*foo = bar;', '', 'foo.cpp')
2087 def test_indent(self):
2088 self.assert_lint('static int noindent;', '')
2089 self.assert_lint(' int fourSpaceIndent;', '')
2090 self.assert_lint(' int oneSpaceIndent;',
2091 'Weird number of spaces at line-start. '
2092 'Are you using a 4-space indent? [whitespace/indent] [3]')
2093 self.assert_lint(' int threeSpaceIndent;',
2094 'Weird number of spaces at line-start. '
2095 'Are you using a 4-space indent? [whitespace/indent] [3]')
2096 self.assert_lint(' char* oneSpaceIndent = "public:";',
2097 'Weird number of spaces at line-start. '
2098 'Are you using a 4-space indent? [whitespace/indent] [3]')
2099 self.assert_lint(' public:',
2100 'Weird number of spaces at line-start. '
2101 'Are you using a 4-space indent? [whitespace/indent] [3]')
2102 self.assert_lint(' public:',
2103 'Weird number of spaces at line-start. '
2104 'Are you using a 4-space indent? [whitespace/indent] [3]')
2105 self.assert_lint(' public:',
2106 'Weird number of spaces at line-start. '
2107 'Are you using a 4-space indent? [whitespace/indent] [3]')
2108 self.assert_multi_line_lint(
2114 '#if ENABLED_BETZ\n'
2121 def test_not_alabel(self):
2122 self.assert_lint('MyVeryLongNamespace::MyVeryLongClassName::', '')
2125 self.assert_lint('\tint a;',
2126 'Tab found; better to use spaces [whitespace/tab] [1]')
2127 self.assert_lint('int a = 5;\t// set a to 5',
2128 'Tab found; better to use spaces [whitespace/tab] [1]')
2130 def test_unnamed_namespaces_in_headers(self):
2131 self.assert_language_rules_check(
2132 'foo.h', 'namespace {',
2133 'Do not use unnamed namespaces in header files. See'
2134 ' http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
2135 ' for more information. [build/namespaces] [4]')
2136 # namespace registration macros are OK.
2137 self.assert_language_rules_check('foo.h', 'namespace { \\', '')
2138 # named namespaces are OK.
2139 self.assert_language_rules_check('foo.h', 'namespace foo {', '')
2140 self.assert_language_rules_check('foo.h', 'namespace foonamespace {', '')
2141 self.assert_language_rules_check('foo.cpp', 'namespace {', '')
2142 self.assert_language_rules_check('foo.cpp', 'namespace foo {', '')
2144 def test_build_class(self):
2145 # Test that the linter can parse to the end of class definitions,
2146 # and that it will report when it can't.
2147 # Use multi-line linter because it performs the ClassState check.
2148 self.assert_multi_line_lint(
2150 'Failed to find complete declaration of class Foo'
2151 ' [build/class] [5]')
2152 # Don't warn on forward declarations of various types.
2153 self.assert_multi_line_lint(
2156 self.assert_multi_line_lint(
2161 # Here is an example where the linter gets confused, even though
2162 # the code doesn't violate the style guide.
2163 self.assert_multi_line_lint(
2165 '#ifdef DERIVE_FROM_GOO\n'
2171 'Failed to find complete declaration of class Foo'
2172 ' [build/class] [5]')
2174 def test_build_end_comment(self):
2175 # The crosstool compiler we currently use will fail to compile the
2176 # code in this test, so we might consider removing the lint check.
2177 self.assert_lint('#endif Not a comment',
2178 'Uncommented text after #endif is non-standard.'
2180 ' [build/endif_comment] [5]')
2182 def test_build_forward_decl(self):
2183 # The crosstool compiler we currently use will fail to compile the
2184 # code in this test, so we might consider removing the lint check.
2185 self.assert_lint('class Foo::Goo;',
2186 'Inner-style forward declarations are invalid.'
2187 ' Remove this line.'
2188 ' [build/forward_decl] [5]')
2190 def test_build_header_guard(self):
2191 file_path = 'mydir/Foo.h'
2193 # We can't rely on our internal stuff to get a sane path on the open source
2194 # side of things, so just parse out the suggested header guard. This
2195 # doesn't allow us to test the suggested header guard, but it does let us
2196 # test all the other header tests.
2197 error_collector = ErrorCollector(self.assertTrue)
2198 self.process_file_data(file_path, 'h', [], error_collector)
2200 matcher = re.compile(
2201 'No \#ifndef header guard found\, suggested CPP variable is\: ([A-Za-z_0-9]+) ')
2202 for error in error_collector.result_list():
2203 matches = matcher.match(error)
2205 expected_guard = matches.group(1)
2208 # Make sure we extracted something for our header guard.
2209 self.assertNotEqual(expected_guard, '')
2212 error_collector = ErrorCollector(self.assertTrue)
2213 self.process_file_data(file_path, 'h',
2214 ['#ifndef FOO_H', '#define FOO_H'], error_collector)
2217 error_collector.result_list().count(
2218 '#ifndef header guard has wrong style, please use: %s'
2219 ' [build/header_guard] [5]' % expected_guard),
2220 error_collector.result_list())
2223 error_collector = ErrorCollector(self.assertTrue)
2224 self.process_file_data(file_path, 'h',
2225 ['#ifndef %s' % expected_guard], error_collector)
2228 error_collector.result_list().count(
2229 'No #ifndef header guard found, suggested CPP variable is: %s'
2230 ' [build/header_guard] [5]' % expected_guard),
2231 error_collector.result_list())
2234 error_collector = ErrorCollector(self.assertTrue)
2235 self.process_file_data(file_path, 'h',
2236 ['#ifndef %s' % expected_guard,
2241 error_collector.result_list().count(
2242 'No #ifndef header guard found, suggested CPP variable is: %s'
2243 ' [build/header_guard] [5]' % expected_guard),
2244 error_collector.result_list())
2246 # No header guard errors
2247 error_collector = ErrorCollector(self.assertTrue)
2248 self.process_file_data(file_path, 'h',
2249 ['#ifndef %s' % expected_guard,
2250 '#define %s' % expected_guard,
2251 '#endif // %s' % expected_guard],
2253 for line in error_collector.result_list():
2254 if line.find('build/header_guard') != -1:
2255 self.fail('Unexpected error: %s' % line)
2257 # Completely incorrect header guard
2258 error_collector = ErrorCollector(self.assertTrue)
2259 self.process_file_data(file_path, 'h',
2266 error_collector.result_list().count(
2267 '#ifndef header guard has wrong style, please use: %s'
2268 ' [build/header_guard] [5]' % expected_guard),
2269 error_collector.result_list())
2271 # Special case for flymake
2272 error_collector = ErrorCollector(self.assertTrue)
2273 self.process_file_data('mydir/Foo_flymake.h', 'h',
2274 ['#ifndef %s' % expected_guard,
2275 '#define %s' % expected_guard,
2276 '#endif // %s' % expected_guard],
2278 for line in error_collector.result_list():
2279 if line.find('build/header_guard') != -1:
2280 self.fail('Unexpected error: %s' % line)
2282 error_collector = ErrorCollector(self.assertTrue)
2283 self.process_file_data('mydir/Foo_flymake.h', 'h', [], error_collector)
2286 error_collector.result_list().count(
2287 'No #ifndef header guard found, suggested CPP variable is: %s'
2288 ' [build/header_guard] [5]' % expected_guard),
2289 error_collector.result_list())
2291 # Verify that we don't blindly suggest the WTF prefix for all headers.
2292 self.assertFalse(expected_guard.startswith('WTF_'))
2294 # Allow the WTF_ prefix for files in that directory.
2295 header_guard_filter = FilterConfiguration(('-', '+build/header_guard'))
2296 error_collector = ErrorCollector(self.assertTrue, header_guard_filter)
2297 self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h',
2298 ['#ifndef WTF_TestName_h', '#define WTF_TestName_h'],
2300 self.assertEqual(0, len(error_collector.result_list()),
2301 error_collector.result_list())
2303 # Also allow the non WTF_ prefix for files in that directory.
2304 error_collector = ErrorCollector(self.assertTrue, header_guard_filter)
2305 self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h',
2306 ['#ifndef TestName_h', '#define TestName_h'],
2308 self.assertEqual(0, len(error_collector.result_list()),
2309 error_collector.result_list())
2311 # Verify that we suggest the WTF prefix version.
2312 error_collector = ErrorCollector(self.assertTrue, header_guard_filter)
2313 self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h',
2314 ['#ifndef BAD_TestName_h', '#define BAD_TestName_h'],
2318 error_collector.result_list().count(
2319 '#ifndef header guard has wrong style, please use: WTF_TestName_h'
2320 ' [build/header_guard] [5]'),
2321 error_collector.result_list())
2323 def test_build_printf_format(self):
2325 r'printf("\%%d", value);',
2326 '%, [, (, and { are undefined character escapes. Unescape them.'
2327 ' [build/printf_format] [3]')
2330 r'snprintf(buffer, sizeof(buffer), "\[%d", value);',
2331 '%, [, (, and { are undefined character escapes. Unescape them.'
2332 ' [build/printf_format] [3]')
2335 r'fprintf(file, "\(%d", value);',
2336 '%, [, (, and { are undefined character escapes. Unescape them.'
2337 ' [build/printf_format] [3]')
2340 r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);',
2341 '%, [, (, and { are undefined character escapes. Unescape them.'
2342 ' [build/printf_format] [3]')
2344 # Don't warn if double-slash precedes the symbol
2345 self.assert_lint(r'printf("\\%%%d", value);',
2348 def test_runtime_printf_format(self):
2350 r'fprintf(file, "%q", value);',
2351 '%q in format strings is deprecated. Use %ll instead.'
2352 ' [runtime/printf_format] [3]')
2355 r'aprintf(file, "The number is %12q", value);',
2356 '%q in format strings is deprecated. Use %ll instead.'
2357 ' [runtime/printf_format] [3]')
2360 r'printf(file, "The number is" "%-12q", value);',
2361 '%q in format strings is deprecated. Use %ll instead.'
2362 ' [runtime/printf_format] [3]')
2365 r'printf(file, "The number is" "%+12q", value);',
2366 '%q in format strings is deprecated. Use %ll instead.'
2367 ' [runtime/printf_format] [3]')
2370 r'printf(file, "The number is" "% 12q", value);',
2371 '%q in format strings is deprecated. Use %ll instead.'
2372 ' [runtime/printf_format] [3]')
2375 r'snprintf(file, "Never mix %d and %1$d parmaeters!", value);',
2376 '%N$ formats are unconventional. Try rewriting to avoid them.'
2377 ' [runtime/printf_format] [2]')
2379 def assert_lintLogCodeOnError(self, code, expected_message):
2380 # Special assert_lint which logs the input code on error.
2381 result = self.perform_single_line_lint(code, 'foo.cpp')
2382 if result != expected_message:
2383 self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"'
2384 % (code, result, expected_message))
2386 def test_build_storage_class(self):
2387 qualifiers = [None, 'const', 'volatile']
2388 signs = [None, 'signed', 'unsigned']
2389 types = ['void', 'char', 'int', 'float', 'double',
2390 'schar', 'int8', 'uint8', 'int16', 'uint16',
2391 'int32', 'uint32', 'int64', 'uint64']
2392 storage_classes = ['auto', 'extern', 'register', 'static', 'typedef']
2394 build_storage_class_error_message = (
2395 'Storage class (static, extern, typedef, etc) should be first.'
2396 ' [build/storage_class] [5]')
2398 # Some explicit cases. Legal in C++, deprecated in C99.
2399 self.assert_lint('const int static foo = 5;',
2400 build_storage_class_error_message)
2402 self.assert_lint('char static foo;',
2403 build_storage_class_error_message)
2405 self.assert_lint('double const static foo = 2.0;',
2406 build_storage_class_error_message)
2408 self.assert_lint('uint64 typedef unsignedLongLong;',
2409 build_storage_class_error_message)
2411 self.assert_lint('int register foo = 0;',
2412 build_storage_class_error_message)
2414 # Since there are a very large number of possibilities, randomly
2415 # construct declarations.
2416 # Make sure that the declaration is logged if there's an error.
2417 # Seed generator with an integer for absolute reproducibility.
2419 for unused_i in range(10):
2420 # Build up random list of non-storage-class declaration specs.
2421 other_decl_specs = [random.choice(qualifiers), random.choice(signs),
2422 random.choice(types)]
2424 other_decl_specs = filter(lambda x: x is not None, other_decl_specs)
2427 random.shuffle(other_decl_specs)
2429 # insert storage class after the first
2430 storage_class = random.choice(storage_classes)
2431 insertion_point = random.randint(1, len(other_decl_specs))
2432 decl_specs = (other_decl_specs[0:insertion_point]
2434 + other_decl_specs[insertion_point:])
2436 self.assert_lintLogCodeOnError(
2437 ' '.join(decl_specs) + ';',
2438 build_storage_class_error_message)
2440 # but no error if storage class is first
2441 self.assert_lintLogCodeOnError(
2442 storage_class + ' ' + ' '.join(other_decl_specs),
2445 def test_legal_copyright(self):
2446 legal_copyright_message = (
2447 'No copyright message found. '
2448 'You should have a line: "Copyright [year] <Copyright Owner>"'
2449 ' [legal/copyright] [5]')
2451 copyright_line = '// Copyright 2008 Google Inc. All Rights Reserved.'
2453 file_path = 'mydir/googleclient/foo.cpp'
2455 # There should be a copyright message in the first 10 lines
2456 error_collector = ErrorCollector(self.assertTrue)
2457 self.process_file_data(file_path, 'cpp', [], error_collector)
2460 error_collector.result_list().count(legal_copyright_message))
2462 error_collector = ErrorCollector(self.assertTrue)
2463 self.process_file_data(
2465 ['' for unused_i in range(10)] + [copyright_line],
2469 error_collector.result_list().count(legal_copyright_message))
2471 # Test that warning isn't issued if Copyright line appears early enough.
2472 error_collector = ErrorCollector(self.assertTrue)
2473 self.process_file_data(file_path, 'cpp', [copyright_line], error_collector)
2474 for message in error_collector.result_list():
2475 if message.find('legal/copyright') != -1:
2476 self.fail('Unexpected error: %s' % message)
2478 error_collector = ErrorCollector(self.assertTrue)
2479 self.process_file_data(
2481 ['' for unused_i in range(9)] + [copyright_line],
2483 for message in error_collector.result_list():
2484 if message.find('legal/copyright') != -1:
2485 self.fail('Unexpected error: %s' % message)
2487 def test_invalid_increment(self):
2488 self.assert_lint('*count++;',
2489 'Changing pointer instead of value (or unused value of '
2490 'operator*). [runtime/invalid_increment] [5]')
2492 # Integral bitfields must be declared with either signed or unsigned keyword.
2493 def test_plain_integral_bitfields(self):
2494 errmsg = ('Please declare integral type bitfields with either signed or unsigned. [runtime/bitfields] [5]')
2496 self.assert_lint('int a : 30;', errmsg)
2497 self.assert_lint('mutable short a : 14;', errmsg)
2498 self.assert_lint('const char a : 6;', errmsg)
2499 self.assert_lint('long int a : 30;', errmsg)
2500 self.assert_lint('int a = 1 ? 0 : 30;', '')
2502 class CleansedLinesTest(unittest.TestCase):
2503 def test_init(self):
2506 'Line 3 // Comment test',
2509 clean_lines = cpp_style.CleansedLines(lines)
2510 self.assertEqual(lines, clean_lines.raw_lines)
2511 self.assertEqual(4, clean_lines.num_lines())
2513 self.assertEqual(['Line 1',
2519 self.assertEqual(['Line 1',
2525 def test_init_empty(self):
2526 clean_lines = cpp_style.CleansedLines([])
2527 self.assertEqual([], clean_lines.raw_lines)
2528 self.assertEqual(0, clean_lines.num_lines())
2530 def test_collapse_strings(self):
2531 collapse = cpp_style.CleansedLines.collapse_strings
2532 self.assertEqual('""', collapse('""')) # "" (empty)
2533 self.assertEqual('"""', collapse('"""')) # """ (bad)
2534 self.assertEqual('""', collapse('"xyz"')) # "xyz" (string)
2535 self.assertEqual('""', collapse('"\\\""')) # "\"" (string)
2536 self.assertEqual('""', collapse('"\'"')) # "'" (string)
2537 self.assertEqual('"\"', collapse('"\"')) # "\" (bad)
2538 self.assertEqual('""', collapse('"\\\\"')) # "\\" (string)
2539 self.assertEqual('"', collapse('"\\\\\\"')) # "\\\" (bad)
2540 self.assertEqual('""', collapse('"\\\\\\\\"')) # "\\\\" (string)
2542 self.assertEqual('\'\'', collapse('\'\'')) # '' (empty)
2543 self.assertEqual('\'\'', collapse('\'a\'')) # 'a' (char)
2544 self.assertEqual('\'\'', collapse('\'\\\'\'')) # '\'' (char)
2545 self.assertEqual('\'', collapse('\'\\\'')) # '\' (bad)
2546 self.assertEqual('', collapse('\\012')) # '\012' (char)
2547 self.assertEqual('', collapse('\\xfF0')) # '\xfF0' (char)
2548 self.assertEqual('', collapse('\\n')) # '\n' (char)
2549 self.assertEqual('\#', collapse('\\#')) # '\#' (bad)
2551 self.assertEqual('StringReplace(body, "", "");',
2552 collapse('StringReplace(body, "\\\\", "\\\\\\\\");'))
2553 self.assertEqual('\'\' ""',
2554 collapse('\'"\' "foo"'))
2557 class OrderOfIncludesTest(CppStyleTestBase):
2559 self.include_state = cpp_style._IncludeState()
2561 # Cheat os.path.abspath called in FileInfo class.
2562 self.os_path_abspath_orig = os.path.abspath
2563 self.os_path_isfile_orig = os.path.isfile
2564 os.path.abspath = lambda value: value
2567 os.path.abspath = self.os_path_abspath_orig
2568 os.path.isfile = self.os_path_isfile_orig
2570 def test_check_next_include_order__no_config(self):
2571 self.assertEqual('Header file should not contain WebCore config.h.',
2572 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, True, True))
2574 def test_check_next_include_order__no_self(self):
2575 self.assertEqual('Header file should not contain itself.',
2576 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, True, True))
2577 # Test actual code to make sure that header types are correctly assigned.
2578 self.assert_language_rules_check('Foo.h',
2579 '#include "Foo.h"\n',
2580 'Header file should not contain itself. Should be: alphabetically sorted.'
2581 ' [build/include_order] [4]')
2582 self.assert_language_rules_check('FooBar.h',
2583 '#include "Foo.h"\n',
2586 def test_check_next_include_order__likely_then_config(self):
2587 self.assertEqual('Found header this file implements before WebCore config.h.',
2588 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False, True))
2589 self.assertEqual('Found WebCore config.h after a header this file implements.',
2590 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
2592 def test_check_next_include_order__other_then_config(self):
2593 self.assertEqual('Found other header before WebCore config.h.',
2594 self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False, True))
2595 self.assertEqual('Found WebCore config.h after other header.',
2596 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
2598 def test_check_next_include_order__config_then_other_then_likely(self):
2599 self.assertEqual('', self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
2600 self.assertEqual('Found other header before a header this file implements.',
2601 self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False, True))
2602 self.assertEqual('Found header this file implements after other header.',
2603 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False, True))
2605 def test_check_alphabetical_include_order(self):
2606 self.assert_language_rules_check('foo.h',
2610 'Alphabetical sorting problem. [build/include_order] [4]')
2612 self.assert_language_rules_check('foo.h',
2618 self.assert_language_rules_check('foo.h',
2619 '#include <assert.h>\n'
2620 '#include "bar.h"\n',
2621 'Bad include order. Mixing system and custom headers. [build/include_order] [4]')
2623 self.assert_language_rules_check('foo.h',
2624 '#include "bar.h"\n'
2625 '#include <assert.h>\n',
2628 def test_check_alphabetical_include_order_errors_reported_for_both_lines(self):
2629 # If one of the two lines of out of order headers are filtered, the error should be
2630 # reported on the other line.
2631 self.assert_language_rules_check('foo.h',
2635 'Alphabetical sorting problem. [build/include_order] [4]',
2638 self.assert_language_rules_check('foo.h',
2642 'Alphabetical sorting problem. [build/include_order] [4]',
2645 # If no lines are filtered, the error should be reported only once.
2646 self.assert_language_rules_check('foo.h',
2650 'Alphabetical sorting problem. [build/include_order] [4]')
2652 def test_check_line_break_after_own_header(self):
2653 self.assert_language_rules_check('foo.cpp',
2654 '#include "config.h"\n'
2655 '#include "foo.h"\n'
2656 '#include "bar.h"\n',
2657 'You should add a blank line after implementation file\'s own header. [build/include_order] [4]')
2659 self.assert_language_rules_check('foo.cpp',
2660 '#include "config.h"\n'
2661 '#include "foo.h"\n'
2663 '#include "bar.h"\n',
2666 def test_check_line_break_before_own_header(self):
2667 self.assert_language_rules_check('foo.cpp',
2668 '#include "config.h"\n'
2670 '#include "foo.h"\n'
2672 '#include "bar.h"\n',
2673 'You should not add a blank line before implementation file\'s own header. [build/include_order] [4]')
2675 self.assert_language_rules_check('foo.cpp',
2676 '#include "config.h"\n'
2677 '#include "foo.h"\n'
2679 '#include "bar.h"\n',
2682 def test_check_preprocessor_in_include_section(self):
2683 self.assert_language_rules_check('foo.cpp',
2684 '#include "config.h"\n'
2685 '#include "foo.h"\n'
2688 '#include "baz.h"\n'
2690 '#include "foobar.h"\n'
2692 '#include "bar.h"\n', # No flag because previous is in preprocessor section
2695 self.assert_language_rules_check('foo.cpp',
2696 '#include "config.h"\n'
2697 '#include "foo.h"\n'
2700 '#include "baz.h"\n'
2702 '#include "bar.h"\n'
2703 '#include "a.h"\n', # Should still flag this.
2704 'Alphabetical sorting problem. [build/include_order] [4]')
2706 self.assert_language_rules_check('foo.cpp',
2707 '#include "config.h"\n'
2708 '#include "foo.h"\n'
2711 '#include "baz.h"\n'
2712 '#include "bar.h"\n' #Should still flag this
2714 'Alphabetical sorting problem. [build/include_order] [4]')
2716 self.assert_language_rules_check('foo.cpp',
2717 '#include "config.h"\n'
2718 '#include "foo.h"\n'
2721 '#include "baz.h"\n'
2724 '#include "foobar.h"\n'
2726 '#include "bar.h"\n'
2727 '#include "a.h"\n', # Should still flag this.
2728 'Alphabetical sorting problem. [build/include_order] [4]')
2730 # Check that after an already included error, the sorting rules still work.
2731 self.assert_language_rules_check('foo.cpp',
2732 '#include "config.h"\n'
2733 '#include "foo.h"\n'
2735 '#include "foo.h"\n'
2737 '"foo.h" already included at foo.cpp:2 [build/include] [4]')
2739 def test_primary_header(self):
2740 # File with non-existing primary header should not produce errors.
2741 self.assert_language_rules_check('foo.cpp',
2742 '#include "config.h"\n'
2744 '#include "bar.h"\n',
2746 # Pretend that header files exist.
2747 os.path.isfile = lambda filename: True
2748 # Missing include for existing primary header -> error.
2749 self.assert_language_rules_check('foo.cpp',
2750 '#include "config.h"\n'
2752 '#include "bar.h"\n',
2753 'Found other header before a header this file implements. '
2754 'Should be: config.h, primary header, blank line, and then '
2755 'alphabetically sorted. [build/include_order] [4]')
2756 # Having include for existing primary header -> no error.
2757 self.assert_language_rules_check('foo.cpp',
2758 '#include "config.h"\n'
2759 '#include "foo.h"\n'
2761 '#include "bar.h"\n',
2764 os.path.isfile = self.os_path_isfile_orig
2766 def test_public_primary_header(self):
2767 # System header is not considered a primary header.
2768 self.assert_language_rules_check('foo.cpp',
2769 '#include "config.h"\n'
2770 '#include <other/foo.h>\n'
2773 'Bad include order. Mixing system and custom headers. [build/include_order] [4]')
2775 # ...except that it starts with public/.
2776 self.assert_language_rules_check('foo.cpp',
2777 '#include "config.h"\n'
2778 '#include <public/foo.h>\n'
2783 # Even if it starts with public/ its base part must match with the source file name.
2784 self.assert_language_rules_check('foo.cpp',
2785 '#include "config.h"\n'
2786 '#include <public/foop.h>\n'
2789 'Bad include order. Mixing system and custom headers. [build/include_order] [4]')
2791 def test_check_wtf_includes(self):
2792 self.assert_language_rules_check('foo.cpp',
2793 '#include "config.h"\n'
2794 '#include "foo.h"\n'
2796 '#include <wtf/Assertions.h>\n',
2798 self.assert_language_rules_check('foo.cpp',
2799 '#include "config.h"\n'
2800 '#include "foo.h"\n'
2802 '#include "wtf/Assertions.h"\n',
2803 'wtf includes should be <wtf/file.h> instead of "wtf/file.h".'
2804 ' [build/include] [4]')
2806 def test_classify_include(self):
2807 classify_include = cpp_style._classify_include
2808 include_state = cpp_style._IncludeState()
2809 self.assertEqual(cpp_style._CONFIG_HEADER,
2810 classify_include('foo/foo.cpp',
2812 False, include_state))
2813 self.assertEqual(cpp_style._PRIMARY_HEADER,
2814 classify_include('foo/internal/foo.cpp',
2816 False, include_state))
2817 self.assertEqual(cpp_style._PRIMARY_HEADER,
2818 classify_include('foo/internal/foo.cpp',
2819 'foo/other/public/foo.h',
2820 False, include_state))
2821 self.assertEqual(cpp_style._OTHER_HEADER,
2822 classify_include('foo/internal/foo.cpp',