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