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