Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: sky/tools/webkitpy/style/checkers/cpp_unittest.py

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

Powered by Google App Engine
This is Rietveld 408576698