Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Tools / Scripts / webkitpy / style / checkers / cpp_unittest.py
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_categories.
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"' % category)
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'), 'abc')
109         self.assertEqual(cpp_style._convert_to_lower_with_underscores('aB'), 'a_b')
110         self.assertEqual(cpp_style._convert_to_lower_with_underscores('isAName'), 'is_a_name')
111         self.assertEqual(cpp_style._convert_to_lower_with_underscores('AnotherTest'), 'another_test')
112         self.assertEqual(cpp_style._convert_to_lower_with_underscores('PassRefPtr<MyClass>'), 'pass_ref_ptr<my_class>')
113         self.assertEqual(cpp_style._convert_to_lower_with_underscores('_ABC'), '_abc')
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_objective_c())
126         self.assertFalse(cpp_style._FileState(clean_lines, 'cc').is_c_or_objective_c())
127         self.assertFalse(cpp_style._FileState(clean_lines, 'h').is_c_or_objective_c())
128         self.assertTrue(cpp_style._FileState(clean_objc_lines, 'h').is_c_or_objective_c())
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 long int'), '                    int,')
177         self.assertEqual(cpp_style.create_skeleton_parameters('long int*'), '     int ,')
178         self.assertEqual(cpp_style.create_skeleton_parameters('PassRefPtr<Foo> a'), 'PassRefPtr      a,')
179         self.assertEqual(cpp_style.create_skeleton_parameters(
180                 'ComplexTemplate<NestedTemplate1<MyClass1, MyClass2>, NestedTemplate1<MyClass1, MyClass2> > param, int second'),
181                           'ComplexTemplate                                                                            param, int second,')
182         self.assertEqual(cpp_style.create_skeleton_parameters('int = 0, Namespace::Type& a'), 'int    ,            Type  a,')
183         # Create skeleton parameters is a bit too aggressive with function variables, but
184         # it allows for parsing other parameters and declarations like this are rare.
185         self.assertEqual(cpp_style.create_skeleton_parameters('void (*fn)(int a, int b), Namespace::Type& a'),
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': 'paramName', 'row': 0},
205                                {'type': 'const Other1Class&', 'name': 'foo', 'row': 1},
206                                {'type': 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const *', 'name': 'param', 'row': 2},
207                                {'type': 'int*', 'name': 'myCount', 'row': 3})
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 should 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(basic_error_rules), lines_to_check)
246         lines = code.split('\n')
247         extension = filename.split('.')[1]
248         self.process_file_data(filename, extension, lines, error_collector, fs)
249         return error_collector.results()
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_rules)
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_check=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, file_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, file_extension))
322
323     def assert_multi_line_lint_re(self, code, expected_message_re, file_name='foo.h'):
324         file_extension = file_name[file_name.rfind('.') + 1:]
325         message = self.perform_multi_line_lint(code, file_extension)
326         if not re.search(expected_message_re, message):
327             self.fail('Message was:\n' + message + 'Expected match to "' + expected_message_re + '"')
328
329     def assert_language_rules_check(self, file_name, code, expected_message, lines_to_check=None):
330         self.assertEqual(expected_message,
331                           self.perform_language_rules_check(file_name, code, lines_to_check))
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_position[1]),
357                           'position %s, tuple_position %s' % (position, tuple_position))
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_information['modifiers_and_return_type'])
372         self.assertEqual(function_state.is_pure, function_information['is_pure'])
373         self.assertEqual(function_state.is_declaration, function_information['is_declaration'])
374         self.assert_positions_equal(function_state.function_name_start_position, function_information['function_name_start_position'])
375         self.assert_positions_equal(function_state.parameter_start_position, function_information['parameter_start_position'])
376         self.assert_positions_equal(function_state.parameter_end_position, function_information['parameter_end_position'])
377         self.assert_positions_equal(function_state.body_start_position, function_information['body_start_position'])
378         self.assert_positions_equal(function_state.end_position, function_information['end_position'])
379         expected_parameters = function_information.get('parameter_list')
380         if expected_parameters:
381             actual_parameters = function_state.parameter_list()
382             self.assertEqual(len(actual_parameters), len(expected_parameters))
383             for index in range(len(expected_parameters)):
384                 actual_parameter = actual_parameters[index]
385                 expected_parameter = expected_parameters[index]
386                 self.assertEqual(actual_parameter.type, expected_parameter['type'])
387                 self.assertEqual(actual_parameter.name, expected_parameter['name'])
388                 self.assertEqual(actual_parameter.row, expected_parameter['row'])
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 CheckedInt<T> &rhs);'],
419             {'name': 'operator /',
420              'modifiers_and_return_type': 'CheckedInt<T>',
421              'function_name_start_position': (0, 14),
422              'parameter_start_position': (0, 24),
423              'parameter_end_position': (0, 76),
424              'body_start_position': (0, 76),
425              'end_position': (0, 77),
426              'is_pure': False,
427              'is_declaration': True})
428
429         self.perform_function_detection(
430             ['CheckedInt<T> operator -(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
431             {'name': 'operator -',
432              'modifiers_and_return_type': 'CheckedInt<T>',
433              'function_name_start_position': (0, 14),
434              'parameter_start_position': (0, 24),
435              'parameter_end_position': (0, 76),
436              'body_start_position': (0, 76),
437              'end_position': (0, 77),
438              'is_pure': False,
439              'is_declaration': True})
440
441         self.perform_function_detection(
442             ['CheckedInt<T> operator !=(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
443             {'name': 'operator !=',
444              'modifiers_and_return_type': 'CheckedInt<T>',
445              'function_name_start_position': (0, 14),
446              'parameter_start_position': (0, 25),
447              'parameter_end_position': (0, 77),
448              'body_start_position': (0, 77),
449              'end_position': (0, 78),
450              'is_pure': False,
451              'is_declaration': True})
452
453         self.perform_function_detection(
454             ['CheckedInt<T> operator +(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
455             {'name': 'operator +',
456              'modifiers_and_return_type': 'CheckedInt<T>',
457              'function_name_start_position': (0, 14),
458              'parameter_start_position': (0, 24),
459              'parameter_end_position': (0, 76),
460              'body_start_position': (0, 76),
461              'end_position': (0, 77),
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 unsigned int);'],
562             {'name': 'functionName',
563              'modifiers_and_return_type': 'void',
564              'function_name_start_position': (0, 5),
565              'parameter_start_position': (0, 17),
566              'parameter_end_position': (0, 76),
567              'body_start_position': (0, 76),
568              'end_position': (0, 77),
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 unsigned long int*&, const MediaPlayer::Preload, Other<Other2, Other3<P1, P2> >, int);'],
580             {'name': 'determineARIADropEffects',
581              'modifiers_and_return_type': 'virtual void',
582              'parameter_start_position': (0, 37),
583              'function_name_start_position': (0, 13),
584              'parameter_end_position': (0, 147),
585              'body_start_position': (0, 147),
586              'end_position': (0, 148),
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 * param = new ComplexTemplate<Class1, NestedTemplate<P1, P2> >(34, 42),',
603              'int* myCount = 0);'],
604             {'name': 'aFunctionName',
605              'modifiers_and_return_type': 'virtual AnotherTemplate<Class1, Class2>',
606              'function_name_start_position': (2, 32),
607              'parameter_start_position': (2, 45),
608              'parameter_end_position': (5, 17),
609              'body_start_position': (5, 17),
610              'end_position': (5, 18),
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.column - 1))
659         self.assertTrue(position < cpp_style.Position(position.row, position.column + 1))
660         self.assertTrue(position < cpp_style.Position(position.row + 1, position.column - 1))
661         self.assertEqual(position.__str__(), '(3, 4)')
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', lines, start_position, not_found_position))
668         self.assertTrue(cpp_style.Position(1, 1) == cpp_style._rfind_in_lines('a', lines, start_position, not_found_position))
669         self.assertEqual(cpp_style.Position(2, 2), cpp_style._rfind_in_lines('(te|a)', lines, start_position, not_found_position))
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 allowed. 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 allowed. 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();', message)
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.path.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 found. '
1136                                      'Lint may give bogus warnings.  Consider replacing these with '
1137                                      '//-style comments, with #if 0...#endif, or with more clearly '
1138                                      'structured multi-line comments.  [readability/multiline_comment] [5]'])
1139         self.assert_multi_line_lint(r'''    // /* comment, but not multi-line''', '')
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 named '
1400                   "('k' followed by CamelCase) compile-time constant for the size."
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];', 'Missing 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 context)
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 for'
1643                          '  [whitespace/parens] [5]')
1644         self.assert_lint('for (foo; bar; ) {', '')
1645         self.assert_lint('for ((foo); (bar); ) {', '')
1646         self.assert_lint('foreach (foo, foos ) {', 'Extra space before ) in foreach'
1647                          '  [whitespace/parens] [5]')
1648         self.assert_lint('foreach ( foo, foos) {', 'Extra space after ( in foreach'
1649                          '  [whitespace/parens] [5]')
1650         self.assert_lint('while (  foo) {', 'Extra space after ( in while'
1651                          '  [whitespace/parens] [5]')
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/braces] [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/multiline_comment] [5]')
1772         self.assert_lint('a<Foo&> t <<= &b | &c;', '')
1773         self.assert_lint('a<Foo*> t <<= &b & &c; // Test', '')
1774         self.assert_lint('a<Foo*> t <<= *b / &c; // Test', '')
1775         self.assert_lint('if (a=b == 1)', 'Missing spaces around =  [whitespace/operators] [4]')
1776         self.assert_lint('a = 1<<20', 'Missing spaces around <<  [whitespace/operators] [3]')
1777         self.assert_lint('if (a = b == 1)', '')
1778         self.assert_lint('a = 1 << 20', '')
1779         self.assert_multi_line_lint('#include <sys/io.h>\n', '')
1780         self.assert_multi_line_lint('#import <foo/bar.h>\n', '')
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 an '
1799                          'empty statement, use { } instead.'
1800                          '  [whitespace/semicolon] [5]')
1801         self.assert_lint('while (true) ;',
1802                          'Extra space before last semicolon. If this should be an '
1803                          'empty statement, use { } instead.'
1804                          '  [whitespace/semicolon] [5]')
1805         self.assert_lint('default:;',
1806                          'Semicolon defining empty statement. Use { } instead.'
1807                          '  [whitespace/semicolon] [5]')
1808         self.assert_lint('        ;',
1809                          'Line contains only semicolon. If this should be an empty '
1810                          'statement, use { } instead.'
1811                          '  [whitespace/semicolon] [5]')
1812         self.assert_lint('for (int i = 0; ;', '')
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 extra spaces.  [whitespace/end_of_line] [4]')
1909         self.assert_lint('int a; // This is a sentence. This is a another sentence.',
1910                          '')
1911         self.assert_lint('int a; // This is a sentence.  This is a another sentence.',
1912                          'Should have only a single space after a punctuation in a comment.  [whitespace/comments] [5]')
1913         self.assert_lint('int a; // This is a sentence!  This is a another sentence.',
1914                          'Should have only a single space after a punctuation in a comment.  [whitespace/comments] [5]')
1915         self.assert_lint('int a; // Why did I write this?  This is a another sentence.',
1916                          'Should have only a single space after a punctuation in a comment.  [whitespace/comments] [5]')
1917         self.assert_lint('int a; // Elementary,  my dear.',
1918                          'Should have only a single space after a punctuation in a comment.  [whitespace/comments] [5]')
1919         self.assert_lint('int a; // The following should be clear:  Is it?',
1920                          'Should have only a single space after a punctuation in a comment.  [whitespace/comments] [5]')
1921         self.assert_lint('int a; // Look at the follow semicolon;  I hope this gives an error.',
1922                          'Should have only a single space after a punctuation in a comment.  [whitespace/comments] [5]')
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  [whitespace/declaration] [3]')
2051         self.assert_lint('else if { }', '')
2052         self.assert_lint('else   if { }', 'Extra space between else and if  [whitespace/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 int* 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 indent?  [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#Namespaces'
2133             ' for more information.  [build/namespaces] [4]')
2134         # namespace registration macros are OK.
2135         self.assert_language_rules_check('foo.h', 'namespace {  \\', '')
2136         # named namespaces are OK.
2137         self.assert_language_rules_check('foo.h', 'namespace foo {', '')
2138         self.assert_language_rules_check('foo.h', 'namespace foonamespace {', '')
2139         self.assert_language_rules_check('foo.cpp', 'namespace {', '')
2140         self.assert_language_rules_check('foo.cpp', 'namespace foo {', '')
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 source
2192         # side of things, so just parse out the suggested header guard. This
2193         # doesn't allow us to test the suggested header guard, but it does let us
2194         # test all the other header tests.
2195         error_collector = ErrorCollector(self.assertTrue)
2196         self.process_file_data(file_path, 'h', [], error_collector)
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_collector)
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_collector)
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 warning.
2510     def test_mixing_unsigned_bool_bitfields(self):
2511         def errmsg(bool_bitfields, unsigned_bitfields, name):
2512             bool_list = ', '.join(bool_bitfields)
2513             unsigned_list = ', '.join(unsigned_bitfields)
2514             return ('The class %s contains mixed unsigned and bool bitfields, '
2515                     'which will pack into separate words on the MSVC compiler.\n'
2516                     'Bool bitfields are [%s].\nUnsigned bitfields are [%s].\n'
2517                     'Consider converting bool bitfields to unsigned.  [runtime/bitfields] [5]'
2518                     % (name, bool_list, unsigned_list))
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_unsignedMember', 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_anotherUnsigned', 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  [runtime/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/bitfields] [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_unusualinternal.h'))
2662         self.assertEqual('',
2663                          cpp_style._drop_common_suffixes('_test.cpp'))
2664         self.assertEqual('test',
2665                          cpp_style._drop_common_suffixes('test.cpp'))
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 config.h.',
2699                          self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False, True))
2700         self.assertEqual('Found WebCore config.h after a header this file implements.',
2701                          self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
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_style._CONFIG_HEADER, False, True))
2711         self.assertEqual('Found other header before a header this file implements.',
2712                          self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False, True))
2713         self.assertEqual('Found header this file implements after other header.',
2714                          self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False, True))
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(self):
2740         # If one of the two lines of out of order headers are filtered, the error should be
2741         # reported on the other line.
2742         self.assert_language_rules_check('foo.h',
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 implementation 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 work.
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 this file implements. '
2849                                          'Should be: config.h, primary header, blank line, and then '
2850                                          'alphabetically sorted.  [build/include_order] [4]')
2851         # Having include for existing primary header -> no error.
2852         self.assert_language_rules_check('foo.cpp',
2853                                          '#include "config.h"\n'
2854                                          '#include "foo.h"\n'
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 source 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" instead of <wtf/file.h>.'
2893                                          '  [build/include] [4]')
2894         self.assert_language_rules_check('foo.cpp',
2895                                          '#include "config.h"\n'
2896                                          '#include "foo.h"\n'
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" instead 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 after a header this file implements.'
2980                                          ' Should be: config.h, primary header, blank line, and then alphabetically sorted.'
2981                                          '  [build/include_order] [4]')
2982         self.assert_language_rules_check('ResourceHandleWin.cpp',
2983                                          '#include "config.h"\n'
2984                                          '#include "ResourceHandle.h"\n'
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_unusualinternal.h'))
2996         self.assertEqual('',
2997                          cpp_style._drop_common_suffixes('_test.cpp'))
2998         self.assertEqual('test',
2999                          cpp_style._drop_common_suffixes('test.cpp'))
3000         self.assertEqual('test',
3001                          cpp_style._drop_common_suffixes('test.cpp'))
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 warning.
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_level),
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 setting.
3092
3093         Args:
3094           error_level: --v setting for cpp_style.
3095         """
3096         self.assert_function_length_check_definition(self.trigger_lines(error_level) - 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 setting.
3101
3102         Args:
3103           error_level: --v setting for cpp_style.
3104         """
3105         self.assert_function_length_check_definition(self.trigger_lines(error_level) + 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_lines + '}'
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 func(const Element*)>*\n'
3210              'my_namespace::my_other_namespace<Type3, Type4>::~MyFunction<Type5<Type6, Type7> >(int arg1, char* arg2)'
3211              + self.function_body(error_lines)),
3212             ('Small and focused functions are preferred: '
3213              'my_namespace::my_other_namespace<Type3, Type4>::~MyFunction<Type5<Type6, Type7> >()'
3214              ' has %d non-comment lines '
3215              '(error triggered by exceeding %d lines).'
3216              '  [readability/fn_size] [%d]')
3217             % (error_lines, trigger_level, error_level))
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_break(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(self):
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.  [readability/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.  [readability/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.  [readability/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.  [readability/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 potential '
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 avoid 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 indent?  [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 statement.'
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 statement.'
3920             '  [whitespace/indent] [4]')
3921         self.assert_multi_line_lint(
3922             '    switch (condition) {\n'
3923             '    case fooCondition:\n'
3924             '    case barCondition:\n'
3925             '        switch (otherCondition) {\n'
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 statement.'
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)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0)\n',
4087             '')
4088         self.assert_multi_line_lint(
4089             '#define TEST_ASSERT(expression) do { if ( !(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0)\n',
4090             'Extra space after ( in if  [whitespace/parens] [5]')
4091         # FIXME: currently we only check first conditional, so we cannot detect errors in next ones.
4092         # self.assert_multi_line_lint(
4093         #     '#define TEST_ASSERT(expression) do { if (!(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0 )\n',
4094         #     'Mismatching spaces inside () in if  [whitespace/parens] [5]')
4095         self.assert_multi_line_lint(
4096             'WTF_MAKE_NONCOPYABLE(ClassName); WTF_MAKE_FAST_ALLOCATED;\n',
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 }  [whitespace/newline] [4]')
4108         self.assert_multi_line_lint(
4109             'if (condition) doSomething(); else doSomethingElse();\n',
4110             ['More than one command on the same line  [whitespace/newline] [4]',
4111              'Else clause should never be on same line as else (use 2 lines)  [whitespace/newline] [4]',
4112              'More than one command on the same line in if  [whitespace/parens] [4]'])
4113         self.assert_multi_line_lint(
4114             'if (condition) doSomething(); else {\n'
4115             '    doSomethingElse();\n'
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 part 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 statement.'
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 part must too.  [whitespace/braces] [4]',
4196              'An else if statement should be written as an if statement when the '
4197              'prior "if" concludes with a return, break, continue or goto statement.'
4198              '  [readability/control_flow] [4]'])
4199         self.assert_multi_line_lint(
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 part must too.  [whitespace/braces] [4]',
4208              'This { should be at the end of the previous line  [whitespace/braces] [4]',
4209              'An else should appear on the same line as the preceding }  [whitespace/newline] [4]',
4210              'An else if statement should be written as an if statement when the '
4211              'prior "if" concludes with a return, break, continue or goto statement.'
4212              '  [readability/control_flow] [4]'])
4213         self.assert_multi_line_lint(
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 statement.'
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 part must too.  [whitespace/braces] [4]',
4248              'An else statement can be removed when the prior "if" concludes '
4249              'with a return, break, continue or goto statement.'
4250              '  [readability/control_flow] [4]'])
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/braces] [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/braces] [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/braces] [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/braces] [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/braces] [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/braces] [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/braces] [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/braces] [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/braces] [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/braces] [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/braces] [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 part 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 part 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 part 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 part 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 part 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 part 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 indent?  [whitespace/indent] [3]')
4592         self.assert_multi_line_lint(
4593             'for ( ; current; current = current->next);\n',
4594             'Semicolon defining empty statement for this loop. Use { } instead.  [whitespace/semicolon] [5]')
4595         self.assert_multi_line_lint(
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 correctly 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 files.
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, type, error, NULL);',
4711             '')
4712         self.assert_lint(
4713             'gchar* result = gdk_pixbuf_save_to_stream(pixbuf, function, data, type, error, NULL);',
4714             '')
4715         self.assert_lint(
4716             'gtk_widget_style_get(style, "propertyName", &value, "otherName", &otherValue, NULL);',
4717             '')
4718         self.assert_lint(
4719             'gtk_style_context_get_style(context, "propertyName", &value, "otherName", &otherValue, NULL);',
4720             '')
4721         self.assert_lint(
4722             'gtk_style_context_get(context, static_cast<GtkStateFlags>(0), "property", &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 equality comparisons\.')
4742         self.assert_lint(
4743             'if (p == nullptr)',
4744             'Tests for true/false and null/non-null should be done without equality comparisons.'
4745             '  [readability/comparison_to_boolean] [5]')
4746         self.assert_lint(
4747             'if (condition == true)',
4748             'Tests for true/false and null/non-null should be done without equality comparisons.'
4749             '  [readability/comparison_to_boolean] [5]')
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 equality 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 equality 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 equality 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 equality 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 equality 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 never 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 underscores in your identifier names.  [readability/naming/underscores] [4]"
4861         name_tooshort_error_message = " is incorrectly named. Don't use the single letter 'l' as an identifier name.  [readability/naming] [4]"
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> > under_score;',
4925                          'under_score' + name_underscore_error_message)
4926         self.assert_lint('int under_score[];',
4927                          'under_score' + name_underscore_error_message)
4928         self.assert_lint('struct dirent* under_score;',
4929                          'under_score' + name_underscore_error_message)
4930         self.assert_lint('long under_score;',
4931                          'under_score' + name_underscore_error_message)
4932         self.assert_lint('long long under_score;',
4933                          'under_score' + name_underscore_error_message)
4934         self.assert_lint('long double under_score;',
4935                          'under_score' + name_underscore_error_message)
4936         self.assert_lint('long long int under_score;',
4937                          'under_score' + name_underscore_error_message)
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_message)
4962         self.assert_lint('int SomeClass::under_score = 0;',
4963                          'SomeClass::under_score' + name_underscore_error_message)
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 JavaScriptCore directory.
4989         self.assert_lint('void this_op_code(int var1, int var2)', '', 'Source/JavaScriptCore/foo.cpp')
4990         self.assert_lint('void op_code(int var1, int var2)', '', 'Source/JavaScriptCore/foo.cpp')
4991         self.assert_lint('void this_op_code(int var1, int var2)', 'this_op_code' + name_underscore_error_message)
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)', '', 'Source/Webkit/gtk/webkit/foo.cpp')
4999         self.assert_lint('void webkit_web_view_load(int var1, int var2)', '', 'Source/Webkit2/UIProcess/gtk/foo.cpp')
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 in your identifier names.'
5004             '  [readability/naming/underscores] [4]', 'Source/Webkit/webkit/foo.cpp')
5005         # Test that this doesn't also apply to names that don't start with 'webkit_'.
5006         self.assert_lint_one_of_many_errors_re('void otherkit_web_view_load(int var1, int var2)',
5007             'otherkit_web_view_load is incorrectly named. Don\'t use underscores in your identifier names.'
5008             '  [readability/naming/underscores] [4]', 'Source/Webkit/webkit/foo.cpp')
5009
5010         # There is an exception for some unit tests that begin with "tst_".
5011         self.assert_lint('void tst_QWebFrame::arrayObjectEnumerable(int var1, int var2)', '')
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         # NPAPI functions that start with NPN_, NPP_ or NP_ are allowed.
5032         self.assert_lint('void NPN_Status(NPP, const char*)', '')
5033         self.assert_lint('NPError NPP_SetWindow(NPP instance, NPWindow *window)', '')
5034         self.assert_lint('NPObject* NP_Allocate(NPP, NPClass*)', '')
5035
5036         # const_iterator is allowed as well.
5037         self.assert_lint('typedef VectorType::const_iterator const_iterator;', '')
5038
5039         # vm_throw is allowed as well.
5040         self.assert_lint('int vm_throw;', '')
5041
5042         # Attributes.
5043         self.assert_lint('int foo ALLOW_UNUSED;', '')
5044         self.assert_lint('int foo_error ALLOW_UNUSED;', 'foo_error' + name_underscore_error_message)
5045         self.assert_lint('ThreadFunctionInvocation* leakedInvocation ALLOW_UNUSED = invocation.leakPtr()', '')
5046
5047         # Bitfields.
5048         self.assert_lint('unsigned _fillRule : 1;',
5049                          '_fillRule' + name_underscore_error_message)
5050
5051         # new operators in initialization.
5052         self.assert_lint('OwnPtr<uint32_t> variable(new uint32_t);', '')
5053         self.assert_lint('OwnPtr<uint32_t> variable(new (expr) uint32_t);', '')
5054         self.assert_lint('OwnPtr<uint32_t> under_score(new uint32_t);',
5055                          'under_score' + name_underscore_error_message)
5056
5057         # Conversion operator declaration.
5058         self.assert_lint('operator int64_t();', '')
5059
5060     def test_parameter_names(self):
5061         # Leave meaningless variable names out of function declarations.
5062         meaningless_variable_name_error_message = 'The parameter name "%s" adds no information, so it should be removed.  [readability/parameter_name] [5]'
5063
5064         parameter_error_rules = ('-',
5065                                  '+readability/parameter_name')
5066         # No variable name, so no error.
5067         self.assertEqual('',
5068                           self.perform_lint('void func(int);', 'test.cpp', parameter_error_rules))
5069
5070         # Verify that copying the name of the set function causes the error (with some odd casing).
5071         self.assertEqual(meaningless_variable_name_error_message % 'itemCount',
5072                           self.perform_lint('void setItemCount(size_t itemCount);', 'test.cpp', parameter_error_rules))
5073         self.assertEqual(meaningless_variable_name_error_message % 'abcCount',
5074                           self.perform_lint('void setABCCount(size_t abcCount);', 'test.cpp', parameter_error_rules))
5075
5076         # Verify that copying a type name will trigger the warning (even if the type is a template parameter).
5077         self.assertEqual(meaningless_variable_name_error_message % 'context',
5078                           self.perform_lint('void funct(PassRefPtr<ScriptExecutionContext> context);', 'test.cpp', parameter_error_rules))
5079
5080         # Verify that acronyms as variable names trigger the error (for both set functions and type names).
5081         self.assertEqual(meaningless_variable_name_error_message % 'ec',
5082                           self.perform_lint('void setExceptionCode(int ec);', 'test.cpp', parameter_error_rules))
5083         self.assertEqual(meaningless_variable_name_error_message % 'ec',
5084                           self.perform_lint('void funct(ExceptionCode ec);', 'test.cpp', parameter_error_rules))
5085
5086         # 'object' alone, appended, or as part of an acronym is meaningless.
5087         self.assertEqual(meaningless_variable_name_error_message % 'object',
5088                           self.perform_lint('void funct(RenderView object);', 'test.cpp', parameter_error_rules))
5089         self.assertEqual(meaningless_variable_name_error_message % 'viewObject',
5090                           self.perform_lint('void funct(RenderView viewObject);', 'test.cpp', parameter_error_rules))
5091         self.assertEqual(meaningless_variable_name_error_message % 'rvo',
5092                           self.perform_lint('void funct(RenderView rvo);', 'test.cpp', parameter_error_rules))
5093
5094         # Check that r, g, b, and a are allowed.
5095         self.assertEqual('',
5096                           self.perform_lint('void setRGBAValues(int r, int g, int b, int a);', 'test.cpp', parameter_error_rules))
5097
5098         # Verify that a simple substring match isn't done which would cause false positives.
5099         self.assertEqual('',
5100                           self.perform_lint('void setNateLateCount(size_t elate);', 'test.cpp', parameter_error_rules))
5101         self.assertEqual('',
5102                           self.perform_lint('void funct(NateLate elate);', 'test.cpp', parameter_error_rules))
5103
5104         # Don't have generate warnings for functions (only declarations).
5105         self.assertEqual('',
5106                           self.perform_lint('void funct(PassRefPtr<ScriptExecutionContext> context)\n'
5107                                             '{\n'
5108                                             '}\n', 'test.cpp', parameter_error_rules))
5109
5110     def test_comments(self):
5111         # A comment at the beginning of a line is ok.
5112         self.assert_lint('// comment', '')
5113         self.assert_lint('    // comment', '')
5114
5115         self.assert_lint('}  // namespace WebCore',
5116                          'One space before end of line comments'
5117                          '  [whitespace/comments] [5]')
5118
5119     def test_webkit_export_check(self):
5120         webkit_export_error_rules = ('-',
5121                                   '+readability/webkit_export')
5122         self.assertEqual('',
5123                           self.perform_lint('WEBKIT_EXPORT int foo();\n',
5124                                             'WebKit/chromium/public/test.h',
5125                                             webkit_export_error_rules))
5126         self.assertEqual('',
5127                           self.perform_lint('WEBKIT_EXPORT int foo();\n',
5128                                             'WebKit/chromium/tests/test.h',
5129                                             webkit_export_error_rules))
5130         self.assertEqual('WEBKIT_EXPORT should only be used in header files.  [readability/webkit_export] [5]',
5131                           self.perform_lint('WEBKIT_EXPORT int foo();\n',
5132                                             'WebKit/chromium/public/test.cpp',
5133                                             webkit_export_error_rules))
5134         self.assertEqual('WEBKIT_EXPORT should only appear in the chromium public (or tests) directory.  [readability/webkit_export] [5]',
5135                           self.perform_lint('WEBKIT_EXPORT int foo();\n',
5136                                             'WebKit/chromium/src/test.h',
5137                                             webkit_export_error_rules))
5138         self.assertEqual('WEBKIT_EXPORT should not be used on a function with a body.  [readability/webkit_export] [5]',
5139                           self.perform_lint('WEBKIT_EXPORT int foo() { }\n',
5140                                             'WebKit/chromium/public/test.h',
5141                                             webkit_export_error_rules))
5142         self.assertEqual('WEBKIT_EXPORT should not be used on a function with a body.  [readability/webkit_export] [5]',
5143                           self.perform_lint('WEBKIT_EXPORT inline int foo()\n'
5144                                             '{\n'
5145                                             '}\n',
5146                                             'WebKit/chromium/public/test.h',
5147                                             webkit_export_error_rules))
5148         self.assertEqual('WEBKIT_EXPORT should not be used with a pure virtual function.  [readability/webkit_export] [5]',
5149                           self.perform_lint('{}\n'
5150                                             'WEBKIT_EXPORT\n'
5151                                             'virtual\n'
5152                                             'int\n'
5153                                             'foo() = 0;\n',
5154                                             'WebKit/chromium/public/test.h',
5155                                             webkit_export_error_rules))
5156         self.assertEqual('',
5157                           self.perform_lint('{}\n'
5158                                             'WEBKIT_EXPORT\n'
5159                                             'virtual\n'
5160                                             'int\n'
5161                                             'foo() = 0;\n',
5162                                             'test.h',
5163                                             webkit_export_error_rules))
5164
5165     def test_other(self):
5166         # FIXME: Implement this.
5167         pass
5168
5169
5170 class CppCheckerTest(unittest.TestCase):
5171
5172     """Tests CppChecker class."""
5173
5174     def mock_handle_style_error(self):
5175         pass
5176
5177     def _checker(self):
5178         return CppChecker("foo", "h", self.mock_handle_style_error, 3)
5179
5180     def test_init(self):
5181         """Test __init__ constructor."""
5182         checker = self._checker()
5183         self.assertEqual(checker.file_extension, "h")
5184         self.assertEqual(checker.file_path, "foo")
5185         self.assertEqual(checker.handle_style_error, self.mock_handle_style_error)
5186         self.assertEqual(checker.min_confidence, 3)
5187
5188     def test_eq(self):
5189         """Test __eq__ equality function."""
5190         checker1 = self._checker()
5191         checker2 = self._checker()
5192
5193         # == calls __eq__.
5194         self.assertTrue(checker1 == checker2)
5195
5196         def mock_handle_style_error2(self):
5197             pass
5198
5199         # Verify that a difference in any argument cause equality to fail.
5200         checker = CppChecker("foo", "h", self.mock_handle_style_error, 3)
5201         self.assertFalse(checker == CppChecker("bar", "h", self.mock_handle_style_error, 3))
5202         self.assertFalse(checker == CppChecker("foo", "c", self.mock_handle_style_error, 3))
5203         self.assertFalse(checker == CppChecker("foo", "h", mock_handle_style_error2, 3))
5204         self.assertFalse(checker == CppChecker("foo", "h", self.mock_handle_style_error, 4))
5205
5206     def test_ne(self):
5207         """Test __ne__ inequality function."""
5208         checker1 = self._checker()
5209         checker2 = self._checker()
5210
5211         # != calls __ne__.
5212         # By default, __ne__ always returns true on different objects.
5213         # Thus, just check the distinguishing case to verify that the
5214         # code defines __ne__.
5215         self.assertFalse(checker1 != checker2)