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