2011-06-22 David Levin <levin@chromium.org>
[WebKit-https.git] / Tools / Scripts / webkitpy / style / checkers / cpp_unittest.py
1 #!/usr/bin/python
2 # -*- coding: utf-8; -*-
3 #
4 # Copyright (C) 2009, 2010 Google Inc. All rights reserved.
5 # Copyright (C) 2009 Torch Mobile Inc.
6 # Copyright (C) 2009 Apple Inc. All rights reserved.
7 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
8 #
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions are
11 # met:
12 #
13 #    * Redistributions of source code must retain the above copyright
14 # notice, this list of conditions and the following disclaimer.
15 #    * Redistributions in binary form must reproduce the above
16 # copyright notice, this list of conditions and the following disclaimer
17 # in the documentation and/or other materials provided with the
18 # distribution.
19 #    * Neither the name of Google Inc. nor the names of its
20 # contributors may be used to endorse or promote products derived from
21 # this software without specific prior written permission.
22 #
23 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35 """Unit test for cpp_style.py."""
36
37 # FIXME: Add a good test that tests UpdateIncludeState.
38
39 import codecs
40 import os
41 import random
42 import re
43 import unittest
44 import cpp as cpp_style
45 from cpp import CppChecker
46 from ..filter import FilterConfiguration
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):
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         if not filter:
62             filter = FilterConfiguration()
63         self._filter = filter
64
65     def __call__(self, unused_linenum, category, confidence, message):
66         self._assert_fn(category in self._all_style_categories,
67                         'Message "%s" has category "%s",'
68                         ' which is not in STYLE_CATEGORIES' % (message, category))
69         if self._filter.should_check(category, ""):
70             self._seen_style_categories[category] = 1
71             self._errors.append('%s  [%s] [%d]' % (message, category, confidence))
72
73     def results(self):
74         if len(self._errors) < 2:
75             return ''.join(self._errors)  # Most tests expect to have a string.
76         else:
77             return self._errors  # Let's give a list if there is more than one.
78
79     def result_list(self):
80         return self._errors
81
82     def verify_all_categories_are_seen(self):
83         """Fails if there's a category in _all_style_categories - _seen_style_categories.
84
85         This should only be called after all tests are run, so
86         _seen_style_categories has had a chance to fully populate.  Since
87         this isn't called from within the normal unittest framework, we
88         can't use the normal unittest assert macros.  Instead we just exit
89         when we see an error.  Good thing this test is always run last!
90         """
91         for category in self._all_style_categories:
92             if category not in self._seen_style_categories:
93                 import sys
94                 sys.exit('FATAL ERROR: There are no tests for category "%s"' % category)
95
96
97 # This class is a lame mock of codecs. We do not verify filename, mode, or
98 # encoding, but for the current use case it is not needed.
99 class MockIo:
100     def __init__(self, mock_file):
101         self.mock_file = mock_file
102
103     def open(self, unused_filename, unused_mode, unused_encoding, _):  # NOLINT
104         # (lint doesn't like open as a method name)
105         return self.mock_file
106
107
108 class CppFunctionsTest(unittest.TestCase):
109
110     """Supports testing functions that do not need CppStyleTestBase."""
111
112     def test_convert_to_lower_with_underscores(self):
113         self.assertEquals(cpp_style._convert_to_lower_with_underscores('ABC'), 'abc')
114         self.assertEquals(cpp_style._convert_to_lower_with_underscores('aB'), 'a_b')
115         self.assertEquals(cpp_style._convert_to_lower_with_underscores('isAName'), 'is_a_name')
116         self.assertEquals(cpp_style._convert_to_lower_with_underscores('AnotherTest'), 'another_test')
117         self.assertEquals(cpp_style._convert_to_lower_with_underscores('PassRefPtr<MyClass>'), 'pass_ref_ptr<my_class>')
118         self.assertEquals(cpp_style._convert_to_lower_with_underscores('_ABC'), '_abc')
119
120     def test_create_acronym(self):
121         self.assertEquals(cpp_style._create_acronym('ABC'), 'ABC')
122         self.assertEquals(cpp_style._create_acronym('IsAName'), 'IAN')
123         self.assertEquals(cpp_style._create_acronym('PassRefPtr<MyClass>'), 'PRP<MC>')
124
125     def test_is_c_or_objective_c(self):
126         clean_lines = cpp_style.CleansedLines([''])
127         clean_objc_lines = cpp_style.CleansedLines(['#import "header.h"'])
128         self.assertTrue(cpp_style._FileState(clean_lines, 'c').is_c_or_objective_c())
129         self.assertTrue(cpp_style._FileState(clean_lines, 'm').is_c_or_objective_c())
130         self.assertFalse(cpp_style._FileState(clean_lines, 'cpp').is_c_or_objective_c())
131         self.assertFalse(cpp_style._FileState(clean_lines, 'cc').is_c_or_objective_c())
132         self.assertFalse(cpp_style._FileState(clean_lines, 'h').is_c_or_objective_c())
133         self.assertTrue(cpp_style._FileState(clean_objc_lines, 'h').is_c_or_objective_c())
134
135     def test_parameter(self):
136         # Test type.
137         parameter = cpp_style.Parameter('ExceptionCode', 13, 1)
138         self.assertEquals(parameter.type, 'ExceptionCode')
139         self.assertEquals(parameter.name, '')
140         self.assertEquals(parameter.row, 1)
141
142         # Test type and name.
143         parameter = cpp_style.Parameter('PassRefPtr<MyClass> parent', 19, 1)
144         self.assertEquals(parameter.type, 'PassRefPtr<MyClass>')
145         self.assertEquals(parameter.name, 'parent')
146         self.assertEquals(parameter.row, 1)
147
148         # Test type, no name, with default value.
149         parameter = cpp_style.Parameter('MyClass = 0', 7, 0)
150         self.assertEquals(parameter.type, 'MyClass')
151         self.assertEquals(parameter.name, '')
152         self.assertEquals(parameter.row, 0)
153
154         # Test type, name, and default value.
155         parameter = cpp_style.Parameter('MyClass a = 0', 7, 0)
156         self.assertEquals(parameter.type, 'MyClass')
157         self.assertEquals(parameter.name, 'a')
158         self.assertEquals(parameter.row, 0)
159
160     def test_single_line_view(self):
161         start_position = cpp_style.Position(row=1, column=1)
162         end_position = cpp_style.Position(row=3, column=1)
163         single_line_view = cpp_style.SingleLineView(['0', 'abcde', 'fgh', 'i'], start_position, end_position)
164         self.assertEquals(single_line_view.single_line, 'bcde fgh i')
165         self.assertEquals(single_line_view.convert_column_to_row(0), 1)
166         self.assertEquals(single_line_view.convert_column_to_row(4), 1)
167         self.assertEquals(single_line_view.convert_column_to_row(5), 2)
168         self.assertEquals(single_line_view.convert_column_to_row(8), 2)
169         self.assertEquals(single_line_view.convert_column_to_row(9), 3)
170         self.assertEquals(single_line_view.convert_column_to_row(100), 3)
171
172         start_position = cpp_style.Position(row=0, column=3)
173         end_position = cpp_style.Position(row=0, column=4)
174         single_line_view = cpp_style.SingleLineView(['abcdef'], start_position, end_position)
175         self.assertEquals(single_line_view.single_line, 'd')
176
177     def test_create_skeleton_parameters(self):
178         self.assertEquals(cpp_style.create_skeleton_parameters(''), '')
179         self.assertEquals(cpp_style.create_skeleton_parameters(' '), ' ')
180         self.assertEquals(cpp_style.create_skeleton_parameters('long'), 'long,')
181         self.assertEquals(cpp_style.create_skeleton_parameters('const unsigned long int'), '                    int,')
182         self.assertEquals(cpp_style.create_skeleton_parameters('long int*'), '     int ,')
183         self.assertEquals(cpp_style.create_skeleton_parameters('PassRefPtr<Foo> a'), 'PassRefPtr      a,')
184         self.assertEquals(cpp_style.create_skeleton_parameters(
185                 'ComplexTemplate<NestedTemplate1<MyClass1, MyClass2>, NestedTemplate1<MyClass1, MyClass2> > param, int second'),
186                           'ComplexTemplate                                                                            param, int second,')
187         self.assertEquals(cpp_style.create_skeleton_parameters('int = 0, Namespace::Type& a'), 'int    ,            Type  a,')
188         # Create skeleton parameters is a bit too aggressive with function variables, but
189         # it allows for parsing other parameters and declarations like this are rare.
190         self.assertEquals(cpp_style.create_skeleton_parameters('void (*fn)(int a, int b), Namespace::Type& a'),
191                           'void                    ,            Type  a,')
192
193         # This doesn't look like functions declarations but the simplifications help to eliminate false positives.
194         self.assertEquals(cpp_style.create_skeleton_parameters('b{d}'), 'b   ,')
195
196     def test_find_parameter_name_index(self):
197         self.assertEquals(cpp_style.find_parameter_name_index(' int a '), 5)
198         self.assertEquals(cpp_style.find_parameter_name_index(' PassRefPtr     '), 16)
199         self.assertEquals(cpp_style.find_parameter_name_index('double'), 6)
200
201     def test_parameter_list(self):
202         elided_lines = ['int blah(PassRefPtr<MyClass> paramName,',
203                         'const Other1Class& foo,',
204                         'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const * param = new ComplexTemplate<Class1, NestedTemplate<P1, P2> >(34, 42),',
205                         'int* myCount = 0);']
206         start_position = cpp_style.Position(row=0, column=8)
207         end_position = cpp_style.Position(row=3, column=16)
208
209         expected_parameters = ({'type': 'PassRefPtr<MyClass>', 'name': 'paramName', 'row': 0},
210                                {'type': 'const Other1Class&', 'name': 'foo', 'row': 1},
211                                {'type': 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const *', 'name': 'param', 'row': 2},
212                                {'type': 'int*', 'name': 'myCount', 'row': 3})
213         index = 0
214         for parameter in cpp_style.parameter_list(elided_lines, start_position, end_position):
215             expected_parameter = expected_parameters[index]
216             self.assertEquals(parameter.type, expected_parameter['type'])
217             self.assertEquals(parameter.name, expected_parameter['name'])
218             self.assertEquals(parameter.row, expected_parameter['row'])
219             index += 1
220         self.assertEquals(index, len(expected_parameters))
221
222     def test_check_parameter_against_text(self):
223         error_collector = ErrorCollector(self.assert_)
224         parameter = cpp_style.Parameter('FooF ooF', 4, 1)
225         self.assertFalse(cpp_style._check_parameter_name_against_text(parameter, 'FooF', error_collector))
226         self.assertEquals(error_collector.results(),
227                           'The parameter name "ooF" adds no information, so it should be removed.  [readability/parameter_name] [5]')
228
229 class CppStyleTestBase(unittest.TestCase):
230     """Provides some useful helper functions for cpp_style tests.
231
232     Attributes:
233       min_confidence: An integer that is the current minimum confidence
234                       level for the tests.
235
236     """
237
238     # FIXME: Refactor the unit tests so the confidence level is passed
239     #        explicitly, just like it is in the real code.
240     min_confidence = 1;
241
242     # Helper function to avoid needing to explicitly pass confidence
243     # in all the unit test calls to cpp_style.process_file_data().
244     def process_file_data(self, filename, file_extension, lines, error, unit_test_config={}):
245         """Call cpp_style.process_file_data() with the min_confidence."""
246         return cpp_style.process_file_data(filename, file_extension, lines,
247                                            error, self.min_confidence, unit_test_config)
248
249     def perform_lint(self, code, filename, basic_error_rules, unit_test_config={}):
250         error_collector = ErrorCollector(self.assert_, FilterConfiguration(basic_error_rules))
251         lines = code.split('\n')
252         extension = filename.split('.')[1]
253         self.process_file_data(filename, extension, lines, error_collector, unit_test_config)
254         return error_collector.results()
255
256     # Perform lint on single line of input and return the error message.
257     def perform_single_line_lint(self, code, filename):
258         basic_error_rules = ('-build/header_guard',
259                              '-legal/copyright',
260                              '-readability/fn_size',
261                              '-readability/parameter_name',
262                              '-readability/pass_ptr',
263                              '-whitespace/ending_newline')
264         return self.perform_lint(code, filename, basic_error_rules)
265
266     # Perform lint over multiple lines and return the error message.
267     def perform_multi_line_lint(self, code, file_extension):
268         basic_error_rules = ('-build/header_guard',
269                              '-legal/copyright',
270                              '-readability/parameter_name',
271                              '-whitespace/ending_newline')
272         return self.perform_lint(code, 'test.' + file_extension, basic_error_rules)
273
274     # Only keep some errors related to includes, namespaces and rtti.
275     def perform_language_rules_check(self, filename, code):
276         basic_error_rules = ('-',
277                              '+build/include',
278                              '+build/include_order',
279                              '+build/namespaces',
280                              '+runtime/rtti')
281         return self.perform_lint(code, filename, basic_error_rules)
282
283     # Only keep function length errors.
284     def perform_function_lengths_check(self, code):
285         basic_error_rules = ('-',
286                              '+readability/fn_size')
287         return self.perform_lint(code, 'test.cpp', basic_error_rules)
288
289     # Only keep pass ptr errors.
290     def perform_pass_ptr_check(self, code):
291         basic_error_rules = ('-',
292                              '+readability/pass_ptr')
293         return self.perform_lint(code, 'test.cpp', basic_error_rules)
294
295     # Only include what you use errors.
296     def perform_include_what_you_use(self, code, filename='foo.h', io=codecs):
297         basic_error_rules = ('-',
298                              '+build/include_what_you_use')
299         unit_test_config = {cpp_style.INCLUDE_IO_INJECTION_KEY: io}
300         return self.perform_lint(code, filename, basic_error_rules, unit_test_config)
301
302     # Perform lint and compare the error message with "expected_message".
303     def assert_lint(self, code, expected_message, file_name='foo.cpp'):
304         self.assertEquals(expected_message, self.perform_single_line_lint(code, file_name))
305
306     def assert_lint_one_of_many_errors_re(self, code, expected_message_re, file_name='foo.cpp'):
307         messages = self.perform_single_line_lint(code, file_name)
308         for message in messages:
309             if re.search(expected_message_re, message):
310                 return
311
312         self.assertEquals(expected_message_re, messages)
313
314     def assert_multi_line_lint(self, code, expected_message, file_name='foo.h'):
315         file_extension = file_name[file_name.rfind('.') + 1:]
316         self.assertEquals(expected_message, self.perform_multi_line_lint(code, file_extension))
317
318     def assert_multi_line_lint_re(self, code, expected_message_re, file_name='foo.h'):
319         file_extension = file_name[file_name.rfind('.') + 1:]
320         message = self.perform_multi_line_lint(code, file_extension)
321         if not re.search(expected_message_re, message):
322             self.fail('Message was:\n' + message + 'Expected match to "' + expected_message_re + '"')
323
324     def assert_language_rules_check(self, file_name, code, expected_message):
325         self.assertEquals(expected_message,
326                           self.perform_language_rules_check(file_name, code))
327
328     def assert_include_what_you_use(self, code, expected_message):
329         self.assertEquals(expected_message,
330                           self.perform_include_what_you_use(code))
331
332     def assert_blank_lines_check(self, lines, start_errors, end_errors):
333         error_collector = ErrorCollector(self.assert_)
334         self.process_file_data('foo.cpp', 'cpp', lines, error_collector)
335         self.assertEquals(
336             start_errors,
337             error_collector.results().count(
338                 'Blank line at the start of a code block.  Is this needed?'
339                 '  [whitespace/blank_line] [2]'))
340         self.assertEquals(
341             end_errors,
342             error_collector.results().count(
343                 'Blank line at the end of a code block.  Is this needed?'
344                 '  [whitespace/blank_line] [3]'))
345
346     def assert_positions_equal(self, position, tuple_position):
347         """Checks if the two positions are equal.
348
349         position: a cpp_style.Position object.
350         tuple_position: a tuple (row, column) to compare against."""
351         self.assertEquals(position, cpp_style.Position(tuple_position[0], tuple_position[1]),
352                           'position %s, tuple_position %s' % (position, tuple_position))
353
354
355 class FunctionDetectionTest(CppStyleTestBase):
356     def perform_function_detection(self, lines, function_information, detection_line=0):
357         clean_lines = cpp_style.CleansedLines(lines)
358         function_state = cpp_style._FunctionState(5)
359         error_collector = ErrorCollector(self.assert_)
360         cpp_style.detect_functions(clean_lines, detection_line, function_state, error_collector)
361         if not function_information:
362             self.assertEquals(function_state.in_a_function, False)
363             return
364         self.assertEquals(function_state.in_a_function, True)
365         self.assertEquals(function_state.current_function, function_information['name'] + '()')
366         self.assertEquals(function_state.modifiers_and_return_type(), function_information['modifiers_and_return_type'])
367         self.assertEquals(function_state.is_pure, function_information['is_pure'])
368         self.assertEquals(function_state.is_declaration, function_information['is_declaration'])
369         self.assert_positions_equal(function_state.function_name_start_position, function_information['function_name_start_position'])
370         self.assert_positions_equal(function_state.parameter_start_position, function_information['parameter_start_position'])
371         self.assert_positions_equal(function_state.parameter_end_position, function_information['parameter_end_position'])
372         self.assert_positions_equal(function_state.body_start_position, function_information['body_start_position'])
373         self.assert_positions_equal(function_state.end_position, function_information['end_position'])
374         expected_parameters = function_information.get('parameter_list')
375         if expected_parameters:
376             actual_parameters = function_state.parameter_list()
377             self.assertEquals(len(actual_parameters), len(expected_parameters))
378             for index in range(len(expected_parameters)):
379                 actual_parameter = actual_parameters[index]
380                 expected_parameter = expected_parameters[index]
381                 self.assertEquals(actual_parameter.type, expected_parameter['type'])
382                 self.assertEquals(actual_parameter.name, expected_parameter['name'])
383                 self.assertEquals(actual_parameter.row, expected_parameter['row'])
384
385     def test_basic_function_detection(self):
386         self.perform_function_detection(
387             ['void theTestFunctionName(int) {',
388              '}'],
389             {'name': 'theTestFunctionName',
390              'modifiers_and_return_type': 'void',
391              'function_name_start_position': (0, 5),
392              'parameter_start_position': (0, 24),
393              'parameter_end_position': (0, 29),
394              'body_start_position': (0, 30),
395              'end_position': (1, 1),
396              'is_pure': False,
397              'is_declaration': False})
398
399     def test_function_declaration_detection(self):
400         self.perform_function_detection(
401             ['void aFunctionName(int);'],
402             {'name': 'aFunctionName',
403              'modifiers_and_return_type': 'void',
404              'function_name_start_position': (0, 5),
405              'parameter_start_position': (0, 18),
406              'parameter_end_position': (0, 23),
407              'body_start_position': (0, 23),
408              'end_position': (0, 24),
409              'is_pure': False,
410              'is_declaration': True})
411
412         self.perform_function_detection(
413             ['CheckedInt<T> operator /(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
414             {'name': 'operator /',
415              'modifiers_and_return_type': 'CheckedInt<T>',
416              'function_name_start_position': (0, 14),
417              'parameter_start_position': (0, 24),
418              'parameter_end_position': (0, 76),
419              'body_start_position': (0, 76),
420              'end_position': (0, 77),
421              'is_pure': False,
422              'is_declaration': True})
423
424         self.perform_function_detection(
425             ['CheckedInt<T> operator -(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
426             {'name': 'operator -',
427              'modifiers_and_return_type': 'CheckedInt<T>',
428              'function_name_start_position': (0, 14),
429              'parameter_start_position': (0, 24),
430              'parameter_end_position': (0, 76),
431              'body_start_position': (0, 76),
432              'end_position': (0, 77),
433              'is_pure': False,
434              'is_declaration': True})
435
436         self.perform_function_detection(
437             ['CheckedInt<T> operator !=(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
438             {'name': 'operator !=',
439              'modifiers_and_return_type': 'CheckedInt<T>',
440              'function_name_start_position': (0, 14),
441              'parameter_start_position': (0, 25),
442              'parameter_end_position': (0, 77),
443              'body_start_position': (0, 77),
444              'end_position': (0, 78),
445              'is_pure': False,
446              'is_declaration': True})
447
448         self.perform_function_detection(
449             ['CheckedInt<T> operator +(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
450             {'name': 'operator +',
451              'modifiers_and_return_type': 'CheckedInt<T>',
452              'function_name_start_position': (0, 14),
453              'parameter_start_position': (0, 24),
454              'parameter_end_position': (0, 76),
455              'body_start_position': (0, 76),
456              'end_position': (0, 77),
457              'is_pure': False,
458              'is_declaration': True})
459
460     def test_pure_function_detection(self):
461         self.perform_function_detection(
462             ['virtual void theTestFunctionName(int = 0);'],
463             {'name': 'theTestFunctionName',
464              'modifiers_and_return_type': 'virtual void',
465              'function_name_start_position': (0, 13),
466              'parameter_start_position': (0, 32),
467              'parameter_end_position': (0, 41),
468              'body_start_position': (0, 41),
469              'end_position': (0, 42),
470              'is_pure': False,
471              'is_declaration': True})
472
473         self.perform_function_detection(
474             ['virtual void theTestFunctionName(int) = 0;'],
475             {'name': 'theTestFunctionName',
476              'modifiers_and_return_type': 'virtual void',
477              'function_name_start_position': (0, 13),
478              'parameter_start_position': (0, 32),
479              'parameter_end_position': (0, 37),
480              'body_start_position': (0, 41),
481              'end_position': (0, 42),
482              'is_pure': True,
483              'is_declaration': True})
484
485         # Hopefully, no one writes code like this but it is a tricky case.
486         self.perform_function_detection(
487             ['virtual void theTestFunctionName(int)',
488              ' = ',
489              ' 0 ;'],
490             {'name': 'theTestFunctionName',
491              'modifiers_and_return_type': 'virtual void',
492              'function_name_start_position': (0, 13),
493              'parameter_start_position': (0, 32),
494              'parameter_end_position': (0, 37),
495              'body_start_position': (2, 3),
496              'end_position': (2, 4),
497              'is_pure': True,
498              'is_declaration': True})
499
500     def test_ignore_macros(self):
501         self.perform_function_detection(['void aFunctionName(int); \\'], None)
502
503     def test_non_functions(self):
504         # This case exposed an error because the open brace was in quotes.
505         self.perform_function_detection(
506             ['asm(',
507              '    "stmdb sp!, {r1-r3}" "\n"',
508              ');'],
509             # This isn't a function but it looks like one to our simple
510             # algorithm and that is ok.
511             {'name': 'asm',
512              'modifiers_and_return_type': '',
513              'function_name_start_position': (0, 0),
514              'parameter_start_position': (0, 3),
515              'parameter_end_position': (2, 1),
516              'body_start_position': (2, 1),
517              'end_position': (2, 2),
518              'is_pure': False,
519              'is_declaration': True})
520
521         # Simple test case with something that is not a function.
522         self.perform_function_detection(['class Stuff;'], None)
523
524     def test_parameter_list(self):
525         # A function with no arguments.
526         function_state = self.perform_function_detection(
527             ['void functionName();'],
528             {'name': 'functionName',
529              'modifiers_and_return_type': 'void',
530              'function_name_start_position': (0, 5),
531              'parameter_start_position': (0, 17),
532              'parameter_end_position': (0, 19),
533              'body_start_position': (0, 19),
534              'end_position': (0, 20),
535              'is_pure': False,
536              'is_declaration': True,
537              'parameter_list': ()})
538
539         # A function with one argument.
540         function_state = self.perform_function_detection(
541             ['void functionName(int);'],
542             {'name': 'functionName',
543              'modifiers_and_return_type': 'void',
544              'function_name_start_position': (0, 5),
545              'parameter_start_position': (0, 17),
546              'parameter_end_position': (0, 22),
547              'body_start_position': (0, 22),
548              'end_position': (0, 23),
549              'is_pure': False,
550              'is_declaration': True,
551              'parameter_list':
552                  ({'type': 'int', 'name': '', 'row': 0},)})
553
554         # A function with unsigned and short arguments
555         function_state = self.perform_function_detection(
556             ['void functionName(unsigned a, short b, long c, long long short unsigned int);'],
557             {'name': 'functionName',
558              'modifiers_and_return_type': 'void',
559              'function_name_start_position': (0, 5),
560              'parameter_start_position': (0, 17),
561              'parameter_end_position': (0, 76),
562              'body_start_position': (0, 76),
563              'end_position': (0, 77),
564              'is_pure': False,
565              'is_declaration': True,
566              'parameter_list':
567                  ({'type': 'unsigned', 'name': 'a', 'row': 0},
568                   {'type': 'short', 'name': 'b', 'row': 0},
569                   {'type': 'long', 'name': 'c', 'row': 0},
570                   {'type': 'long long short unsigned int', 'name': '', 'row': 0})})
571
572         # Some parameter type with modifiers and no parameter names.
573         function_state = self.perform_function_detection(
574             ['virtual void determineARIADropEffects(Vector<String>*&, const unsigned long int*&, const MediaPlayer::Preload, Other<Other2, Other3<P1, P2> >, int);'],
575             {'name': 'determineARIADropEffects',
576              'modifiers_and_return_type': 'virtual void',
577              'parameter_start_position': (0, 37),
578              'function_name_start_position': (0, 13),
579              'parameter_end_position': (0, 147),
580              'body_start_position': (0, 147),
581              'end_position': (0, 148),
582              'is_pure': False,
583              'is_declaration': True,
584              'parameter_list':
585                  ({'type': 'Vector<String>*&', 'name': '', 'row': 0},
586                   {'type': 'const unsigned long int*&', 'name': '', 'row': 0},
587                   {'type': 'const MediaPlayer::Preload', 'name': '', 'row': 0},
588                   {'type': 'Other<Other2, Other3<P1, P2> >', 'name': '', 'row': 0},
589                   {'type': 'int', 'name': '', 'row': 0})})
590
591         # Try parsing a function with a very complex definition.
592         function_state = self.perform_function_detection(
593             ['#define MyMacro(a) a',
594              'virtual',
595              'AnotherTemplate<Class1, Class2> aFunctionName(PassRefPtr<MyClass> paramName,',
596              'const Other1Class& foo,',
597              'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const * param = new ComplexTemplate<Class1, NestedTemplate<P1, P2> >(34, 42),',
598              'int* myCount = 0);'],
599             {'name': 'aFunctionName',
600              'modifiers_and_return_type': 'virtual AnotherTemplate<Class1, Class2>',
601              'function_name_start_position': (2, 32),
602              'parameter_start_position': (2, 45),
603              'parameter_end_position': (5, 17),
604              'body_start_position': (5, 17),
605              'end_position': (5, 18),
606              'is_pure': False,
607              'is_declaration': True,
608              'parameter_list':
609                  ({'type': 'PassRefPtr<MyClass>', 'name': 'paramName', 'row': 2},
610                   {'type': 'const Other1Class&', 'name': 'foo', 'row': 3},
611                   {'type': 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const *', 'name': 'param', 'row': 4},
612                   {'type': 'int*', 'name': 'myCount', 'row': 5})},
613             detection_line=2)
614
615
616 class CppStyleTest(CppStyleTestBase):
617
618     # Test get line width.
619     def test_get_line_width(self):
620         self.assertEquals(0, cpp_style.get_line_width(''))
621         self.assertEquals(10, cpp_style.get_line_width(u'x' * 10))
622         self.assertEquals(16, cpp_style.get_line_width(u'都|道|府|県|支庁'))
623
624     def test_find_next_multi_line_comment_start(self):
625         self.assertEquals(1, cpp_style.find_next_multi_line_comment_start([''], 0))
626
627         lines = ['a', 'b', '/* c']
628         self.assertEquals(2, cpp_style.find_next_multi_line_comment_start(lines, 0))
629
630         lines = ['char a[] = "/*";']  # not recognized as comment.
631         self.assertEquals(1, cpp_style.find_next_multi_line_comment_start(lines, 0))
632
633     def test_find_next_multi_line_comment_end(self):
634         self.assertEquals(1, cpp_style.find_next_multi_line_comment_end([''], 0))
635         lines = ['a', 'b', ' c */']
636         self.assertEquals(2, cpp_style.find_next_multi_line_comment_end(lines, 0))
637
638     def test_remove_multi_line_comments_from_range(self):
639         lines = ['a', '  /* comment ', ' * still comment', ' comment */   ', 'b']
640         cpp_style.remove_multi_line_comments_from_range(lines, 1, 4)
641         self.assertEquals(['a', '// dummy', '// dummy', '// dummy', 'b'], lines)
642
643     def test_position(self):
644         position = cpp_style.Position(3, 4)
645         self.assert_positions_equal(position, (3, 4))
646         self.assertEquals(position.row, 3)
647         self.assertTrue(position > cpp_style.Position(position.row - 1, position.column + 1))
648         self.assertTrue(position > cpp_style.Position(position.row, position.column - 1))
649         self.assertTrue(position < cpp_style.Position(position.row, position.column + 1))
650         self.assertTrue(position < cpp_style.Position(position.row + 1, position.column - 1))
651         self.assertEquals(position.__str__(), '(3, 4)')
652
653     def test_rfind_in_lines(self):
654         not_found_position = cpp_style.Position(10, 11)
655         start_position = cpp_style.Position(2, 2)
656         lines = ['ab', 'ace', 'test']
657         self.assertEquals(not_found_position, cpp_style._rfind_in_lines('st', lines, start_position, not_found_position))
658         self.assertTrue(cpp_style.Position(1, 1) == cpp_style._rfind_in_lines('a', lines, start_position, not_found_position))
659         self.assertEquals(cpp_style.Position(2, 2), cpp_style._rfind_in_lines('(te|a)', lines, start_position, not_found_position))
660
661     def test_close_expression(self):
662         self.assertEquals(cpp_style.Position(1, -1), cpp_style.close_expression([')('], cpp_style.Position(0, 1)))
663         self.assertEquals(cpp_style.Position(1, -1), cpp_style.close_expression([') ()'], cpp_style.Position(0, 1)))
664         self.assertEquals(cpp_style.Position(0, 4), cpp_style.close_expression([')[)]'], cpp_style.Position(0, 1)))
665         self.assertEquals(cpp_style.Position(0, 5), cpp_style.close_expression(['}{}{}'], cpp_style.Position(0, 3)))
666         self.assertEquals(cpp_style.Position(1, 1), cpp_style.close_expression(['}{}{', '}'], cpp_style.Position(0, 3)))
667         self.assertEquals(cpp_style.Position(2, -1), cpp_style.close_expression(['][][', ' '], cpp_style.Position(0, 3)))
668
669     def test_spaces_at_end_of_line(self):
670         self.assert_lint(
671             '// Hello there ',
672             'Line ends in whitespace.  Consider deleting these extra spaces.'
673             '  [whitespace/end_of_line] [4]')
674
675     # Test C-style cast cases.
676     def test_cstyle_cast(self):
677         self.assert_lint(
678             'int a = (int)1.0;',
679             'Using C-style cast.  Use static_cast<int>(...) instead'
680             '  [readability/casting] [4]')
681         self.assert_lint(
682             'int *a = (int *)DEFINED_VALUE;',
683             'Using C-style cast.  Use reinterpret_cast<int *>(...) instead'
684             '  [readability/casting] [4]', 'foo.c')
685         self.assert_lint(
686             'uint16 a = (uint16)1.0;',
687             'Using C-style cast.  Use static_cast<uint16>(...) instead'
688             '  [readability/casting] [4]')
689         self.assert_lint(
690             'int32 a = (int32)1.0;',
691             'Using C-style cast.  Use static_cast<int32>(...) instead'
692             '  [readability/casting] [4]')
693         self.assert_lint(
694             'uint64 a = (uint64)1.0;',
695             'Using C-style cast.  Use static_cast<uint64>(...) instead'
696             '  [readability/casting] [4]')
697
698     # Test taking address of casts (runtime/casting)
699     def test_runtime_casting(self):
700         self.assert_lint(
701             'int* x = &static_cast<int*>(foo);',
702             'Are you taking an address of a cast?  '
703             'This is dangerous: could be a temp var.  '
704             'Take the address before doing the cast, rather than after'
705             '  [runtime/casting] [4]')
706
707         self.assert_lint(
708             'int* x = &dynamic_cast<int *>(foo);',
709             ['Are you taking an address of a cast?  '
710              'This is dangerous: could be a temp var.  '
711              'Take the address before doing the cast, rather than after'
712              '  [runtime/casting] [4]',
713              'Do not use dynamic_cast<>.  If you need to cast within a class '
714              'hierarchy, use static_cast<> to upcast.  Google doesn\'t support '
715              'RTTI.  [runtime/rtti] [5]'])
716
717         self.assert_lint(
718             'int* x = &reinterpret_cast<int *>(foo);',
719             'Are you taking an address of a cast?  '
720             'This is dangerous: could be a temp var.  '
721             'Take the address before doing the cast, rather than after'
722             '  [runtime/casting] [4]')
723
724         # It's OK to cast an address.
725         self.assert_lint(
726             'int* x = reinterpret_cast<int *>(&foo);',
727             '')
728
729     def test_runtime_selfinit(self):
730         self.assert_lint(
731             'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }',
732             'You seem to be initializing a member variable with itself.'
733             '  [runtime/init] [4]')
734         self.assert_lint(
735             'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }',
736             '')
737         self.assert_lint(
738             'Foo::Foo(Bar r) : r_(r), l_(r_), ll_(l_) { }',
739             '')
740
741     def test_runtime_rtti(self):
742         statement = 'int* x = dynamic_cast<int*>(&foo);'
743         error_message = (
744             'Do not use dynamic_cast<>.  If you need to cast within a class '
745             'hierarchy, use static_cast<> to upcast.  Google doesn\'t support '
746             'RTTI.  [runtime/rtti] [5]')
747         # dynamic_cast is disallowed in most files.
748         self.assert_language_rules_check('foo.cpp', statement, error_message)
749         self.assert_language_rules_check('foo.h', statement, error_message)
750
751     # We cannot test this functionality because of difference of
752     # function definitions.  Anyway, we may never enable this.
753     #
754     # # Test for unnamed arguments in a method.
755     # def test_check_for_unnamed_params(self):
756     #   message = ('All parameters should be named in a function'
757     #              '  [readability/function] [3]')
758     #   self.assert_lint('virtual void A(int*) const;', message)
759     #   self.assert_lint('virtual void B(void (*fn)(int*));', message)
760     #   self.assert_lint('virtual void C(int*);', message)
761     #   self.assert_lint('void *(*f)(void *) = x;', message)
762     #   self.assert_lint('void Method(char*) {', message)
763     #   self.assert_lint('void Method(char*);', message)
764     #   self.assert_lint('void Method(char* /*x*/);', message)
765     #   self.assert_lint('typedef void (*Method)(int32);', message)
766     #   self.assert_lint('static void operator delete[](void*) throw();', message)
767     # 
768     #   self.assert_lint('virtual void D(int* p);', '')
769     #   self.assert_lint('void operator delete(void* x) throw();', '')
770     #   self.assert_lint('void Method(char* x)\n{', '')
771     #   self.assert_lint('void Method(char* /*x*/)\n{', '')
772     #   self.assert_lint('void Method(char* x);', '')
773     #   self.assert_lint('typedef void (*Method)(int32 x);', '')
774     #   self.assert_lint('static void operator delete[](void* x) throw();', '')
775     #   self.assert_lint('static void operator delete[](void* /*x*/) throw();', '')
776     # 
777     #   # This one should technically warn, but doesn't because the function
778     #   # pointer is confusing.
779     #   self.assert_lint('virtual void E(void (*fn)(int* p));', '')
780
781     # Test deprecated casts such as int(d)
782     def test_deprecated_cast(self):
783         self.assert_lint(
784             'int a = int(2.2);',
785             'Using deprecated casting style.  '
786             'Use static_cast<int>(...) instead'
787             '  [readability/casting] [4]')
788         # Checks for false positives...
789         self.assert_lint(
790             'int a = int(); // Constructor, o.k.',
791             '')
792         self.assert_lint(
793             'X::X() : a(int()) { } // default Constructor, o.k.',
794             '')
795         self.assert_lint(
796             'operator bool(); // Conversion operator, o.k.',
797             '')
798
799     # The second parameter to a gMock method definition is a function signature
800     # that often looks like a bad cast but should not picked up by lint.
801     def test_mock_method(self):
802         self.assert_lint(
803             'MOCK_METHOD0(method, int());',
804             '')
805         self.assert_lint(
806             'MOCK_CONST_METHOD1(method, float(string));',
807             '')
808         self.assert_lint(
809             'MOCK_CONST_METHOD2_T(method, double(float, float));',
810             '')
811
812     # Test sizeof(type) cases.
813     def test_sizeof_type(self):
814         self.assert_lint(
815             'sizeof(int);',
816             'Using sizeof(type).  Use sizeof(varname) instead if possible'
817             '  [runtime/sizeof] [1]')
818         self.assert_lint(
819             'sizeof(int *);',
820             'Using sizeof(type).  Use sizeof(varname) instead if possible'
821             '  [runtime/sizeof] [1]')
822
823     # Test typedef cases.  There was a bug that cpp_style misidentified
824     # typedef for pointer to function as C-style cast and produced
825     # false-positive error messages.
826     def test_typedef_for_pointer_to_function(self):
827         self.assert_lint(
828             'typedef void (*Func)(int x);',
829             '')
830         self.assert_lint(
831             'typedef void (*Func)(int *x);',
832             '')
833         self.assert_lint(
834             'typedef void Func(int x);',
835             '')
836         self.assert_lint(
837             'typedef void Func(int *x);',
838             '')
839
840     def test_include_what_you_use_no_implementation_files(self):
841         code = 'std::vector<int> foo;'
842         self.assertEquals('Add #include <vector> for vector<>'
843                           '  [build/include_what_you_use] [4]',
844                           self.perform_include_what_you_use(code, 'foo.h'))
845         self.assertEquals('',
846                           self.perform_include_what_you_use(code, 'foo.cpp'))
847
848     def test_include_what_you_use(self):
849         self.assert_include_what_you_use(
850             '''#include <vector>
851                std::vector<int> foo;
852             ''',
853             '')
854         self.assert_include_what_you_use(
855             '''#include <map>
856                std::pair<int,int> foo;
857             ''',
858             '')
859         self.assert_include_what_you_use(
860             '''#include <multimap>
861                std::pair<int,int> foo;
862             ''',
863             '')
864         self.assert_include_what_you_use(
865             '''#include <hash_map>
866                std::pair<int,int> foo;
867             ''',
868             '')
869         self.assert_include_what_you_use(
870             '''#include <utility>
871                std::pair<int,int> foo;
872             ''',
873             '')
874         self.assert_include_what_you_use(
875             '''#include <vector>
876                DECLARE_string(foobar);
877             ''',
878             '')
879         self.assert_include_what_you_use(
880             '''#include <vector>
881                DEFINE_string(foobar, "", "");
882             ''',
883             '')
884         self.assert_include_what_you_use(
885             '''#include <vector>
886                std::pair<int,int> foo;
887             ''',
888             'Add #include <utility> for pair<>'
889             '  [build/include_what_you_use] [4]')
890         self.assert_include_what_you_use(
891             '''#include "base/foobar.h"
892                std::vector<int> foo;
893             ''',
894             'Add #include <vector> for vector<>'
895             '  [build/include_what_you_use] [4]')
896         self.assert_include_what_you_use(
897             '''#include <vector>
898                std::set<int> foo;
899             ''',
900             'Add #include <set> for set<>'
901             '  [build/include_what_you_use] [4]')
902         self.assert_include_what_you_use(
903             '''#include "base/foobar.h"
904               hash_map<int, int> foobar;
905             ''',
906             'Add #include <hash_map> for hash_map<>'
907             '  [build/include_what_you_use] [4]')
908         self.assert_include_what_you_use(
909             '''#include "base/foobar.h"
910                bool foobar = std::less<int>(0,1);
911             ''',
912             'Add #include <functional> for less<>'
913             '  [build/include_what_you_use] [4]')
914         self.assert_include_what_you_use(
915             '''#include "base/foobar.h"
916                bool foobar = min<int>(0,1);
917             ''',
918             'Add #include <algorithm> for min  [build/include_what_you_use] [4]')
919         self.assert_include_what_you_use(
920             'void a(const string &foobar);',
921             'Add #include <string> for string  [build/include_what_you_use] [4]')
922         self.assert_include_what_you_use(
923             '''#include "base/foobar.h"
924                bool foobar = swap(0,1);
925             ''',
926             'Add #include <algorithm> for swap  [build/include_what_you_use] [4]')
927         self.assert_include_what_you_use(
928             '''#include "base/foobar.h"
929                bool foobar = transform(a.begin(), a.end(), b.start(), Foo);
930             ''',
931             'Add #include <algorithm> for transform  '
932             '[build/include_what_you_use] [4]')
933         self.assert_include_what_you_use(
934             '''#include "base/foobar.h"
935                bool foobar = min_element(a.begin(), a.end());
936             ''',
937             'Add #include <algorithm> for min_element  '
938             '[build/include_what_you_use] [4]')
939         self.assert_include_what_you_use(
940             '''foo->swap(0,1);
941                foo.swap(0,1);
942             ''',
943             '')
944         self.assert_include_what_you_use(
945             '''#include <string>
946                void a(const std::multimap<int,string> &foobar);
947             ''',
948             'Add #include <map> for multimap<>'
949             '  [build/include_what_you_use] [4]')
950         self.assert_include_what_you_use(
951             '''#include <queue>
952                void a(const std::priority_queue<int> &foobar);
953             ''',
954             '')
955         self.assert_include_what_you_use(
956              '''#include "base/basictypes.h"
957                 #include "base/port.h"
958                 #include <assert.h>
959                 #include <string>
960                 #include <vector>
961                 vector<string> hajoa;''', '')
962         self.assert_include_what_you_use(
963             '''#include <string>
964                int i = numeric_limits<int>::max()
965             ''',
966             'Add #include <limits> for numeric_limits<>'
967             '  [build/include_what_you_use] [4]')
968         self.assert_include_what_you_use(
969             '''#include <limits>
970                int i = numeric_limits<int>::max()
971             ''',
972             '')
973
974         # Test the UpdateIncludeState code path.
975         mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"']
976         message = self.perform_include_what_you_use(
977             '#include "config.h"\n'
978             '#include "blah/a.h"\n',
979             filename='blah/a.cpp',
980             io=MockIo(mock_header_contents))
981         self.assertEquals(message, '')
982
983         mock_header_contents = ['#include <set>']
984         message = self.perform_include_what_you_use(
985             '''#include "config.h"
986                #include "blah/a.h"
987
988                std::set<int> foo;''',
989             filename='blah/a.cpp',
990             io=MockIo(mock_header_contents))
991         self.assertEquals(message, '')
992
993         # If there's just a .cpp and the header can't be found then it's ok.
994         message = self.perform_include_what_you_use(
995             '''#include "config.h"
996                #include "blah/a.h"
997
998                std::set<int> foo;''',
999             filename='blah/a.cpp')
1000         self.assertEquals(message, '')
1001
1002         # Make sure we find the headers with relative paths.
1003         mock_header_contents = ['']
1004         message = self.perform_include_what_you_use(
1005             '''#include "config.h"
1006                #include "%s%sa.h"
1007
1008                std::set<int> foo;''' % (os.path.basename(os.getcwd()), os.path.sep),
1009             filename='a.cpp',
1010             io=MockIo(mock_header_contents))
1011         self.assertEquals(message, 'Add #include <set> for set<>  '
1012                                    '[build/include_what_you_use] [4]')
1013
1014     def test_files_belong_to_same_module(self):
1015         f = cpp_style.files_belong_to_same_module
1016         self.assertEquals((True, ''), f('a.cpp', 'a.h'))
1017         self.assertEquals((True, ''), f('base/google.cpp', 'base/google.h'))
1018         self.assertEquals((True, ''), f('base/google_test.cpp', 'base/google.h'))
1019         self.assertEquals((True, ''),
1020                           f('base/google_unittest.cpp', 'base/google.h'))
1021         self.assertEquals((True, ''),
1022                           f('base/internal/google_unittest.cpp',
1023                             'base/public/google.h'))
1024         self.assertEquals((True, 'xxx/yyy/'),
1025                           f('xxx/yyy/base/internal/google_unittest.cpp',
1026                             'base/public/google.h'))
1027         self.assertEquals((True, 'xxx/yyy/'),
1028                           f('xxx/yyy/base/google_unittest.cpp',
1029                             'base/public/google.h'))
1030         self.assertEquals((True, ''),
1031                           f('base/google_unittest.cpp', 'base/google-inl.h'))
1032         self.assertEquals((True, '/home/build/google3/'),
1033                           f('/home/build/google3/base/google.cpp', 'base/google.h'))
1034
1035         self.assertEquals((False, ''),
1036                           f('/home/build/google3/base/google.cpp', 'basu/google.h'))
1037         self.assertEquals((False, ''), f('a.cpp', 'b.h'))
1038
1039     def test_cleanse_line(self):
1040         self.assertEquals('int foo = 0;  ',
1041                           cpp_style.cleanse_comments('int foo = 0;  // danger!'))
1042         self.assertEquals('int o = 0;',
1043                           cpp_style.cleanse_comments('int /* foo */ o = 0;'))
1044         self.assertEquals('foo(int a, int b);',
1045                           cpp_style.cleanse_comments('foo(int a /* abc */, int b);'))
1046         self.assertEqual('f(a, b);',
1047                          cpp_style.cleanse_comments('f(a, /* name */ b);'))
1048         self.assertEqual('f(a, b);',
1049                          cpp_style.cleanse_comments('f(a /* name */, b);'))
1050         self.assertEqual('f(a, b);',
1051                          cpp_style.cleanse_comments('f(a, /* name */b);'))
1052
1053     def test_multi_line_comments(self):
1054         # missing explicit is bad
1055         self.assert_multi_line_lint(
1056             r'''int a = 0;
1057                 /* multi-liner
1058                 class Foo {
1059                 Foo(int f);  // should cause a lint warning in code
1060                 }
1061             */ ''',
1062         '')
1063         self.assert_multi_line_lint(
1064             r'''/* int a = 0; multi-liner
1065             static const int b = 0;''',
1066             ['Could not find end of multi-line comment'
1067              '  [readability/multiline_comment] [5]',
1068              'Complex multi-line /*...*/-style comment found. '
1069              'Lint may give bogus warnings.  Consider replacing these with '
1070              '//-style comments, with #if 0...#endif, or with more clearly '
1071              'structured multi-line comments.  [readability/multiline_comment] [5]'])
1072         self.assert_multi_line_lint(r'''    /* multi-line comment''',
1073                                     ['Could not find end of multi-line comment'
1074                                      '  [readability/multiline_comment] [5]',
1075                                      'Complex multi-line /*...*/-style comment found. '
1076                                      'Lint may give bogus warnings.  Consider replacing these with '
1077                                      '//-style comments, with #if 0...#endif, or with more clearly '
1078                                      'structured multi-line comments.  [readability/multiline_comment] [5]'])
1079         self.assert_multi_line_lint(r'''    // /* comment, but not multi-line''', '')
1080
1081     def test_multiline_strings(self):
1082         multiline_string_error_message = (
1083             'Multi-line string ("...") found.  This lint script doesn\'t '
1084             'do well with such strings, and may give bogus warnings.  They\'re '
1085             'ugly and unnecessary, and you should use concatenation instead".'
1086             '  [readability/multiline_string] [5]')
1087
1088         file_path = 'mydir/foo.cpp'
1089
1090         error_collector = ErrorCollector(self.assert_)
1091         self.process_file_data(file_path, 'cpp',
1092                                ['const char* str = "This is a\\',
1093                                 ' multiline string.";'],
1094                                error_collector)
1095         self.assertEquals(
1096             2,  # One per line.
1097             error_collector.result_list().count(multiline_string_error_message))
1098
1099     # Test non-explicit single-argument constructors
1100     def test_explicit_single_argument_constructors(self):
1101         # missing explicit is bad
1102         self.assert_multi_line_lint(
1103             '''class Foo {
1104                  Foo(int f);
1105                };''',
1106             'Single-argument constructors should be marked explicit.'
1107             '  [runtime/explicit] [5]')
1108         # missing explicit is bad, even with whitespace
1109         self.assert_multi_line_lint(
1110             '''class Foo {
1111                  Foo (int f);
1112                };''',
1113             ['Extra space before ( in function call  [whitespace/parens] [4]',
1114              'Single-argument constructors should be marked explicit.'
1115              '  [runtime/explicit] [5]'])
1116         # missing explicit, with distracting comment, is still bad
1117         self.assert_multi_line_lint(
1118             '''class Foo {
1119                  Foo(int f); // simpler than Foo(blargh, blarg)
1120                };''',
1121             'Single-argument constructors should be marked explicit.'
1122             '  [runtime/explicit] [5]')
1123         # missing explicit, with qualified classname
1124         self.assert_multi_line_lint(
1125             '''class Qualifier::AnotherOne::Foo {
1126                  Foo(int f);
1127                };''',
1128             'Single-argument constructors should be marked explicit.'
1129             '  [runtime/explicit] [5]')
1130         # structs are caught as well.
1131         self.assert_multi_line_lint(
1132             '''struct Foo {
1133                  Foo(int f);
1134                };''',
1135             'Single-argument constructors should be marked explicit.'
1136             '  [runtime/explicit] [5]')
1137         # Templatized classes are caught as well.
1138         self.assert_multi_line_lint(
1139             '''template<typename T> class Foo {
1140                  Foo(int f);
1141                };''',
1142             'Single-argument constructors should be marked explicit.'
1143             '  [runtime/explicit] [5]')
1144         # proper style is okay
1145         self.assert_multi_line_lint(
1146             '''class Foo {
1147                  explicit Foo(int f);
1148                };''',
1149             '')
1150         # two argument constructor is okay
1151         self.assert_multi_line_lint(
1152             '''class Foo {
1153                  Foo(int f, int b);
1154                };''',
1155             '')
1156         # two argument constructor, across two lines, is okay
1157         self.assert_multi_line_lint(
1158             '''class Foo {
1159                  Foo(int f,
1160                      int b);
1161                };''',
1162             '')
1163         # non-constructor (but similar name), is okay
1164         self.assert_multi_line_lint(
1165             '''class Foo {
1166                  aFoo(int f);
1167                };''',
1168             '')
1169         # constructor with void argument is okay
1170         self.assert_multi_line_lint(
1171             '''class Foo {
1172                  Foo(void);
1173                };''',
1174             '')
1175         # single argument method is okay
1176         self.assert_multi_line_lint(
1177             '''class Foo {
1178                  Bar(int b);
1179                };''',
1180             '')
1181         # comments should be ignored
1182         self.assert_multi_line_lint(
1183             '''class Foo {
1184                // Foo(int f);
1185                };''',
1186             '')
1187         # single argument function following class definition is okay
1188         # (okay, it's not actually valid, but we don't want a false positive)
1189         self.assert_multi_line_lint(
1190             '''class Foo {
1191                  Foo(int f, int b);
1192                };
1193                Foo(int f);''',
1194             '')
1195         # single argument function is okay
1196         self.assert_multi_line_lint(
1197             '''static Foo(int f);''',
1198             '')
1199         # single argument copy constructor is okay.
1200         self.assert_multi_line_lint(
1201             '''class Foo {
1202                  Foo(const Foo&);
1203                };''',
1204             '')
1205         self.assert_multi_line_lint(
1206             '''class Foo {
1207                  Foo(Foo&);
1208                };''',
1209             '')
1210
1211     def test_slash_star_comment_on_single_line(self):
1212         self.assert_multi_line_lint(
1213             '''/* static */ Foo(int f);''',
1214             '')
1215         self.assert_multi_line_lint(
1216             '''/*/ static */  Foo(int f);''',
1217             '')
1218         self.assert_multi_line_lint(
1219             '''/*/ static Foo(int f);''',
1220             'Could not find end of multi-line comment'
1221             '  [readability/multiline_comment] [5]')
1222         self.assert_multi_line_lint(
1223             '''    /*/ static Foo(int f);''',
1224             'Could not find end of multi-line comment'
1225             '  [readability/multiline_comment] [5]')
1226         self.assert_multi_line_lint(
1227             '''    /**/ static Foo(int f);''',
1228             '')
1229
1230     # Test suspicious usage of "if" like this:
1231     # if (a == b) {
1232     #   DoSomething();
1233     # } if (a == c) {   // Should be "else if".
1234     #   DoSomething();  // This gets called twice if a == b && a == c.
1235     # }
1236     def test_suspicious_usage_of_if(self):
1237         self.assert_lint(
1238             '    if (a == b) {',
1239             '')
1240         self.assert_lint(
1241             '    } if (a == b) {',
1242             'Did you mean "else if"? If not, start a new line for "if".'
1243             '  [readability/braces] [4]')
1244
1245     # Test suspicious usage of memset. Specifically, a 0
1246     # as the final argument is almost certainly an error.
1247     def test_suspicious_usage_of_memset(self):
1248         # Normal use is okay.
1249         self.assert_lint(
1250             '    memset(buf, 0, sizeof(buf))',
1251             '')
1252
1253         # A 0 as the final argument is almost certainly an error.
1254         self.assert_lint(
1255             '    memset(buf, sizeof(buf), 0)',
1256             'Did you mean "memset(buf, 0, sizeof(buf))"?'
1257             '  [runtime/memset] [4]')
1258         self.assert_lint(
1259             '    memset(buf, xsize * ysize, 0)',
1260             'Did you mean "memset(buf, 0, xsize * ysize)"?'
1261             '  [runtime/memset] [4]')
1262
1263         # There is legitimate test code that uses this form.
1264         # This is okay since the second argument is a literal.
1265         self.assert_lint(
1266             "    memset(buf, 'y', 0)",
1267             '')
1268         self.assert_lint(
1269             '    memset(buf, 4, 0)',
1270             '')
1271         self.assert_lint(
1272             '    memset(buf, -1, 0)',
1273             '')
1274         self.assert_lint(
1275             '    memset(buf, 0xF1, 0)',
1276             '')
1277         self.assert_lint(
1278             '    memset(buf, 0xcd, 0)',
1279             '')
1280
1281     def test_check_posix_threading(self):
1282         self.assert_lint('sctime_r()', '')
1283         self.assert_lint('strtok_r()', '')
1284         self.assert_lint('    strtok_r(foo, ba, r)', '')
1285         self.assert_lint('brand()', '')
1286         self.assert_lint('_rand()', '')
1287         self.assert_lint('.rand()', '')
1288         self.assert_lint('>rand()', '')
1289         self.assert_lint('rand()',
1290                          'Consider using rand_r(...) instead of rand(...)'
1291                          ' for improved thread safety.'
1292                          '  [runtime/threadsafe_fn] [2]')
1293         self.assert_lint('strtok()',
1294                          'Consider using strtok_r(...) '
1295                          'instead of strtok(...)'
1296                          ' for improved thread safety.'
1297                          '  [runtime/threadsafe_fn] [2]')
1298
1299     # Test potential format string bugs like printf(foo).
1300     def test_format_strings(self):
1301         self.assert_lint('printf("foo")', '')
1302         self.assert_lint('printf("foo: %s", foo)', '')
1303         self.assert_lint('DocidForPrintf(docid)', '')  # Should not trigger.
1304         self.assert_lint(
1305             'printf(foo)',
1306             'Potential format string bug. Do printf("%s", foo) instead.'
1307             '  [runtime/printf] [4]')
1308         self.assert_lint(
1309             'printf(foo.c_str())',
1310             'Potential format string bug. '
1311             'Do printf("%s", foo.c_str()) instead.'
1312             '  [runtime/printf] [4]')
1313         self.assert_lint(
1314             'printf(foo->c_str())',
1315             'Potential format string bug. '
1316             'Do printf("%s", foo->c_str()) instead.'
1317             '  [runtime/printf] [4]')
1318         self.assert_lint(
1319             'StringPrintf(foo)',
1320             'Potential format string bug. Do StringPrintf("%s", foo) instead.'
1321             ''
1322             '  [runtime/printf] [4]')
1323
1324     # Variable-length arrays are not permitted.
1325     def test_variable_length_array_detection(self):
1326         errmsg = ('Do not use variable-length arrays.  Use an appropriately named '
1327                   "('k' followed by CamelCase) compile-time constant for the size."
1328                   '  [runtime/arrays] [1]')
1329
1330         self.assert_lint('int a[any_old_variable];', errmsg)
1331         self.assert_lint('int doublesize[some_var * 2];', errmsg)
1332         self.assert_lint('int a[afunction()];', errmsg)
1333         self.assert_lint('int a[function(kMaxFooBars)];', errmsg)
1334         self.assert_lint('bool aList[items_->size()];', errmsg)
1335         self.assert_lint('namespace::Type buffer[len+1];', errmsg)
1336
1337         self.assert_lint('int a[64];', '')
1338         self.assert_lint('int a[0xFF];', '')
1339         self.assert_lint('int first[256], second[256];', '')
1340         self.assert_lint('int arrayName[kCompileTimeConstant];', '')
1341         self.assert_lint('char buf[somenamespace::kBufSize];', '')
1342         self.assert_lint('int arrayName[ALL_CAPS];', '')
1343         self.assert_lint('AClass array1[foo::bar::ALL_CAPS];', '')
1344         self.assert_lint('int a[kMaxStrLen + 1];', '')
1345         self.assert_lint('int a[sizeof(foo)];', '')
1346         self.assert_lint('int a[sizeof(*foo)];', '')
1347         self.assert_lint('int a[sizeof foo];', '')
1348         self.assert_lint('int a[sizeof(struct Foo)];', '')
1349         self.assert_lint('int a[128 - sizeof(const bar)];', '')
1350         self.assert_lint('int a[(sizeof(foo) * 4)];', '')
1351         self.assert_lint('int a[(arraysize(fixed_size_array)/2) << 1];', 'Missing spaces around /  [whitespace/operators] [3]')
1352         self.assert_lint('delete a[some_var];', '')
1353         self.assert_lint('return a[some_var];', '')
1354
1355     # Brace usage
1356     def test_braces(self):
1357         # Braces shouldn't be followed by a ; unless they're defining a struct
1358         # or initializing an array
1359         self.assert_lint('int a[3] = { 1, 2, 3 };', '')
1360         self.assert_lint(
1361             '''const int foo[] =
1362                    {1, 2, 3 };''',
1363             '')
1364         # For single line, unmatched '}' with a ';' is ignored (not enough context)
1365         self.assert_multi_line_lint(
1366             '''int a[3] = { 1,
1367                             2,
1368                             3 };''',
1369             '')
1370         self.assert_multi_line_lint(
1371             '''int a[2][3] = { { 1, 2 },
1372                              { 3, 4 } };''',
1373             '')
1374         self.assert_multi_line_lint(
1375             '''int a[2][3] =
1376                    { { 1, 2 },
1377                      { 3, 4 } };''',
1378             '')
1379
1380     # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements
1381     def test_check_check(self):
1382         self.assert_lint('CHECK(x == 42)',
1383                          'Consider using CHECK_EQ instead of CHECK(a == b)'
1384                          '  [readability/check] [2]')
1385         self.assert_lint('CHECK(x != 42)',
1386                          'Consider using CHECK_NE instead of CHECK(a != b)'
1387                          '  [readability/check] [2]')
1388         self.assert_lint('CHECK(x >= 42)',
1389                          'Consider using CHECK_GE instead of CHECK(a >= b)'
1390                          '  [readability/check] [2]')
1391         self.assert_lint('CHECK(x > 42)',
1392                          'Consider using CHECK_GT instead of CHECK(a > b)'
1393                          '  [readability/check] [2]')
1394         self.assert_lint('CHECK(x <= 42)',
1395                          'Consider using CHECK_LE instead of CHECK(a <= b)'
1396                          '  [readability/check] [2]')
1397         self.assert_lint('CHECK(x < 42)',
1398                          'Consider using CHECK_LT instead of CHECK(a < b)'
1399                          '  [readability/check] [2]')
1400
1401         self.assert_lint('DCHECK(x == 42)',
1402                          'Consider using DCHECK_EQ instead of DCHECK(a == b)'
1403                          '  [readability/check] [2]')
1404         self.assert_lint('DCHECK(x != 42)',
1405                          'Consider using DCHECK_NE instead of DCHECK(a != b)'
1406                          '  [readability/check] [2]')
1407         self.assert_lint('DCHECK(x >= 42)',
1408                          'Consider using DCHECK_GE instead of DCHECK(a >= b)'
1409                          '  [readability/check] [2]')
1410         self.assert_lint('DCHECK(x > 42)',
1411                          'Consider using DCHECK_GT instead of DCHECK(a > b)'
1412                          '  [readability/check] [2]')
1413         self.assert_lint('DCHECK(x <= 42)',
1414                          'Consider using DCHECK_LE instead of DCHECK(a <= b)'
1415                          '  [readability/check] [2]')
1416         self.assert_lint('DCHECK(x < 42)',
1417                          'Consider using DCHECK_LT instead of DCHECK(a < b)'
1418                          '  [readability/check] [2]')
1419
1420         self.assert_lint(
1421             'EXPECT_TRUE("42" == x)',
1422             'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)'
1423             '  [readability/check] [2]')
1424         self.assert_lint(
1425             'EXPECT_TRUE("42" != x)',
1426             'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)'
1427             '  [readability/check] [2]')
1428         self.assert_lint(
1429             'EXPECT_TRUE(+42 >= x)',
1430             'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)'
1431             '  [readability/check] [2]')
1432         self.assert_lint(
1433             'EXPECT_TRUE_M(-42 > x)',
1434             'Consider using EXPECT_GT_M instead of EXPECT_TRUE_M(a > b)'
1435             '  [readability/check] [2]')
1436         self.assert_lint(
1437             'EXPECT_TRUE_M(42U <= x)',
1438             'Consider using EXPECT_LE_M instead of EXPECT_TRUE_M(a <= b)'
1439             '  [readability/check] [2]')
1440         self.assert_lint(
1441             'EXPECT_TRUE_M(42L < x)',
1442             'Consider using EXPECT_LT_M instead of EXPECT_TRUE_M(a < b)'
1443             '  [readability/check] [2]')
1444
1445         self.assert_lint(
1446             'EXPECT_FALSE(x == 42)',
1447             'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)'
1448             '  [readability/check] [2]')
1449         self.assert_lint(
1450             'EXPECT_FALSE(x != 42)',
1451             'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)'
1452             '  [readability/check] [2]')
1453         self.assert_lint(
1454             'EXPECT_FALSE(x >= 42)',
1455             'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)'
1456             '  [readability/check] [2]')
1457         self.assert_lint(
1458             'ASSERT_FALSE(x > 42)',
1459             'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)'
1460             '  [readability/check] [2]')
1461         self.assert_lint(
1462             'ASSERT_FALSE(x <= 42)',
1463             'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)'
1464             '  [readability/check] [2]')
1465         self.assert_lint(
1466             'ASSERT_FALSE_M(x < 42)',
1467             'Consider using ASSERT_GE_M instead of ASSERT_FALSE_M(a < b)'
1468             '  [readability/check] [2]')
1469
1470         self.assert_lint('CHECK(some_iterator == obj.end())', '')
1471         self.assert_lint('EXPECT_TRUE(some_iterator == obj.end())', '')
1472         self.assert_lint('EXPECT_FALSE(some_iterator == obj.end())', '')
1473
1474         self.assert_lint('CHECK(CreateTestFile(dir, (1 << 20)));', '')
1475         self.assert_lint('CHECK(CreateTestFile(dir, (1 >> 20)));', '')
1476
1477         self.assert_lint('CHECK(x<42)',
1478                          ['Missing spaces around <'
1479                           '  [whitespace/operators] [3]',
1480                           'Consider using CHECK_LT instead of CHECK(a < b)'
1481                           '  [readability/check] [2]'])
1482         self.assert_lint('CHECK(x>42)',
1483                          'Consider using CHECK_GT instead of CHECK(a > b)'
1484                          '  [readability/check] [2]')
1485
1486         self.assert_lint(
1487             '    EXPECT_TRUE(42 < x) // Random comment.',
1488             'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1489             '  [readability/check] [2]')
1490         self.assert_lint(
1491             'EXPECT_TRUE( 42 < x )',
1492             ['Extra space after ( in function call'
1493              '  [whitespace/parens] [4]',
1494              'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1495              '  [readability/check] [2]'])
1496         self.assert_lint(
1497             'CHECK("foo" == "foo")',
1498             'Consider using CHECK_EQ instead of CHECK(a == b)'
1499             '  [readability/check] [2]')
1500
1501         self.assert_lint('CHECK_EQ("foo", "foo")', '')
1502
1503     def test_brace_at_begin_of_line(self):
1504         self.assert_lint('{',
1505                          'This { should be at the end of the previous line'
1506                          '  [whitespace/braces] [4]')
1507         self.assert_multi_line_lint(
1508             '#endif\n'
1509             '{\n'
1510             '}\n',
1511             '')
1512         self.assert_multi_line_lint(
1513             'if (condition) {',
1514             '')
1515         self.assert_multi_line_lint(
1516             '    MACRO1(macroArg) {',
1517             '')
1518         self.assert_multi_line_lint(
1519             'ACCESSOR_GETTER(MessageEventPorts) {',
1520             'Place brace on its own line for function definitions.  [whitespace/braces] [4]')
1521         self.assert_multi_line_lint(
1522             'int foo() {',
1523             'Place brace on its own line for function definitions.  [whitespace/braces] [4]')
1524         self.assert_multi_line_lint(
1525             'int foo() const {',
1526             'Place brace on its own line for function definitions.  [whitespace/braces] [4]')
1527         self.assert_multi_line_lint(
1528             'int foo() const\n'
1529             '{\n'
1530             '}\n',
1531             '')
1532         self.assert_multi_line_lint(
1533             'if (condition\n'
1534             '    && condition2\n'
1535             '    && condition3) {\n'
1536             '}\n',
1537             '')
1538
1539     def test_mismatching_spaces_in_parens(self):
1540         self.assert_lint('if (foo ) {', 'Extra space before ) in if'
1541                          '  [whitespace/parens] [5]')
1542         self.assert_lint('switch ( foo) {', 'Extra space after ( in switch'
1543                          '  [whitespace/parens] [5]')
1544         self.assert_lint('for (foo; ba; bar ) {', 'Extra space before ) in for'
1545                          '  [whitespace/parens] [5]')
1546         self.assert_lint('for ((foo); (ba); (bar) ) {', 'Extra space before ) in for'
1547                          '  [whitespace/parens] [5]')
1548         self.assert_lint('for (; foo; bar) {', '')
1549         self.assert_lint('for (; (foo); (bar)) {', '')
1550         self.assert_lint('for ( ; foo; bar) {', '')
1551         self.assert_lint('for ( ; (foo); (bar)) {', '')
1552         self.assert_lint('for ( ; foo; bar ) {', 'Extra space before ) in for'
1553                          '  [whitespace/parens] [5]')
1554         self.assert_lint('for ( ; (foo); (bar) ) {', 'Extra space before ) in for'
1555                          '  [whitespace/parens] [5]')
1556         self.assert_lint('for (foo; bar; ) {', '')
1557         self.assert_lint('for ((foo); (bar); ) {', '')
1558         self.assert_lint('foreach (foo, foos ) {', 'Extra space before ) in foreach'
1559                          '  [whitespace/parens] [5]')
1560         self.assert_lint('foreach ( foo, foos) {', 'Extra space after ( in foreach'
1561                          '  [whitespace/parens] [5]')
1562         self.assert_lint('while (  foo) {', 'Extra space after ( in while'
1563                          '  [whitespace/parens] [5]')
1564
1565     def test_spacing_for_fncall(self):
1566         self.assert_lint('if (foo) {', '')
1567         self.assert_lint('for (foo;bar;baz) {', '')
1568         self.assert_lint('foreach (foo, foos) {', '')
1569         self.assert_lint('while (foo) {', '')
1570         self.assert_lint('switch (foo) {', '')
1571         self.assert_lint('new (RenderArena()) RenderInline(document())', '')
1572         self.assert_lint('foo( bar)', 'Extra space after ( in function call'
1573                          '  [whitespace/parens] [4]')
1574         self.assert_lint('foobar( \\', '')
1575         self.assert_lint('foobar(     \\', '')
1576         self.assert_lint('( a + b)', 'Extra space after ('
1577                          '  [whitespace/parens] [2]')
1578         self.assert_lint('((a+b))', '')
1579         self.assert_lint('foo (foo)', 'Extra space before ( in function call'
1580                          '  [whitespace/parens] [4]')
1581         self.assert_lint('#elif (foo(bar))', '')
1582         self.assert_lint('#elif (foo(bar) && foo(baz))', '')
1583         self.assert_lint('typedef foo (*foo)(foo)', '')
1584         self.assert_lint('typedef foo (*foo12bar_)(foo)', '')
1585         self.assert_lint('typedef foo (Foo::*bar)(foo)', '')
1586         self.assert_lint('foo (Foo::*bar)(',
1587                          'Extra space before ( in function call'
1588                          '  [whitespace/parens] [4]')
1589         self.assert_lint('typedef foo (Foo::*bar)(', '')
1590         self.assert_lint('(foo)(bar)', '')
1591         self.assert_lint('Foo (*foo)(bar)', '')
1592         self.assert_lint('Foo (*foo)(Bar bar,', '')
1593         self.assert_lint('char (*p)[sizeof(foo)] = &foo', '')
1594         self.assert_lint('char (&ref)[sizeof(foo)] = &foo', '')
1595         self.assert_lint('const char32 (*table[])[6];', '')
1596
1597     def test_spacing_before_braces(self):
1598         self.assert_lint('if (foo){', 'Missing space before {'
1599                          '  [whitespace/braces] [5]')
1600         self.assert_lint('for{', 'Missing space before {'
1601                          '  [whitespace/braces] [5]')
1602         self.assert_lint('for {', '')
1603         self.assert_lint('EXPECT_DEBUG_DEATH({', '')
1604
1605     def test_spacing_between_braces(self):
1606         self.assert_lint('    { }', '')
1607         self.assert_lint('    {}', 'Missing space inside { }.  [whitespace/braces] [5]')
1608         self.assert_lint('    {   }', 'Too many spaces inside { }.  [whitespace/braces] [5]')
1609
1610     def test_spacing_around_else(self):
1611         self.assert_lint('}else {', 'Missing space before else'
1612                          '  [whitespace/braces] [5]')
1613         self.assert_lint('} else{', 'Missing space before {'
1614                          '  [whitespace/braces] [5]')
1615         self.assert_lint('} else {', '')
1616         self.assert_lint('} else if', '')
1617
1618     def test_spacing_for_binary_ops(self):
1619         self.assert_lint('if (foo<=bar) {', 'Missing spaces around <='
1620                          '  [whitespace/operators] [3]')
1621         self.assert_lint('if (foo<bar) {', 'Missing spaces around <'
1622                          '  [whitespace/operators] [3]')
1623         self.assert_lint('if (foo<bar->baz) {', 'Missing spaces around <'
1624                          '  [whitespace/operators] [3]')
1625         self.assert_lint('if (foo<bar->bar) {', 'Missing spaces around <'
1626                          '  [whitespace/operators] [3]')
1627         self.assert_lint('typedef hash_map<Foo, Bar', 'Missing spaces around <'
1628                          '  [whitespace/operators] [3]')
1629         self.assert_lint('typedef hash_map<FoooooType, BaaaaarType,', '')
1630         self.assert_lint('a<Foo> t+=b;', 'Missing spaces around +='
1631                          '  [whitespace/operators] [3]')
1632         self.assert_lint('a<Foo> t-=b;', 'Missing spaces around -='
1633                          '  [whitespace/operators] [3]')
1634         self.assert_lint('a<Foo*> t*=b;', 'Missing spaces around *='
1635                          '  [whitespace/operators] [3]')
1636         self.assert_lint('a<Foo*> t/=b;', 'Missing spaces around /='
1637                          '  [whitespace/operators] [3]')
1638         self.assert_lint('a<Foo*> t|=b;', 'Missing spaces around |='
1639                          '  [whitespace/operators] [3]')
1640         self.assert_lint('a<Foo*> t&=b;', 'Missing spaces around &='
1641                          '  [whitespace/operators] [3]')
1642         self.assert_lint('a<Foo*> t<<=b;', 'Missing spaces around <<='
1643                          '  [whitespace/operators] [3]')
1644         self.assert_lint('a<Foo*> t>>=b;', 'Missing spaces around >>='
1645                          '  [whitespace/operators] [3]')
1646         self.assert_lint('a<Foo*> t>>=&b|c;', 'Missing spaces around >>='
1647                          '  [whitespace/operators] [3]')
1648         self.assert_lint('a<Foo*> t<<=*b/c;', 'Missing spaces around <<='
1649                          '  [whitespace/operators] [3]')
1650         self.assert_lint('a<Foo> t -= b;', '')
1651         self.assert_lint('a<Foo> t += b;', '')
1652         self.assert_lint('a<Foo*> t *= b;', '')
1653         self.assert_lint('a<Foo*> t /= b;', '')
1654         self.assert_lint('a<Foo*> t |= b;', '')
1655         self.assert_lint('a<Foo*> t &= b;', '')
1656         self.assert_lint('a<Foo*> t <<= b;', '')
1657         self.assert_lint('a<Foo*> t >>= b;', '')
1658         self.assert_lint('a<Foo*> t >>= &b|c;', 'Missing spaces around |'
1659                          '  [whitespace/operators] [3]')
1660         self.assert_lint('a<Foo*> t <<= *b/c;', 'Missing spaces around /'
1661                          '  [whitespace/operators] [3]')
1662         self.assert_lint('a<Foo*> t <<= b/c; //Test', [
1663                          'Should have a space between // and comment  '
1664                          '[whitespace/comments] [4]', 'Missing'
1665                          ' spaces around /  [whitespace/operators] [3]'])
1666         self.assert_lint('a<Foo*> t <<= b||c;  //Test', ['One space before end'
1667                          ' of line comments  [whitespace/comments] [5]',
1668                          'Should have a space between // and comment  '
1669                          '[whitespace/comments] [4]',
1670                          'Missing spaces around ||  [whitespace/operators] [3]'])
1671         self.assert_lint('a<Foo*> t <<= b&&c; // Test', 'Missing spaces around'
1672                          ' &&  [whitespace/operators] [3]')
1673         self.assert_lint('a<Foo*> t <<= b&&&c; // Test', 'Missing spaces around'
1674                          ' &&  [whitespace/operators] [3]')
1675         self.assert_lint('a<Foo*> t <<= b&&*c; // Test', 'Missing spaces around'
1676                          ' &&  [whitespace/operators] [3]')
1677         self.assert_lint('a<Foo*> t <<= b && *c; // Test', '')
1678         self.assert_lint('a<Foo*> t <<= b && &c; // Test', '')
1679         self.assert_lint('a<Foo*> t <<= b || &c;  /*Test', 'Complex multi-line '
1680                          '/*...*/-style comment found. Lint may give bogus '
1681                          'warnings.  Consider replacing these with //-style'
1682                          ' comments, with #if 0...#endif, or with more clearly'
1683                          ' structured multi-line comments.  [readability/multiline_comment] [5]')
1684         self.assert_lint('a<Foo&> t <<= &b | &c;', '')
1685         self.assert_lint('a<Foo*> t <<= &b & &c; // Test', '')
1686         self.assert_lint('a<Foo*> t <<= *b / &c; // Test', '')
1687         self.assert_lint('if (a=b == 1)', 'Missing spaces around =  [whitespace/operators] [4]')
1688         self.assert_lint('a = 1<<20', 'Missing spaces around <<  [whitespace/operators] [3]')
1689         self.assert_lint('if (a = b == 1)', '')
1690         self.assert_lint('a = 1 << 20', '')
1691         self.assert_multi_line_lint('#include <sys/io.h>\n', '')
1692         self.assert_multi_line_lint('#import <foo/bar.h>\n', '')
1693
1694     def test_operator_methods(self):
1695         self.assert_lint('String operator+(const String&, const String&);', '')
1696         self.assert_lint('bool operator==(const String&, const String&);', '')
1697         self.assert_lint('String& operator-=(const String&, const String&);', '')
1698         self.assert_lint('String& operator+=(const String&, const String&);', '')
1699         self.assert_lint('String& operator*=(const String&, const String&);', '')
1700         self.assert_lint('String& operator%=(const String&, const String&);', '')
1701         self.assert_lint('String& operator&=(const String&, const String&);', '')
1702         self.assert_lint('String& operator<<=(const String&, const String&);', '')
1703         self.assert_lint('String& operator>>=(const String&, const String&);', '')
1704         self.assert_lint('String& operator|=(const String&, const String&);', '')
1705         self.assert_lint('String& operator^=(const String&, const String&);', '')
1706
1707     def test_spacing_before_last_semicolon(self):
1708         self.assert_lint('call_function() ;',
1709                          'Extra space before last semicolon. If this should be an '
1710                          'empty statement, use { } instead.'
1711                          '  [whitespace/semicolon] [5]')
1712         self.assert_lint('while (true) ;',
1713                          'Extra space before last semicolon. If this should be an '
1714                          'empty statement, use { } instead.'
1715                          '  [whitespace/semicolon] [5]')
1716         self.assert_lint('default:;',
1717                          'Semicolon defining empty statement. Use { } instead.'
1718                          '  [whitespace/semicolon] [5]')
1719         self.assert_lint('      ;',
1720                          'Line contains only semicolon. If this should be an empty '
1721                          'statement, use { } instead.'
1722                          '  [whitespace/semicolon] [5]')
1723         self.assert_lint('for (int i = 0; ;', '')
1724
1725     # Static or global STL strings.
1726     def test_static_or_global_stlstrings(self):
1727         self.assert_lint('string foo;',
1728                          'For a static/global string constant, use a C style '
1729                          'string instead: "char foo[]".'
1730                          '  [runtime/string] [4]')
1731         self.assert_lint('string kFoo = "hello"; // English',
1732                          'For a static/global string constant, use a C style '
1733                          'string instead: "char kFoo[]".'
1734                          '  [runtime/string] [4]')
1735         self.assert_lint('static string foo;',
1736                          'For a static/global string constant, use a C style '
1737                          'string instead: "static char foo[]".'
1738                          '  [runtime/string] [4]')
1739         self.assert_lint('static const string foo;',
1740                          'For a static/global string constant, use a C style '
1741                          'string instead: "static const char foo[]".'
1742                          '  [runtime/string] [4]')
1743         self.assert_lint('string Foo::bar;',
1744                          'For a static/global string constant, use a C style '
1745                          'string instead: "char Foo::bar[]".'
1746                          '  [runtime/string] [4]')
1747         # Rare case.
1748         self.assert_lint('string foo("foobar");',
1749                          'For a static/global string constant, use a C style '
1750                          'string instead: "char foo[]".'
1751                          '  [runtime/string] [4]')
1752         # Should not catch local or member variables.
1753         self.assert_lint('    string foo', '')
1754         # Should not catch functions.
1755         self.assert_lint('string EmptyString() { return ""; }', '')
1756         self.assert_lint('string EmptyString () { return ""; }', '')
1757         self.assert_lint('string VeryLongNameFunctionSometimesEndsWith(\n'
1758                          '    VeryLongNameType veryLongNameVariable) { }', '')
1759         self.assert_lint('template<>\n'
1760                          'string FunctionTemplateSpecialization<SomeType>(\n'
1761                          '      int x) { return ""; }', '')
1762         self.assert_lint('template<>\n'
1763                          'string FunctionTemplateSpecialization<vector<A::B>* >(\n'
1764                          '      int x) { return ""; }', '')
1765
1766         # should not catch methods of template classes.
1767         self.assert_lint('string Class<Type>::Method() const\n'
1768                          '{\n'
1769                          '    return "";\n'
1770                          '}\n', '')
1771         self.assert_lint('string Class<Type>::Method(\n'
1772                          '    int arg) const\n'
1773                          '{\n'
1774                          '    return "";\n'
1775                          '}\n', '')
1776
1777     def test_no_spaces_in_function_calls(self):
1778         self.assert_lint('TellStory(1, 3);',
1779                          '')
1780         self.assert_lint('TellStory(1, 3 );',
1781                          'Extra space before )'
1782                          '  [whitespace/parens] [2]')
1783         self.assert_lint('TellStory(1 /* wolf */, 3 /* pigs */);',
1784                          '')
1785         self.assert_multi_line_lint('#endif\n    );',
1786                                     '')
1787
1788     def test_one_spaces_between_code_and_comments(self):
1789         self.assert_lint('} // namespace foo',
1790                          '')
1791         self.assert_lint('}// namespace foo',
1792                          'One space before end of line comments'
1793                          '  [whitespace/comments] [5]')
1794         self.assert_lint('printf("foo"); // Outside quotes.',
1795                          '')
1796         self.assert_lint('int i = 0; // Having one space is fine.','')
1797         self.assert_lint('int i = 0;  // Having two spaces is bad.',
1798                          'One space before end of line comments'
1799                          '  [whitespace/comments] [5]')
1800         self.assert_lint('int i = 0;   // Having three spaces is bad.',
1801                          'One space before end of line comments'
1802                          '  [whitespace/comments] [5]')
1803         self.assert_lint('// Top level comment', '')
1804         self.assert_lint('    // Line starts with four spaces.', '')
1805         self.assert_lint('foo();\n'
1806                          '{ // A scope is opening.', '')
1807         self.assert_lint('    foo();\n'
1808                          '    { // An indented scope is opening.', '')
1809         self.assert_lint('if (foo) { // not a pure scope',
1810                          '')
1811         self.assert_lint('printf("// In quotes.")', '')
1812         self.assert_lint('printf("\\"%s // In quotes.")', '')
1813         self.assert_lint('printf("%s", "// In quotes.")', '')
1814
1815     def test_one_spaces_after_punctuation_in_comments(self):
1816         self.assert_lint('int a; // This is a sentence.',
1817                          '')
1818         self.assert_lint('int a; // This is a sentence.  ',
1819                          'Line ends in whitespace.  Consider deleting these extra spaces.  [whitespace/end_of_line] [4]')
1820         self.assert_lint('int a; // This is a sentence. This is a another sentence.',
1821                          '')
1822         self.assert_lint('int a; // This is a sentence.  This is a another sentence.',
1823                          'Should have only a single space after a punctuation in a comment.  [whitespace/comments] [5]')
1824         self.assert_lint('int a; // This is a sentence!  This is a another sentence.',
1825                          'Should have only a single space after a punctuation in a comment.  [whitespace/comments] [5]')
1826         self.assert_lint('int a; // Why did I write this?  This is a another sentence.',
1827                          'Should have only a single space after a punctuation in a comment.  [whitespace/comments] [5]')
1828         self.assert_lint('int a; // Elementary,  my dear.',
1829                          'Should have only a single space after a punctuation in a comment.  [whitespace/comments] [5]')
1830         self.assert_lint('int a; // The following should be clear:  Is it?',
1831                          'Should have only a single space after a punctuation in a comment.  [whitespace/comments] [5]')
1832         self.assert_lint('int a; // Look at the follow semicolon;  I hope this gives an error.',
1833                          'Should have only a single space after a punctuation in a comment.  [whitespace/comments] [5]')
1834
1835     def test_space_after_comment_marker(self):
1836         self.assert_lint('//', '')
1837         self.assert_lint('//x', 'Should have a space between // and comment'
1838                          '  [whitespace/comments] [4]')
1839         self.assert_lint('// x', '')
1840         self.assert_lint('//----', '')
1841         self.assert_lint('//====', '')
1842         self.assert_lint('//////', '')
1843         self.assert_lint('////// x', '')
1844         self.assert_lint('/// x', '')
1845         self.assert_lint('////x', 'Should have a space between // and comment'
1846                          '  [whitespace/comments] [4]')
1847
1848     def test_newline_at_eof(self):
1849         def do_test(self, data, is_missing_eof):
1850             error_collector = ErrorCollector(self.assert_)
1851             self.process_file_data('foo.cpp', 'cpp', data.split('\n'),
1852                                    error_collector)
1853             # The warning appears only once.
1854             self.assertEquals(
1855                 int(is_missing_eof),
1856                 error_collector.results().count(
1857                     'Could not find a newline character at the end of the file.'
1858                     '  [whitespace/ending_newline] [5]'))
1859
1860         do_test(self, '// Newline\n// at EOF\n', False)
1861         do_test(self, '// No newline\n// at EOF', True)
1862
1863     def test_invalid_utf8(self):
1864         def do_test(self, raw_bytes, has_invalid_utf8):
1865             error_collector = ErrorCollector(self.assert_)
1866             self.process_file_data('foo.cpp', 'cpp',
1867                                    unicode(raw_bytes, 'utf8', 'replace').split('\n'),
1868                                    error_collector)
1869             # The warning appears only once.
1870             self.assertEquals(
1871                 int(has_invalid_utf8),
1872                 error_collector.results().count(
1873                     'Line contains invalid UTF-8'
1874                     ' (or Unicode replacement character).'
1875                     '  [readability/utf8] [5]'))
1876
1877         do_test(self, 'Hello world\n', False)
1878         do_test(self, '\xe9\x8e\xbd\n', False)
1879         do_test(self, '\xe9x\x8e\xbd\n', True)
1880         # This is the encoding of the replacement character itself (which
1881         # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')).
1882         do_test(self, '\xef\xbf\xbd\n', True)
1883
1884     def test_is_blank_line(self):
1885         self.assert_(cpp_style.is_blank_line(''))
1886         self.assert_(cpp_style.is_blank_line(' '))
1887         self.assert_(cpp_style.is_blank_line(' \t\r\n'))
1888         self.assert_(not cpp_style.is_blank_line('int a;'))
1889         self.assert_(not cpp_style.is_blank_line('{'))
1890
1891     def test_blank_lines_check(self):
1892         self.assert_blank_lines_check(['{\n', '\n', '\n', '}\n'], 1, 1)
1893         self.assert_blank_lines_check(['  if (foo) {\n', '\n', '  }\n'], 1, 1)
1894         self.assert_blank_lines_check(
1895             ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0)
1896         self.assert_blank_lines_check(['\n', 'run("{");\n', '\n'], 0, 0)
1897         self.assert_blank_lines_check(['\n', '  if (foo) { return 0; }\n', '\n'], 0, 0)
1898
1899     def test_allow_blank_line_before_closing_namespace(self):
1900         error_collector = ErrorCollector(self.assert_)
1901         self.process_file_data('foo.cpp', 'cpp',
1902                                ['namespace {', '', '}  // namespace'],
1903                                error_collector)
1904         self.assertEquals(0, error_collector.results().count(
1905             'Blank line at the end of a code block.  Is this needed?'
1906             '  [whitespace/blank_line] [3]'))
1907
1908     def test_allow_blank_line_before_if_else_chain(self):
1909         error_collector = ErrorCollector(self.assert_)
1910         self.process_file_data('foo.cpp', 'cpp',
1911                                ['if (hoge) {',
1912                                 '',  # No warning
1913                                 '} else if (piyo) {',
1914                                 '',  # No warning
1915                                 '} else if (piyopiyo) {',
1916                                 '  hoge = true;',  # No warning
1917                                 '} else {',
1918                                 '',  # Warning on this line
1919                                 '}'],
1920                                error_collector)
1921         self.assertEquals(1, error_collector.results().count(
1922             'Blank line at the end of a code block.  Is this needed?'
1923             '  [whitespace/blank_line] [3]'))
1924
1925     def test_else_on_same_line_as_closing_braces(self):
1926         error_collector = ErrorCollector(self.assert_)
1927         self.process_file_data('foo.cpp', 'cpp',
1928                                ['if (hoge) {',
1929                                 '',
1930                                 '}',
1931                                 ' else {'  # Warning on this line
1932                                 '',
1933                                 '}'],
1934                                error_collector)
1935         self.assertEquals(1, error_collector.results().count(
1936             'An else should appear on the same line as the preceding }'
1937             '  [whitespace/newline] [4]'))
1938
1939     def test_else_clause_not_on_same_line_as_else(self):
1940         self.assert_lint('    else DoSomethingElse();',
1941                          'Else clause should never be on same line as else '
1942                          '(use 2 lines)  [whitespace/newline] [4]')
1943         self.assert_lint('    else ifDoSomethingElse();',
1944                          'Else clause should never be on same line as else '
1945                          '(use 2 lines)  [whitespace/newline] [4]')
1946         self.assert_lint('    else if (blah) {', '')
1947         self.assert_lint('    variable_ends_in_else = true;', '')
1948
1949     def test_comma(self):
1950         self.assert_lint('a = f(1,2);',
1951                          'Missing space after ,  [whitespace/comma] [3]')
1952         self.assert_lint('int tmp=a,a=b,b=tmp;',
1953                          ['Missing spaces around =  [whitespace/operators] [4]',
1954                           'Missing space after ,  [whitespace/comma] [3]'])
1955         self.assert_lint('f(a, /* name */ b);', '')
1956         self.assert_lint('f(a, /* name */b);', '')
1957
1958     def test_declaration(self):
1959         self.assert_lint('int a;', '')
1960         self.assert_lint('int   a;', 'Extra space between int and a  [whitespace/declaration] [3]')
1961         self.assert_lint('int*  a;', 'Extra space between int* and a  [whitespace/declaration] [3]')
1962         self.assert_lint('else if { }', '')
1963         self.assert_lint('else   if { }', 'Extra space between else and if  [whitespace/declaration] [3]')
1964
1965     def test_pointer_reference_marker_location(self):
1966         self.assert_lint('int* b;', '', 'foo.cpp')
1967         self.assert_lint('int *b;',
1968                          'Declaration has space between type name and * in int *b  [whitespace/declaration] [3]',
1969                          'foo.cpp')
1970         self.assert_lint('return *b;', '', 'foo.cpp')
1971         self.assert_lint('delete *b;', '', 'foo.cpp')
1972         self.assert_lint('int *b;', '', 'foo.c')
1973         self.assert_lint('int* b;',
1974                          'Declaration has space between * and variable name in int* b  [whitespace/declaration] [3]',
1975                          'foo.c')
1976         self.assert_lint('int& b;', '', 'foo.cpp')
1977         self.assert_lint('int &b;',
1978                          'Declaration has space between type name and & in int &b  [whitespace/declaration] [3]',
1979                          'foo.cpp')
1980         self.assert_lint('return &b;', '', 'foo.cpp')
1981
1982     def test_indent(self):
1983         self.assert_lint('static int noindent;', '')
1984         self.assert_lint('    int fourSpaceIndent;', '')
1985         self.assert_lint(' int oneSpaceIndent;',
1986                          'Weird number of spaces at line-start.  '
1987                          'Are you using a 4-space indent?  [whitespace/indent] [3]')
1988         self.assert_lint('   int threeSpaceIndent;',
1989                          'Weird number of spaces at line-start.  '
1990                          'Are you using a 4-space indent?  [whitespace/indent] [3]')
1991         self.assert_lint(' char* oneSpaceIndent = "public:";',
1992                          'Weird number of spaces at line-start.  '
1993                          'Are you using a 4-space indent?  [whitespace/indent] [3]')
1994         self.assert_lint(' public:', '')
1995         self.assert_lint('  public:', '')
1996         self.assert_lint('   public:', '')
1997
1998     def test_label(self):
1999         self.assert_lint('public:',
2000                          'Labels should always be indented at least one space.  '
2001                          'If this is a member-initializer list in a constructor, '
2002                          'the colon should be on the line after the definition '
2003                          'header.  [whitespace/labels] [4]')
2004         self.assert_lint('  public:', '')
2005         self.assert_lint('   public:', '')
2006         self.assert_lint(' public:', '')
2007         self.assert_lint('  public:', '')
2008         self.assert_lint('   public:', '')
2009
2010     def test_not_alabel(self):
2011         self.assert_lint('MyVeryLongNamespace::MyVeryLongClassName::', '')
2012
2013     def test_tab(self):
2014         self.assert_lint('\tint a;',
2015                          'Tab found; better to use spaces  [whitespace/tab] [1]')
2016         self.assert_lint('int a = 5;\t// set a to 5',
2017                          'Tab found; better to use spaces  [whitespace/tab] [1]')
2018
2019     def test_unnamed_namespaces_in_headers(self):
2020         self.assert_language_rules_check(
2021             'foo.h', 'namespace {',
2022             'Do not use unnamed namespaces in header files.  See'
2023             ' http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
2024             ' for more information.  [build/namespaces] [4]')
2025         # namespace registration macros are OK.
2026         self.assert_language_rules_check('foo.h', 'namespace {  \\', '')
2027         # named namespaces are OK.
2028         self.assert_language_rules_check('foo.h', 'namespace foo {', '')
2029         self.assert_language_rules_check('foo.h', 'namespace foonamespace {', '')
2030         self.assert_language_rules_check('foo.cpp', 'namespace {', '')
2031         self.assert_language_rules_check('foo.cpp', 'namespace foo {', '')
2032
2033     def test_build_class(self):
2034         # Test that the linter can parse to the end of class definitions,
2035         # and that it will report when it can't.
2036         # Use multi-line linter because it performs the ClassState check.
2037         self.assert_multi_line_lint(
2038             'class Foo {',
2039             'Failed to find complete declaration of class Foo'
2040             '  [build/class] [5]')
2041         # Don't warn on forward declarations of various types.
2042         self.assert_multi_line_lint(
2043             'class Foo;',
2044             '')
2045         self.assert_multi_line_lint(
2046             '''struct Foo*
2047                  foo = NewFoo();''',
2048             '')
2049         # Here is an example where the linter gets confused, even though
2050         # the code doesn't violate the style guide.
2051         self.assert_multi_line_lint(
2052             '''class Foo
2053             #ifdef DERIVE_FROM_GOO
2054               : public Goo {
2055             #else
2056               : public Hoo {
2057             #endif
2058               };''',
2059             'Failed to find complete declaration of class Foo'
2060             '  [build/class] [5]')
2061
2062     def test_build_end_comment(self):
2063         # The crosstool compiler we currently use will fail to compile the
2064         # code in this test, so we might consider removing the lint check.
2065         self.assert_lint('#endif Not a comment',
2066                          'Uncommented text after #endif is non-standard.'
2067                          '  Use a comment.'
2068                          '  [build/endif_comment] [5]')
2069
2070     def test_build_forward_decl(self):
2071         # The crosstool compiler we currently use will fail to compile the
2072         # code in this test, so we might consider removing the lint check.
2073         self.assert_lint('class Foo::Goo;',
2074                          'Inner-style forward declarations are invalid.'
2075                          '  Remove this line.'
2076                          '  [build/forward_decl] [5]')
2077
2078     def test_build_header_guard(self):
2079         file_path = 'mydir/Foo.h'
2080
2081         # We can't rely on our internal stuff to get a sane path on the open source
2082         # side of things, so just parse out the suggested header guard. This
2083         # doesn't allow us to test the suggested header guard, but it does let us
2084         # test all the other header tests.
2085         error_collector = ErrorCollector(self.assert_)
2086         self.process_file_data(file_path, 'h', [], error_collector)
2087         expected_guard = ''
2088         matcher = re.compile(
2089             'No \#ifndef header guard found\, suggested CPP variable is\: ([A-Za-z_0-9]+) ')
2090         for error in error_collector.result_list():
2091             matches = matcher.match(error)
2092             if matches:
2093                 expected_guard = matches.group(1)
2094                 break
2095
2096         # Make sure we extracted something for our header guard.
2097         self.assertNotEqual(expected_guard, '')
2098
2099         # Wrong guard
2100         error_collector = ErrorCollector(self.assert_)
2101         self.process_file_data(file_path, 'h',
2102                                ['#ifndef FOO_H', '#define FOO_H'], error_collector)
2103         self.assertEquals(
2104             1,
2105             error_collector.result_list().count(
2106                 '#ifndef header guard has wrong style, please use: %s'
2107                 '  [build/header_guard] [5]' % expected_guard),
2108             error_collector.result_list())
2109
2110         # No define
2111         error_collector = ErrorCollector(self.assert_)
2112         self.process_file_data(file_path, 'h',
2113                                ['#ifndef %s' % expected_guard], error_collector)
2114         self.assertEquals(
2115             1,
2116             error_collector.result_list().count(
2117                 'No #ifndef header guard found, suggested CPP variable is: %s'
2118                 '  [build/header_guard] [5]' % expected_guard),
2119             error_collector.result_list())
2120
2121         # Mismatched define
2122         error_collector = ErrorCollector(self.assert_)
2123         self.process_file_data(file_path, 'h',
2124                                ['#ifndef %s' % expected_guard,
2125                                 '#define FOO_H'],
2126                                error_collector)
2127         self.assertEquals(
2128             1,
2129             error_collector.result_list().count(
2130                 'No #ifndef header guard found, suggested CPP variable is: %s'
2131                 '  [build/header_guard] [5]' % expected_guard),
2132             error_collector.result_list())
2133
2134         # No header guard errors
2135         error_collector = ErrorCollector(self.assert_)
2136         self.process_file_data(file_path, 'h',
2137                                ['#ifndef %s' % expected_guard,
2138                                 '#define %s' % expected_guard,
2139                                 '#endif // %s' % expected_guard],
2140                                error_collector)
2141         for line in error_collector.result_list():
2142             if line.find('build/header_guard') != -1:
2143                 self.fail('Unexpected error: %s' % line)
2144
2145         # Completely incorrect header guard
2146         error_collector = ErrorCollector(self.assert_)
2147         self.process_file_data(file_path, 'h',
2148                                ['#ifndef FOO',
2149                                 '#define FOO',
2150                                 '#endif  // FOO'],
2151                                error_collector)
2152         self.assertEquals(
2153             1,
2154             error_collector.result_list().count(
2155                 '#ifndef header guard has wrong style, please use: %s'
2156                 '  [build/header_guard] [5]' % expected_guard),
2157             error_collector.result_list())
2158
2159         # Special case for flymake
2160         error_collector = ErrorCollector(self.assert_)
2161         self.process_file_data('mydir/Foo_flymake.h', 'h',
2162                                ['#ifndef %s' % expected_guard,
2163                                 '#define %s' % expected_guard,
2164                                 '#endif // %s' % expected_guard],
2165                                error_collector)
2166         for line in error_collector.result_list():
2167             if line.find('build/header_guard') != -1:
2168                 self.fail('Unexpected error: %s' % line)
2169
2170         error_collector = ErrorCollector(self.assert_)
2171         self.process_file_data('mydir/Foo_flymake.h', 'h', [], error_collector)
2172         self.assertEquals(
2173             1,
2174             error_collector.result_list().count(
2175                 'No #ifndef header guard found, suggested CPP variable is: %s'
2176                 '  [build/header_guard] [5]' % expected_guard),
2177             error_collector.result_list())
2178
2179         # Allow the WTF_ prefix for files in that directory.
2180         header_guard_filter = FilterConfiguration(('-', '+build/header_guard'))
2181         error_collector = ErrorCollector(self.assert_, header_guard_filter)
2182         self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h',
2183                                ['#ifndef WTF_TestName_h', '#define WTF_TestName_h'],
2184                                error_collector)
2185         self.assertEquals(0, len(error_collector.result_list()),
2186                           error_collector.result_list())
2187
2188         # Also allow the non WTF_ prefix for files in that directory.
2189         error_collector = ErrorCollector(self.assert_, header_guard_filter)
2190         self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h',
2191                                ['#ifndef TestName_h', '#define TestName_h'],
2192                                error_collector)
2193         self.assertEquals(0, len(error_collector.result_list()),
2194                           error_collector.result_list())
2195
2196         # Verify that we suggest the WTF prefix version.
2197         error_collector = ErrorCollector(self.assert_, header_guard_filter)
2198         self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h',
2199                                ['#ifndef BAD_TestName_h', '#define BAD_TestName_h'],
2200                                error_collector)
2201         self.assertEquals(
2202             1,
2203             error_collector.result_list().count(
2204                 '#ifndef header guard has wrong style, please use: WTF_TestName_h'
2205                 '  [build/header_guard] [5]'),
2206             error_collector.result_list())
2207
2208     def test_build_printf_format(self):
2209         self.assert_lint(
2210             r'printf("\%%d", value);',
2211             '%, [, (, and { are undefined character escapes.  Unescape them.'
2212             '  [build/printf_format] [3]')
2213
2214         self.assert_lint(
2215             r'snprintf(buffer, sizeof(buffer), "\[%d", value);',
2216             '%, [, (, and { are undefined character escapes.  Unescape them.'
2217             '  [build/printf_format] [3]')
2218
2219         self.assert_lint(
2220             r'fprintf(file, "\(%d", value);',
2221             '%, [, (, and { are undefined character escapes.  Unescape them.'
2222             '  [build/printf_format] [3]')
2223
2224         self.assert_lint(
2225             r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);',
2226             '%, [, (, and { are undefined character escapes.  Unescape them.'
2227             '  [build/printf_format] [3]')
2228
2229         # Don't warn if double-slash precedes the symbol
2230         self.assert_lint(r'printf("\\%%%d", value);',
2231                          '')
2232
2233     def test_runtime_printf_format(self):
2234         self.assert_lint(
2235             r'fprintf(file, "%q", value);',
2236             '%q in format strings is deprecated.  Use %ll instead.'
2237             '  [runtime/printf_format] [3]')
2238
2239         self.assert_lint(
2240             r'aprintf(file, "The number is %12q", value);',
2241             '%q in format strings is deprecated.  Use %ll instead.'
2242             '  [runtime/printf_format] [3]')
2243
2244         self.assert_lint(
2245             r'printf(file, "The number is" "%-12q", value);',
2246             '%q in format strings is deprecated.  Use %ll instead.'
2247             '  [runtime/printf_format] [3]')
2248
2249         self.assert_lint(
2250             r'printf(file, "The number is" "%+12q", value);',
2251             '%q in format strings is deprecated.  Use %ll instead.'
2252             '  [runtime/printf_format] [3]')
2253
2254         self.assert_lint(
2255             r'printf(file, "The number is" "% 12q", value);',
2256             '%q in format strings is deprecated.  Use %ll instead.'
2257             '  [runtime/printf_format] [3]')
2258
2259         self.assert_lint(
2260             r'snprintf(file, "Never mix %d and %1$d parmaeters!", value);',
2261             '%N$ formats are unconventional.  Try rewriting to avoid them.'
2262             '  [runtime/printf_format] [2]')
2263
2264     def assert_lintLogCodeOnError(self, code, expected_message):
2265         # Special assert_lint which logs the input code on error.
2266         result = self.perform_single_line_lint(code, 'foo.cpp')
2267         if result != expected_message:
2268             self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"'
2269                       % (code, result, expected_message))
2270
2271     def test_build_storage_class(self):
2272         qualifiers = [None, 'const', 'volatile']
2273         signs = [None, 'signed', 'unsigned']
2274         types = ['void', 'char', 'int', 'float', 'double',
2275                  'schar', 'int8', 'uint8', 'int16', 'uint16',
2276                  'int32', 'uint32', 'int64', 'uint64']
2277         storage_classes = ['auto', 'extern', 'register', 'static', 'typedef']
2278
2279         build_storage_class_error_message = (
2280             'Storage class (static, extern, typedef, etc) should be first.'
2281             '  [build/storage_class] [5]')
2282
2283         # Some explicit cases. Legal in C++, deprecated in C99.
2284         self.assert_lint('const int static foo = 5;',
2285                          build_storage_class_error_message)
2286
2287         self.assert_lint('char static foo;',
2288                          build_storage_class_error_message)
2289
2290         self.assert_lint('double const static foo = 2.0;',
2291                          build_storage_class_error_message)
2292
2293         self.assert_lint('uint64 typedef unsignedLongLong;',
2294                          build_storage_class_error_message)
2295
2296         self.assert_lint('int register foo = 0;',
2297                          build_storage_class_error_message)
2298
2299         # Since there are a very large number of possibilities, randomly
2300         # construct declarations.
2301         # Make sure that the declaration is logged if there's an error.
2302         # Seed generator with an integer for absolute reproducibility.
2303         random.seed(25)
2304         for unused_i in range(10):
2305             # Build up random list of non-storage-class declaration specs.
2306             other_decl_specs = [random.choice(qualifiers), random.choice(signs),
2307                                 random.choice(types)]
2308             # remove None
2309             other_decl_specs = filter(lambda x: x is not None, other_decl_specs)
2310
2311             # shuffle
2312             random.shuffle(other_decl_specs)
2313
2314             # insert storage class after the first
2315             storage_class = random.choice(storage_classes)
2316             insertion_point = random.randint(1, len(other_decl_specs))
2317             decl_specs = (other_decl_specs[0:insertion_point]
2318                           + [storage_class]
2319                           + other_decl_specs[insertion_point:])
2320
2321             self.assert_lintLogCodeOnError(
2322                 ' '.join(decl_specs) + ';',
2323                 build_storage_class_error_message)
2324
2325             # but no error if storage class is first
2326             self.assert_lintLogCodeOnError(
2327                 storage_class + ' ' + ' '.join(other_decl_specs),
2328                 '')
2329
2330     def test_legal_copyright(self):
2331         legal_copyright_message = (
2332             'No copyright message found.  '
2333             'You should have a line: "Copyright [year] <Copyright Owner>"'
2334             '  [legal/copyright] [5]')
2335
2336         copyright_line = '// Copyright 2008 Google Inc. All Rights Reserved.'
2337
2338         file_path = 'mydir/googleclient/foo.cpp'
2339
2340         # There should be a copyright message in the first 10 lines
2341         error_collector = ErrorCollector(self.assert_)
2342         self.process_file_data(file_path, 'cpp', [], error_collector)
2343         self.assertEquals(
2344             1,
2345             error_collector.result_list().count(legal_copyright_message))
2346
2347         error_collector = ErrorCollector(self.assert_)
2348         self.process_file_data(
2349             file_path, 'cpp',
2350             ['' for unused_i in range(10)] + [copyright_line],
2351             error_collector)
2352         self.assertEquals(
2353             1,
2354             error_collector.result_list().count(legal_copyright_message))
2355
2356         # Test that warning isn't issued if Copyright line appears early enough.
2357         error_collector = ErrorCollector(self.assert_)
2358         self.process_file_data(file_path, 'cpp', [copyright_line], error_collector)
2359         for message in error_collector.result_list():
2360             if message.find('legal/copyright') != -1:
2361                 self.fail('Unexpected error: %s' % message)
2362
2363         error_collector = ErrorCollector(self.assert_)
2364         self.process_file_data(
2365             file_path, 'cpp',
2366             ['' for unused_i in range(9)] + [copyright_line],
2367             error_collector)
2368         for message in error_collector.result_list():
2369             if message.find('legal/copyright') != -1:
2370                 self.fail('Unexpected error: %s' % message)
2371
2372     def test_invalid_increment(self):
2373         self.assert_lint('*count++;',
2374                          'Changing pointer instead of value (or unused value of '
2375                          'operator*).  [runtime/invalid_increment] [5]')
2376
2377     # Integral bitfields must be declared with either signed or unsigned keyword.
2378     def test_plain_integral_bitfields(self):
2379         errmsg = ('Please declare integral type bitfields with either signed or unsigned.  [runtime/bitfields] [5]')
2380
2381         self.assert_lint('int a : 30;', errmsg)
2382         self.assert_lint('mutable short a : 14;', errmsg)
2383         self.assert_lint('const char a : 6;', errmsg)
2384         self.assert_lint('long int a : 30;', errmsg)
2385         self.assert_lint('int a = 1 ? 0 : 30;', '')
2386
2387 class CleansedLinesTest(unittest.TestCase):
2388     def test_init(self):
2389         lines = ['Line 1',
2390                  'Line 2',
2391                  'Line 3 // Comment test',
2392                  'Line 4 "foo"']
2393
2394         clean_lines = cpp_style.CleansedLines(lines)
2395         self.assertEquals(lines, clean_lines.raw_lines)
2396         self.assertEquals(4, clean_lines.num_lines())
2397
2398         self.assertEquals(['Line 1',
2399                            'Line 2',
2400                            'Line 3 ',
2401                            'Line 4 "foo"'],
2402                           clean_lines.lines)
2403
2404         self.assertEquals(['Line 1',
2405                            'Line 2',
2406                            'Line 3 ',
2407                            'Line 4 ""'],
2408                           clean_lines.elided)
2409
2410     def test_init_empty(self):
2411         clean_lines = cpp_style.CleansedLines([])
2412         self.assertEquals([], clean_lines.raw_lines)
2413         self.assertEquals(0, clean_lines.num_lines())
2414
2415     def test_collapse_strings(self):
2416         collapse = cpp_style.CleansedLines.collapse_strings
2417         self.assertEquals('""', collapse('""'))             # ""     (empty)
2418         self.assertEquals('"""', collapse('"""'))           # """    (bad)
2419         self.assertEquals('""', collapse('"xyz"'))          # "xyz"  (string)
2420         self.assertEquals('""', collapse('"\\\""'))         # "\""   (string)
2421         self.assertEquals('""', collapse('"\'"'))           # "'"    (string)
2422         self.assertEquals('"\"', collapse('"\"'))           # "\"    (bad)
2423         self.assertEquals('""', collapse('"\\\\"'))         # "\\"   (string)
2424         self.assertEquals('"', collapse('"\\\\\\"'))        # "\\\"  (bad)
2425         self.assertEquals('""', collapse('"\\\\\\\\"'))     # "\\\\" (string)
2426
2427         self.assertEquals('\'\'', collapse('\'\''))         # ''     (empty)
2428         self.assertEquals('\'\'', collapse('\'a\''))        # 'a'    (char)
2429         self.assertEquals('\'\'', collapse('\'\\\'\''))     # '\''   (char)
2430         self.assertEquals('\'', collapse('\'\\\''))         # '\'    (bad)
2431         self.assertEquals('', collapse('\\012'))            # '\012' (char)
2432         self.assertEquals('', collapse('\\xfF0'))           # '\xfF0' (char)
2433         self.assertEquals('', collapse('\\n'))              # '\n' (char)
2434         self.assertEquals('\#', collapse('\\#'))            # '\#' (bad)
2435
2436         self.assertEquals('StringReplace(body, "", "");',
2437                           collapse('StringReplace(body, "\\\\", "\\\\\\\\");'))
2438         self.assertEquals('\'\' ""',
2439                           collapse('\'"\' "foo"'))
2440
2441
2442 class OrderOfIncludesTest(CppStyleTestBase):
2443     def setUp(self):
2444         self.include_state = cpp_style._IncludeState()
2445
2446         # Cheat os.path.abspath called in FileInfo class.
2447         self.os_path_abspath_orig = os.path.abspath
2448         os.path.abspath = lambda value: value
2449
2450     def tearDown(self):
2451         os.path.abspath = self.os_path_abspath_orig
2452
2453     def test_try_drop_common_suffixes(self):
2454         self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h'))
2455         self.assertEqual('foo/bar/foo',
2456                          cpp_style._drop_common_suffixes('foo/bar/foo_inl.h'))
2457         self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp'))
2458         self.assertEqual('foo/foo_unusualinternal',
2459                          cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h'))
2460         self.assertEqual('',
2461                          cpp_style._drop_common_suffixes('_test.cpp'))
2462         self.assertEqual('test',
2463                          cpp_style._drop_common_suffixes('test.cpp'))
2464
2465
2466 class OrderOfIncludesTest(CppStyleTestBase):
2467     def setUp(self):
2468         self.include_state = cpp_style._IncludeState()
2469
2470         # Cheat os.path.abspath called in FileInfo class.
2471         self.os_path_abspath_orig = os.path.abspath
2472         self.os_path_isfile_orig = os.path.isfile
2473         os.path.abspath = lambda value: value
2474
2475     def tearDown(self):
2476         os.path.abspath = self.os_path_abspath_orig
2477         os.path.isfile = self.os_path_isfile_orig
2478
2479     def test_check_next_include_order__no_config(self):
2480         self.assertEqual('Header file should not contain WebCore config.h.',
2481                          self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, True, True))
2482
2483     def test_check_next_include_order__no_self(self):
2484         self.assertEqual('Header file should not contain itself.',
2485                          self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, True, True))
2486         # Test actual code to make sure that header types are correctly assigned.
2487         self.assert_language_rules_check('Foo.h',
2488                                          '#include "Foo.h"\n',
2489                                          'Header file should not contain itself. Should be: alphabetically sorted.'
2490                                          '  [build/include_order] [4]')
2491         self.assert_language_rules_check('FooBar.h',
2492                                          '#include "Foo.h"\n',
2493                                          '')
2494
2495     def test_check_next_include_order__likely_then_config(self):
2496         self.assertEqual('Found header this file implements before WebCore config.h.',
2497                          self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False, True))
2498         self.assertEqual('Found WebCore config.h after a header this file implements.',
2499                          self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
2500
2501     def test_check_next_include_order__other_then_config(self):
2502         self.assertEqual('Found other header before WebCore config.h.',
2503                          self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False, True))
2504         self.assertEqual('Found WebCore config.h after other header.',
2505                          self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
2506
2507     def test_check_next_include_order__config_then_other_then_likely(self):
2508         self.assertEqual('', self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
2509         self.assertEqual('Found other header before a header this file implements.',
2510                          self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False, True))
2511         self.assertEqual('Found header this file implements after other header.',
2512                          self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False, True))
2513
2514     def test_check_alphabetical_include_order(self):
2515         self.assert_language_rules_check('foo.h',
2516                                          '#include "a.h"\n'
2517                                          '#include "c.h"\n'
2518                                          '#include "b.h"\n',
2519                                          'Alphabetical sorting problem.  [build/include_order] [4]')
2520
2521         self.assert_language_rules_check('foo.h',
2522                                          '#include "a.h"\n'
2523                                          '#include "b.h"\n'
2524                                          '#include "c.h"\n',
2525                                          '')
2526
2527         self.assert_language_rules_check('foo.h',
2528                                          '#include <assert.h>\n'
2529                                          '#include "bar.h"\n',
2530                                          'Alphabetical sorting problem.  [build/include_order] [4]')
2531
2532         self.assert_language_rules_check('foo.h',
2533                                          '#include "bar.h"\n'
2534                                          '#include <assert.h>\n',
2535                                          '')
2536
2537     def test_check_line_break_after_own_header(self):
2538         self.assert_language_rules_check('foo.cpp',
2539                                          '#include "config.h"\n'
2540                                          '#include "foo.h"\n'
2541                                          '#include "bar.h"\n',
2542                                          'You should add a blank line after implementation file\'s own header.  [build/include_order] [4]')
2543
2544         self.assert_language_rules_check('foo.cpp',
2545                                          '#include "config.h"\n'
2546                                          '#include "foo.h"\n'
2547                                          '\n'
2548                                          '#include "bar.h"\n',
2549                                          '')
2550
2551     def test_check_preprocessor_in_include_section(self):
2552         self.assert_language_rules_check('foo.cpp',
2553                                          '#include "config.h"\n'
2554                                          '#include "foo.h"\n'
2555                                          '\n'
2556                                          '#ifdef BAZ\n'
2557                                          '#include "baz.h"\n'
2558                                          '#else\n'
2559                                          '#include "foobar.h"\n'
2560                                          '#endif"\n'
2561                                          '#include "bar.h"\n', # No flag because previous is in preprocessor section
2562                                          '')
2563
2564         self.assert_language_rules_check('foo.cpp',
2565                                          '#include "config.h"\n'
2566                                          '#include "foo.h"\n'
2567                                          '\n'
2568                                          '#ifdef BAZ\n'
2569                                          '#include "baz.h"\n'
2570                                          '#endif"\n'
2571                                          '#include "bar.h"\n'
2572                                          '#include "a.h"\n', # Should still flag this.
2573                                          'Alphabetical sorting problem.  [build/include_order] [4]')
2574
2575         self.assert_language_rules_check('foo.cpp',
2576                                          '#include "config.h"\n'
2577                                          '#include "foo.h"\n'
2578                                          '\n'
2579                                          '#ifdef BAZ\n'
2580                                          '#include "baz.h"\n'
2581                                          '#include "bar.h"\n' #Should still flag this
2582                                          '#endif"\n',
2583                                          'Alphabetical sorting problem.  [build/include_order] [4]')
2584
2585         self.assert_language_rules_check('foo.cpp',
2586                                          '#include "config.h"\n'
2587                                          '#include "foo.h"\n'
2588                                          '\n'
2589                                          '#ifdef BAZ\n'
2590                                          '#include "baz.h"\n'
2591                                          '#endif"\n'
2592                                          '#ifdef FOOBAR\n'
2593                                          '#include "foobar.h"\n'
2594                                          '#endif"\n'
2595                                          '#include "bar.h"\n'
2596                                          '#include "a.h"\n', # Should still flag this.
2597                                          'Alphabetical sorting problem.  [build/include_order] [4]')
2598
2599         # Check that after an already included error, the sorting rules still work.
2600         self.assert_language_rules_check('foo.cpp',
2601                                          '#include "config.h"\n'
2602                                          '#include "foo.h"\n'
2603                                          '\n'
2604                                          '#include "foo.h"\n'
2605                                          '#include "g.h"\n',
2606                                          '"foo.h" already included at foo.cpp:2  [build/include] [4]')
2607
2608     def test_primary_header(self):
2609         # File with non-existing primary header should not produce errors.
2610         self.assert_language_rules_check('foo.cpp',
2611                                          '#include "config.h"\n'
2612                                          '\n'
2613                                          '#include "bar.h"\n',
2614                                          '')
2615         # Pretend that header files exist.
2616         os.path.isfile = lambda filename: True
2617         # Missing include for existing primary header -> error.
2618         self.assert_language_rules_check('foo.cpp',
2619                                          '#include "config.h"\n'
2620                                          '\n'
2621                                          '#include "bar.h"\n',
2622                                          'Found other header before a header this file implements. '
2623                                          'Should be: config.h, primary header, blank line, and then '
2624                                          'alphabetically sorted.  [build/include_order] [4]')
2625         # Having include for existing primary header -> no error.
2626         self.assert_language_rules_check('foo.cpp',
2627                                          '#include "config.h"\n'
2628                                          '#include "foo.h"\n'
2629                                          '\n'
2630                                          '#include "bar.h"\n',
2631                                          '')
2632
2633         os.path.isfile = self.os_path_isfile_orig
2634
2635
2636     def test_check_wtf_includes(self):
2637         self.assert_language_rules_check('foo.cpp',
2638                                          '#include "config.h"\n'
2639                                          '#include "foo.h"\n'
2640                                          '\n'
2641                                          '#include <wtf/Assertions.h>\n',
2642                                          '')
2643         self.assert_language_rules_check('foo.cpp',
2644                                          '#include "config.h"\n'
2645                                          '#include "foo.h"\n'
2646                                          '\n'
2647                                          '#include "wtf/Assertions.h"\n',
2648                                          'wtf includes should be <wtf/file.h> instead of "wtf/file.h".'
2649                                          '  [build/include] [4]')
2650
2651     def test_classify_include(self):
2652         classify_include = cpp_style._classify_include
2653         include_state = cpp_style._IncludeState()
2654         self.assertEqual(cpp_style._CONFIG_HEADER,
2655                          classify_include('foo/foo.cpp',
2656                                           'config.h',
2657                                           False, include_state))
2658         self.assertEqual(cpp_style._PRIMARY_HEADER,
2659                          classify_include('foo/internal/foo.cpp',
2660                                           'foo/public/foo.h',
2661                                           False, include_state))
2662         self.assertEqual(cpp_style._PRIMARY_HEADER,
2663                          classify_include('foo/internal/foo.cpp',
2664                                           'foo/other/public/foo.h',
2665                                           False, include_state))
2666         self.assertEqual(cpp_style._OTHER_HEADER,
2667                          classify_include('foo/internal/foo.cpp',
2668                                           'foo/other/public/foop.h',
2669                                           False, include_state))
2670         self.assertEqual(cpp_style._OTHER_HEADER,
2671                          classify_include('foo/foo.cpp',
2672                                           'string',
2673                                           True, include_state))
2674         self.assertEqual(cpp_style._PRIMARY_HEADER,
2675                          classify_include('fooCustom.cpp',
2676                                           'foo.h',
2677                                           False, include_state))
2678         self.assertEqual(cpp_style._PRIMARY_HEADER,
2679                          classify_include('PrefixFooCustom.cpp',
2680                                           'Foo.h',
2681                                           False, include_state))
2682         self.assertEqual(cpp_style._MOC_HEADER,
2683                          classify_include('foo.cpp',
2684                                           'foo.moc',
2685                                           False, include_state))
2686         self.assertEqual(cpp_style._MOC_HEADER,
2687                          classify_include('foo.cpp',
2688                                           'moc_foo.cpp',
2689                                           False, include_state))
2690         # Tricky example where both includes might be classified as primary.
2691         self.assert_language_rules_check('ScrollbarThemeWince.cpp',
2692                                          '#include "config.h"\n'
2693                                          '#include "ScrollbarThemeWince.h"\n'
2694                                          '\n'
2695                                          '#include "Scrollbar.h"\n',
2696                                          '')
2697         self.assert_language_rules_check('ScrollbarThemeWince.cpp',
2698                                          '#include "config.h"\n'
2699                                          '#include "Scrollbar.h"\n'
2700                                          '\n'
2701                                          '#include "ScrollbarThemeWince.h"\n',
2702                                          'Found header this file implements after a header this file implements.'
2703                                          ' Should be: config.h, primary header, blank line, and then alphabetically sorted.'
2704                                          '  [build/include_order] [4]')
2705         self.assert_language_rules_check('ResourceHandleWin.cpp',
2706                                          '#include "config.h"\n'
2707                                          '#include "ResourceHandle.h"\n'
2708                                          '\n'
2709                                          '#include "ResourceHandleWin.h"\n',
2710                                          '')
2711
2712     def test_try_drop_common_suffixes(self):
2713         self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h'))
2714         self.assertEqual('foo/bar/foo',
2715                          cpp_style._drop_common_suffixes('foo/bar/foo_inl.h'))
2716         self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp'))
2717         self.assertEqual('foo/foo_unusualinternal',
2718                          cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h'))
2719         self.assertEqual('',
2720                          cpp_style._drop_common_suffixes('_test.cpp'))
2721         self.assertEqual('test',
2722                          cpp_style._drop_common_suffixes('test.cpp'))
2723         self.assertEqual('test',
2724                          cpp_style._drop_common_suffixes('test.cpp'))
2725
2726 class CheckForFunctionLengthsTest(CppStyleTestBase):
2727     def setUp(self):
2728         # Reducing these thresholds for the tests speeds up tests significantly.
2729         self.old_normal_trigger = cpp_style._FunctionState._NORMAL_TRIGGER
2730         self.old_test_trigger = cpp_style._FunctionState._TEST_TRIGGER
2731
2732         cpp_style._FunctionState._NORMAL_TRIGGER = 10
2733         cpp_style._FunctionState._TEST_TRIGGER = 25
2734
2735     def tearDown(self):
2736         cpp_style._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger
2737         cpp_style._FunctionState._TEST_TRIGGER = self.old_test_trigger
2738
2739     # FIXME: Eliminate the need for this function.
2740     def set_min_confidence(self, min_confidence):
2741         """Set new test confidence and return old test confidence."""
2742         old_min_confidence = self.min_confidence
2743         self.min_confidence = min_confidence
2744         return old_min_confidence
2745
2746     def assert_function_lengths_check(self, code, expected_message):
2747         """Check warnings for long function bodies are as expected.
2748
2749         Args:
2750           code: C++ source code expected to generate a warning message.
2751           expected_message: Message expected to be generated by the C++ code.
2752         """
2753         self.assertEquals(expected_message,
2754                           self.perform_function_lengths_check(code))
2755
2756     def trigger_lines(self, error_level):
2757         """Return number of lines needed to trigger a function length warning.
2758
2759         Args:
2760           error_level: --v setting for cpp_style.
2761
2762         Returns:
2763           Number of lines needed to trigger a function length warning.
2764         """
2765         return cpp_style._FunctionState._NORMAL_TRIGGER * 2 ** error_level
2766
2767     def trigger_test_lines(self, error_level):
2768         """Return number of lines needed to trigger a test function length warning.
2769
2770         Args:
2771           error_level: --v setting for cpp_style.
2772
2773         Returns:
2774           Number of lines needed to trigger a test function length warning.
2775         """
2776         return cpp_style._FunctionState._TEST_TRIGGER * 2 ** error_level
2777
2778     def assert_function_length_check_definition(self, lines, error_level):
2779         """Generate long function definition and check warnings are as expected.
2780
2781         Args:
2782           lines: Number of lines to generate.
2783           error_level:  --v setting for cpp_style.
2784         """
2785         trigger_level = self.trigger_lines(self.min_confidence)
2786         self.assert_function_lengths_check(
2787             'void test(int x)' + self.function_body(lines),
2788             ('Small and focused functions are preferred: '
2789              'test() has %d non-comment lines '
2790              '(error triggered by exceeding %d lines).'
2791              '  [readability/fn_size] [%d]'
2792              % (lines, trigger_level, error_level)))
2793
2794     def assert_function_length_check_definition_ok(self, lines):
2795         """Generate shorter function definition and check no warning is produced.
2796
2797         Args:
2798           lines: Number of lines to generate.
2799         """
2800         self.assert_function_lengths_check(
2801             'void test(int x)' + self.function_body(lines),
2802             '')
2803
2804     def assert_function_length_check_at_error_level(self, error_level):
2805         """Generate and check function at the trigger level for --v setting.
2806
2807         Args:
2808           error_level: --v setting for cpp_style.
2809         """
2810         self.assert_function_length_check_definition(self.trigger_lines(error_level),
2811                                                      error_level)
2812
2813     def assert_function_length_check_below_error_level(self, error_level):
2814         """Generate and check function just below the trigger level for --v setting.
2815
2816         Args:
2817           error_level: --v setting for cpp_style.
2818         """
2819         self.assert_function_length_check_definition(self.trigger_lines(error_level) - 1,
2820                                                      error_level - 1)
2821
2822     def assert_function_length_check_above_error_level(self, error_level):
2823         """Generate and check function just above the trigger level for --v setting.
2824
2825         Args:
2826           error_level: --v setting for cpp_style.