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