1*8c35d5eeSXin Li#!/usr/bin/python 2*8c35d5eeSXin Li# -*- coding: utf-8; -*- 3*8c35d5eeSXin Li# 4*8c35d5eeSXin Li# Copyright (c) 2009 Google Inc. All rights reserved. 5*8c35d5eeSXin Li# 6*8c35d5eeSXin Li# Redistribution and use in source and binary forms, with or without 7*8c35d5eeSXin Li# modification, are permitted provided that the following conditions are 8*8c35d5eeSXin Li# met: 9*8c35d5eeSXin Li# 10*8c35d5eeSXin Li# * Redistributions of source code must retain the above copyright 11*8c35d5eeSXin Li# notice, this list of conditions and the following disclaimer. 12*8c35d5eeSXin Li# * Redistributions in binary form must reproduce the above 13*8c35d5eeSXin Li# copyright notice, this list of conditions and the following disclaimer 14*8c35d5eeSXin Li# in the documentation and/or other materials provided with the 15*8c35d5eeSXin Li# distribution. 16*8c35d5eeSXin Li# * Neither the name of Google Inc. nor the names of its 17*8c35d5eeSXin Li# contributors may be used to endorse or promote products derived from 18*8c35d5eeSXin Li# this software without specific prior written permission. 19*8c35d5eeSXin Li# 20*8c35d5eeSXin Li# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21*8c35d5eeSXin Li# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*8c35d5eeSXin Li# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23*8c35d5eeSXin Li# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24*8c35d5eeSXin Li# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25*8c35d5eeSXin Li# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26*8c35d5eeSXin Li# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27*8c35d5eeSXin Li# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28*8c35d5eeSXin Li# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29*8c35d5eeSXin Li# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30*8c35d5eeSXin Li# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31*8c35d5eeSXin Li 32*8c35d5eeSXin Li"""Unit test for cpplint.py.""" 33*8c35d5eeSXin Li 34*8c35d5eeSXin Li# TODO(unknown): Add a good test that tests UpdateIncludeState. 35*8c35d5eeSXin Li 36*8c35d5eeSXin Liimport codecs 37*8c35d5eeSXin Liimport os 38*8c35d5eeSXin Liimport random 39*8c35d5eeSXin Liimport re 40*8c35d5eeSXin Liimport subprocess 41*8c35d5eeSXin Liimport sys 42*8c35d5eeSXin Liimport unittest 43*8c35d5eeSXin Li 44*8c35d5eeSXin Liimport cpplint 45*8c35d5eeSXin Li 46*8c35d5eeSXin Litry: 47*8c35d5eeSXin Li xrange # Python 2 48*8c35d5eeSXin Liexcept NameError: 49*8c35d5eeSXin Li xrange = range # Python 3 50*8c35d5eeSXin Li 51*8c35d5eeSXin Li 52*8c35d5eeSXin Li# This class works as an error collector and replaces cpplint.Error 53*8c35d5eeSXin Li# function for the unit tests. We also verify each category we see 54*8c35d5eeSXin Li# is in cpplint._ERROR_CATEGORIES, to help keep that list up to date. 55*8c35d5eeSXin Liclass ErrorCollector(object): 56*8c35d5eeSXin Li # These are a global list, covering all categories seen ever. 57*8c35d5eeSXin Li _ERROR_CATEGORIES = cpplint._ERROR_CATEGORIES 58*8c35d5eeSXin Li _SEEN_ERROR_CATEGORIES = {} 59*8c35d5eeSXin Li 60*8c35d5eeSXin Li def __init__(self, assert_fn): 61*8c35d5eeSXin Li """assert_fn: a function to call when we notice a problem.""" 62*8c35d5eeSXin Li self._assert_fn = assert_fn 63*8c35d5eeSXin Li self._errors = [] 64*8c35d5eeSXin Li cpplint.ResetNolintSuppressions() 65*8c35d5eeSXin Li 66*8c35d5eeSXin Li def __call__(self, unused_filename, linenum, 67*8c35d5eeSXin Li category, confidence, message): 68*8c35d5eeSXin Li self._assert_fn(category in self._ERROR_CATEGORIES, 69*8c35d5eeSXin Li 'Message "%s" has category "%s",' 70*8c35d5eeSXin Li ' which is not in _ERROR_CATEGORIES' % (message, category)) 71*8c35d5eeSXin Li self._SEEN_ERROR_CATEGORIES[category] = 1 72*8c35d5eeSXin Li if cpplint._ShouldPrintError(category, confidence, linenum): 73*8c35d5eeSXin Li self._errors.append('%s [%s] [%d]' % (message, category, confidence)) 74*8c35d5eeSXin Li 75*8c35d5eeSXin Li def Results(self): 76*8c35d5eeSXin Li if len(self._errors) < 2: 77*8c35d5eeSXin Li return ''.join(self._errors) # Most tests expect to have a string. 78*8c35d5eeSXin Li else: 79*8c35d5eeSXin Li return self._errors # Let's give a list if there is more than one. 80*8c35d5eeSXin Li 81*8c35d5eeSXin Li def ResultList(self): 82*8c35d5eeSXin Li return self._errors 83*8c35d5eeSXin Li 84*8c35d5eeSXin Li def VerifyAllCategoriesAreSeen(self): 85*8c35d5eeSXin Li """Fails if there's a category in _ERROR_CATEGORIES~_SEEN_ERROR_CATEGORIES. 86*8c35d5eeSXin Li 87*8c35d5eeSXin Li This should only be called after all tests are run, so 88*8c35d5eeSXin Li _SEEN_ERROR_CATEGORIES has had a chance to fully populate. Since 89*8c35d5eeSXin Li this isn't called from within the normal unittest framework, we 90*8c35d5eeSXin Li can't use the normal unittest assert macros. Instead we just exit 91*8c35d5eeSXin Li when we see an error. Good thing this test is always run last! 92*8c35d5eeSXin Li """ 93*8c35d5eeSXin Li for category in self._ERROR_CATEGORIES: 94*8c35d5eeSXin Li if category not in self._SEEN_ERROR_CATEGORIES: 95*8c35d5eeSXin Li sys.exit('FATAL ERROR: There are no tests for category "%s"' % category) 96*8c35d5eeSXin Li 97*8c35d5eeSXin Li def RemoveIfPresent(self, substr): 98*8c35d5eeSXin Li for (index, error) in enumerate(self._errors): 99*8c35d5eeSXin Li if error.find(substr) != -1: 100*8c35d5eeSXin Li self._errors = self._errors[0:index] + self._errors[(index + 1):] 101*8c35d5eeSXin Li break 102*8c35d5eeSXin Li 103*8c35d5eeSXin Li 104*8c35d5eeSXin Li# This class is a lame mock of codecs. We do not verify filename, mode, or 105*8c35d5eeSXin Li# encoding, but for the current use case it is not needed. 106*8c35d5eeSXin Liclass MockIo(object): 107*8c35d5eeSXin Li 108*8c35d5eeSXin Li def __init__(self, mock_file): 109*8c35d5eeSXin Li self.mock_file = mock_file 110*8c35d5eeSXin Li 111*8c35d5eeSXin Li def open(self, # pylint: disable-msg=C6409 112*8c35d5eeSXin Li unused_filename, unused_mode, unused_encoding, _): 113*8c35d5eeSXin Li return self.mock_file 114*8c35d5eeSXin Li 115*8c35d5eeSXin Li 116*8c35d5eeSXin Liclass CpplintTestBase(unittest.TestCase): 117*8c35d5eeSXin Li """Provides some useful helper functions for cpplint tests.""" 118*8c35d5eeSXin Li 119*8c35d5eeSXin Li def setUp(self): 120*8c35d5eeSXin Li # Allow subclasses to cheat os.path.abspath called in FileInfo class. 121*8c35d5eeSXin Li self.os_path_abspath_orig = os.path.abspath 122*8c35d5eeSXin Li 123*8c35d5eeSXin Li def tearDown(self): 124*8c35d5eeSXin Li os.path.abspath = self.os_path_abspath_orig 125*8c35d5eeSXin Li 126*8c35d5eeSXin Li # Perform lint on single line of input and return the error message. 127*8c35d5eeSXin Li def PerformSingleLineLint(self, code): 128*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 129*8c35d5eeSXin Li lines = code.split('\n') 130*8c35d5eeSXin Li cpplint.RemoveMultiLineComments('foo.h', lines, error_collector) 131*8c35d5eeSXin Li clean_lines = cpplint.CleansedLines(lines) 132*8c35d5eeSXin Li include_state = cpplint._IncludeState() 133*8c35d5eeSXin Li function_state = cpplint._FunctionState() 134*8c35d5eeSXin Li nesting_state = cpplint.NestingState() 135*8c35d5eeSXin Li cpplint.ProcessLine('foo.cc', 'cc', clean_lines, 0, 136*8c35d5eeSXin Li include_state, function_state, 137*8c35d5eeSXin Li nesting_state, error_collector) 138*8c35d5eeSXin Li # Single-line lint tests are allowed to fail the 'unlintable function' 139*8c35d5eeSXin Li # check. 140*8c35d5eeSXin Li error_collector.RemoveIfPresent( 141*8c35d5eeSXin Li 'Lint failed to find start of function body.') 142*8c35d5eeSXin Li return error_collector.Results() 143*8c35d5eeSXin Li 144*8c35d5eeSXin Li # Perform lint over multiple lines and return the error message. 145*8c35d5eeSXin Li def PerformMultiLineLint(self, code): 146*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 147*8c35d5eeSXin Li lines = code.split('\n') 148*8c35d5eeSXin Li cpplint.RemoveMultiLineComments('foo.h', lines, error_collector) 149*8c35d5eeSXin Li lines = cpplint.CleansedLines(lines) 150*8c35d5eeSXin Li nesting_state = cpplint.NestingState() 151*8c35d5eeSXin Li for i in xrange(lines.NumLines()): 152*8c35d5eeSXin Li nesting_state.Update('foo.h', lines, i, error_collector) 153*8c35d5eeSXin Li cpplint.CheckStyle('foo.h', lines, i, 'h', nesting_state, 154*8c35d5eeSXin Li error_collector) 155*8c35d5eeSXin Li cpplint.CheckForNonStandardConstructs('foo.h', lines, i, 156*8c35d5eeSXin Li nesting_state, error_collector) 157*8c35d5eeSXin Li nesting_state.CheckCompletedBlocks('foo.h', error_collector) 158*8c35d5eeSXin Li return error_collector.Results() 159*8c35d5eeSXin Li 160*8c35d5eeSXin Li # Similar to PerformMultiLineLint, but calls CheckLanguage instead of 161*8c35d5eeSXin Li # CheckForNonStandardConstructs 162*8c35d5eeSXin Li def PerformLanguageRulesCheck(self, file_name, code): 163*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 164*8c35d5eeSXin Li include_state = cpplint._IncludeState() 165*8c35d5eeSXin Li nesting_state = cpplint.NestingState() 166*8c35d5eeSXin Li lines = code.split('\n') 167*8c35d5eeSXin Li cpplint.RemoveMultiLineComments(file_name, lines, error_collector) 168*8c35d5eeSXin Li lines = cpplint.CleansedLines(lines) 169*8c35d5eeSXin Li ext = file_name[file_name.rfind('.') + 1:] 170*8c35d5eeSXin Li for i in xrange(lines.NumLines()): 171*8c35d5eeSXin Li cpplint.CheckLanguage(file_name, lines, i, ext, include_state, 172*8c35d5eeSXin Li nesting_state, error_collector) 173*8c35d5eeSXin Li return error_collector.Results() 174*8c35d5eeSXin Li 175*8c35d5eeSXin Li def PerformFunctionLengthsCheck(self, code): 176*8c35d5eeSXin Li """Perform Lint function length check on block of code and return warnings. 177*8c35d5eeSXin Li 178*8c35d5eeSXin Li Builds up an array of lines corresponding to the code and strips comments 179*8c35d5eeSXin Li using cpplint functions. 180*8c35d5eeSXin Li 181*8c35d5eeSXin Li Establishes an error collector and invokes the function length checking 182*8c35d5eeSXin Li function following cpplint's pattern. 183*8c35d5eeSXin Li 184*8c35d5eeSXin Li Args: 185*8c35d5eeSXin Li code: C++ source code expected to generate a warning message. 186*8c35d5eeSXin Li 187*8c35d5eeSXin Li Returns: 188*8c35d5eeSXin Li The accumulated errors. 189*8c35d5eeSXin Li """ 190*8c35d5eeSXin Li file_name = 'foo.cc' 191*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 192*8c35d5eeSXin Li function_state = cpplint._FunctionState() 193*8c35d5eeSXin Li lines = code.split('\n') 194*8c35d5eeSXin Li cpplint.RemoveMultiLineComments(file_name, lines, error_collector) 195*8c35d5eeSXin Li lines = cpplint.CleansedLines(lines) 196*8c35d5eeSXin Li for i in xrange(lines.NumLines()): 197*8c35d5eeSXin Li cpplint.CheckForFunctionLengths(file_name, lines, i, 198*8c35d5eeSXin Li function_state, error_collector) 199*8c35d5eeSXin Li return error_collector.Results() 200*8c35d5eeSXin Li 201*8c35d5eeSXin Li def PerformIncludeWhatYouUse(self, code, filename='foo.h', io=codecs): 202*8c35d5eeSXin Li # First, build up the include state. 203*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 204*8c35d5eeSXin Li include_state = cpplint._IncludeState() 205*8c35d5eeSXin Li nesting_state = cpplint.NestingState() 206*8c35d5eeSXin Li lines = code.split('\n') 207*8c35d5eeSXin Li cpplint.RemoveMultiLineComments(filename, lines, error_collector) 208*8c35d5eeSXin Li lines = cpplint.CleansedLines(lines) 209*8c35d5eeSXin Li for i in xrange(lines.NumLines()): 210*8c35d5eeSXin Li cpplint.CheckLanguage(filename, lines, i, '.h', include_state, 211*8c35d5eeSXin Li nesting_state, error_collector) 212*8c35d5eeSXin Li # We could clear the error_collector here, but this should 213*8c35d5eeSXin Li # also be fine, since our IncludeWhatYouUse unittests do not 214*8c35d5eeSXin Li # have language problems. 215*8c35d5eeSXin Li 216*8c35d5eeSXin Li # Second, look for missing includes. 217*8c35d5eeSXin Li cpplint.CheckForIncludeWhatYouUse(filename, lines, include_state, 218*8c35d5eeSXin Li error_collector, io) 219*8c35d5eeSXin Li return error_collector.Results() 220*8c35d5eeSXin Li 221*8c35d5eeSXin Li # Perform lint and compare the error message with "expected_message". 222*8c35d5eeSXin Li def TestLint(self, code, expected_message): 223*8c35d5eeSXin Li self.assertEquals(expected_message, self.PerformSingleLineLint(code)) 224*8c35d5eeSXin Li 225*8c35d5eeSXin Li def TestMultiLineLint(self, code, expected_message): 226*8c35d5eeSXin Li self.assertEquals(expected_message, self.PerformMultiLineLint(code)) 227*8c35d5eeSXin Li 228*8c35d5eeSXin Li def TestMultiLineLintRE(self, code, expected_message_re): 229*8c35d5eeSXin Li message = self.PerformMultiLineLint(code) 230*8c35d5eeSXin Li if not re.search(expected_message_re, message): 231*8c35d5eeSXin Li self.fail('Message was:\n' + message + 'Expected match to "' + 232*8c35d5eeSXin Li expected_message_re + '"') 233*8c35d5eeSXin Li 234*8c35d5eeSXin Li def TestLanguageRulesCheck(self, file_name, code, expected_message): 235*8c35d5eeSXin Li self.assertEquals(expected_message, 236*8c35d5eeSXin Li self.PerformLanguageRulesCheck(file_name, code)) 237*8c35d5eeSXin Li 238*8c35d5eeSXin Li def TestIncludeWhatYouUse(self, code, expected_message): 239*8c35d5eeSXin Li self.assertEquals(expected_message, 240*8c35d5eeSXin Li self.PerformIncludeWhatYouUse(code)) 241*8c35d5eeSXin Li 242*8c35d5eeSXin Li def TestBlankLinesCheck(self, lines, start_errors, end_errors): 243*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 244*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', lines, error_collector) 245*8c35d5eeSXin Li self.assertEquals( 246*8c35d5eeSXin Li start_errors, 247*8c35d5eeSXin Li error_collector.Results().count( 248*8c35d5eeSXin Li 'Redundant blank line at the start of a code block ' 249*8c35d5eeSXin Li 'should be deleted. [whitespace/blank_line] [2]')) 250*8c35d5eeSXin Li self.assertEquals( 251*8c35d5eeSXin Li end_errors, 252*8c35d5eeSXin Li error_collector.Results().count( 253*8c35d5eeSXin Li 'Redundant blank line at the end of a code block ' 254*8c35d5eeSXin Li 'should be deleted. [whitespace/blank_line] [3]')) 255*8c35d5eeSXin Li 256*8c35d5eeSXin Li 257*8c35d5eeSXin Liclass CpplintTest(CpplintTestBase): 258*8c35d5eeSXin Li 259*8c35d5eeSXin Li def GetNamespaceResults(self, lines): 260*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 261*8c35d5eeSXin Li cpplint.RemoveMultiLineComments('foo.h', lines, error_collector) 262*8c35d5eeSXin Li lines = cpplint.CleansedLines(lines) 263*8c35d5eeSXin Li nesting_state = cpplint.NestingState() 264*8c35d5eeSXin Li for i in xrange(lines.NumLines()): 265*8c35d5eeSXin Li nesting_state.Update('foo.h', lines, i, error_collector) 266*8c35d5eeSXin Li cpplint.CheckForNamespaceIndentation('foo.h', nesting_state, 267*8c35d5eeSXin Li lines, i, error_collector) 268*8c35d5eeSXin Li 269*8c35d5eeSXin Li return error_collector.Results() 270*8c35d5eeSXin Li 271*8c35d5eeSXin Li def testForwardDeclarationNameSpaceIndentation(self): 272*8c35d5eeSXin Li lines = ['namespace Test {', 273*8c35d5eeSXin Li ' class ForwardDeclaration;', 274*8c35d5eeSXin Li '} // namespace Test'] 275*8c35d5eeSXin Li 276*8c35d5eeSXin Li results = self.GetNamespaceResults(lines) 277*8c35d5eeSXin Li self.assertEquals(results, 'Do not indent within a namespace ' 278*8c35d5eeSXin Li ' [runtime/indentation_namespace] [4]') 279*8c35d5eeSXin Li 280*8c35d5eeSXin Li def testNameSpaceIndentationForClass(self): 281*8c35d5eeSXin Li lines = ['namespace Test {', 282*8c35d5eeSXin Li 'void foo() { }', 283*8c35d5eeSXin Li ' class Test {', 284*8c35d5eeSXin Li ' };', 285*8c35d5eeSXin Li '} // namespace Test'] 286*8c35d5eeSXin Li 287*8c35d5eeSXin Li results = self.GetNamespaceResults(lines) 288*8c35d5eeSXin Li self.assertEquals(results, 'Do not indent within a namespace ' 289*8c35d5eeSXin Li ' [runtime/indentation_namespace] [4]') 290*8c35d5eeSXin Li 291*8c35d5eeSXin Li def testNameSpaceIndentationNoError(self): 292*8c35d5eeSXin Li lines = ['namespace Test {', 293*8c35d5eeSXin Li 'void foo() { }', 294*8c35d5eeSXin Li '} // namespace Test'] 295*8c35d5eeSXin Li 296*8c35d5eeSXin Li results = self.GetNamespaceResults(lines) 297*8c35d5eeSXin Li self.assertEquals(results, '') 298*8c35d5eeSXin Li 299*8c35d5eeSXin Li def testWhitespaceBeforeNamespace(self): 300*8c35d5eeSXin Li lines = [' namespace Test {', 301*8c35d5eeSXin Li ' void foo() { }', 302*8c35d5eeSXin Li ' } // namespace Test'] 303*8c35d5eeSXin Li 304*8c35d5eeSXin Li results = self.GetNamespaceResults(lines) 305*8c35d5eeSXin Li self.assertEquals(results, '') 306*8c35d5eeSXin Li 307*8c35d5eeSXin Li def testFalsePositivesNoError(self): 308*8c35d5eeSXin Li lines = ['namespace Test {', 309*8c35d5eeSXin Li 'struct OuterClass {', 310*8c35d5eeSXin Li ' struct NoFalsePositivesHere;', 311*8c35d5eeSXin Li ' struct NoFalsePositivesHere member_variable;', 312*8c35d5eeSXin Li '};', 313*8c35d5eeSXin Li '} // namespace Test'] 314*8c35d5eeSXin Li 315*8c35d5eeSXin Li results = self.GetNamespaceResults(lines) 316*8c35d5eeSXin Li self.assertEquals(results, '') 317*8c35d5eeSXin Li 318*8c35d5eeSXin Li 319*8c35d5eeSXin Li # Test get line width. 320*8c35d5eeSXin Li def testGetLineWidth(self): 321*8c35d5eeSXin Li self.assertEquals(0, cpplint.GetLineWidth('')) 322*8c35d5eeSXin Li self.assertEquals(10, cpplint.GetLineWidth(u'x' * 10)) 323*8c35d5eeSXin Li self.assertEquals(16, cpplint.GetLineWidth(u'都|道|府|県|支庁')) 324*8c35d5eeSXin Li self.assertEquals(5 + 13 + 9, cpplint.GetLineWidth( 325*8c35d5eeSXin Li u'd/dt' + u'f : t ⨯ → ℝ' + u't ⨯ → ℝ')) 326*8c35d5eeSXin Li 327*8c35d5eeSXin Li def testGetTextInside(self): 328*8c35d5eeSXin Li self.assertEquals('', cpplint._GetTextInside('fun()', r'fun\(')) 329*8c35d5eeSXin Li self.assertEquals('x, y', cpplint._GetTextInside('f(x, y)', r'f\(')) 330*8c35d5eeSXin Li self.assertEquals('a(), b(c())', cpplint._GetTextInside( 331*8c35d5eeSXin Li 'printf(a(), b(c()))', r'printf\(')) 332*8c35d5eeSXin Li self.assertEquals('x, y{}', cpplint._GetTextInside('f[x, y{}]', r'f\[')) 333*8c35d5eeSXin Li self.assertEquals(None, cpplint._GetTextInside('f[a, b(}]', r'f\[')) 334*8c35d5eeSXin Li self.assertEquals(None, cpplint._GetTextInside('f[x, y]', r'f\(')) 335*8c35d5eeSXin Li self.assertEquals('y, h(z, (a + b))', cpplint._GetTextInside( 336*8c35d5eeSXin Li 'f(x, g(y, h(z, (a + b))))', r'g\(')) 337*8c35d5eeSXin Li self.assertEquals('f(f(x))', cpplint._GetTextInside('f(f(f(x)))', r'f\(')) 338*8c35d5eeSXin Li # Supports multiple lines. 339*8c35d5eeSXin Li self.assertEquals('\n return loop(x);\n', 340*8c35d5eeSXin Li cpplint._GetTextInside( 341*8c35d5eeSXin Li 'int loop(int x) {\n return loop(x);\n}\n', r'\{')) 342*8c35d5eeSXin Li # '^' matches the beginning of each line. 343*8c35d5eeSXin Li self.assertEquals('x, y', 344*8c35d5eeSXin Li cpplint._GetTextInside( 345*8c35d5eeSXin Li '#include "inl.h" // skip #define\n' 346*8c35d5eeSXin Li '#define A2(x, y) a_inl_(x, y, __LINE__)\n' 347*8c35d5eeSXin Li '#define A(x) a_inl_(x, "", __LINE__)\n', 348*8c35d5eeSXin Li r'^\s*#define\s*\w+\(')) 349*8c35d5eeSXin Li 350*8c35d5eeSXin Li def testFindNextMultiLineCommentStart(self): 351*8c35d5eeSXin Li self.assertEquals(1, cpplint.FindNextMultiLineCommentStart([''], 0)) 352*8c35d5eeSXin Li 353*8c35d5eeSXin Li lines = ['a', 'b', '/* c'] 354*8c35d5eeSXin Li self.assertEquals(2, cpplint.FindNextMultiLineCommentStart(lines, 0)) 355*8c35d5eeSXin Li 356*8c35d5eeSXin Li lines = ['char a[] = "/*";'] # not recognized as comment. 357*8c35d5eeSXin Li self.assertEquals(1, cpplint.FindNextMultiLineCommentStart(lines, 0)) 358*8c35d5eeSXin Li 359*8c35d5eeSXin Li def testFindNextMultiLineCommentEnd(self): 360*8c35d5eeSXin Li self.assertEquals(1, cpplint.FindNextMultiLineCommentEnd([''], 0)) 361*8c35d5eeSXin Li lines = ['a', 'b', ' c */'] 362*8c35d5eeSXin Li self.assertEquals(2, cpplint.FindNextMultiLineCommentEnd(lines, 0)) 363*8c35d5eeSXin Li 364*8c35d5eeSXin Li def testRemoveMultiLineCommentsFromRange(self): 365*8c35d5eeSXin Li lines = ['a', ' /* comment ', ' * still comment', ' comment */ ', 'b'] 366*8c35d5eeSXin Li cpplint.RemoveMultiLineCommentsFromRange(lines, 1, 4) 367*8c35d5eeSXin Li self.assertEquals(['a', '/**/', '/**/', '/**/', 'b'], lines) 368*8c35d5eeSXin Li 369*8c35d5eeSXin Li def testSpacesAtEndOfLine(self): 370*8c35d5eeSXin Li self.TestLint( 371*8c35d5eeSXin Li '// Hello there ', 372*8c35d5eeSXin Li 'Line ends in whitespace. Consider deleting these extra spaces.' 373*8c35d5eeSXin Li ' [whitespace/end_of_line] [4]') 374*8c35d5eeSXin Li 375*8c35d5eeSXin Li # Test line length check. 376*8c35d5eeSXin Li def testLineLengthCheck(self): 377*8c35d5eeSXin Li self.TestLint( 378*8c35d5eeSXin Li '// Hello', 379*8c35d5eeSXin Li '') 380*8c35d5eeSXin Li self.TestLint( 381*8c35d5eeSXin Li '// x' + ' x' * 40, 382*8c35d5eeSXin Li 'Lines should be <= 80 characters long' 383*8c35d5eeSXin Li ' [whitespace/line_length] [2]') 384*8c35d5eeSXin Li self.TestLint( 385*8c35d5eeSXin Li '// x' + ' x' * 50, 386*8c35d5eeSXin Li 'Lines should be <= 80 characters long' 387*8c35d5eeSXin Li ' [whitespace/line_length] [2]') 388*8c35d5eeSXin Li self.TestLint( 389*8c35d5eeSXin Li '// //some/path/to/f' + ('i' * 100) + 'le', 390*8c35d5eeSXin Li '') 391*8c35d5eeSXin Li self.TestLint( 392*8c35d5eeSXin Li '// //some/path/to/f' + ('i' * 100) + 'le', 393*8c35d5eeSXin Li '') 394*8c35d5eeSXin Li self.TestLint( 395*8c35d5eeSXin Li '// //some/path/to/f' + ('i' * 50) + 'le and some comments', 396*8c35d5eeSXin Li 'Lines should be <= 80 characters long' 397*8c35d5eeSXin Li ' [whitespace/line_length] [2]') 398*8c35d5eeSXin Li self.TestLint( 399*8c35d5eeSXin Li '// http://g' + ('o' * 100) + 'gle.com/', 400*8c35d5eeSXin Li '') 401*8c35d5eeSXin Li self.TestLint( 402*8c35d5eeSXin Li '// https://g' + ('o' * 100) + 'gle.com/', 403*8c35d5eeSXin Li '') 404*8c35d5eeSXin Li self.TestLint( 405*8c35d5eeSXin Li '// https://g' + ('o' * 60) + 'gle.com/ and some comments', 406*8c35d5eeSXin Li 'Lines should be <= 80 characters long' 407*8c35d5eeSXin Li ' [whitespace/line_length] [2]') 408*8c35d5eeSXin Li self.TestLint( 409*8c35d5eeSXin Li '// Read https://g' + ('o' * 60) + 'gle.com/', 410*8c35d5eeSXin Li '') 411*8c35d5eeSXin Li self.TestLint( 412*8c35d5eeSXin Li '// $Id: g' + ('o' * 80) + 'gle.cc#1 $', 413*8c35d5eeSXin Li '') 414*8c35d5eeSXin Li self.TestLint( 415*8c35d5eeSXin Li '// $Id: g' + ('o' * 80) + 'gle.cc#1', 416*8c35d5eeSXin Li 'Lines should be <= 80 characters long' 417*8c35d5eeSXin Li ' [whitespace/line_length] [2]') 418*8c35d5eeSXin Li self.TestMultiLineLint( 419*8c35d5eeSXin Li 'static const char kCStr[] = "g' + ('o' * 50) + 'gle";\n', 420*8c35d5eeSXin Li 'Lines should be <= 80 characters long' 421*8c35d5eeSXin Li ' [whitespace/line_length] [2]') 422*8c35d5eeSXin Li self.TestMultiLineLint( 423*8c35d5eeSXin Li 'static const char kRawStr[] = R"(g' + ('o' * 50) + 'gle)";\n', 424*8c35d5eeSXin Li '') # no warning because raw string content is elided 425*8c35d5eeSXin Li self.TestMultiLineLint( 426*8c35d5eeSXin Li 'static const char kMultiLineRawStr[] = R"(\n' 427*8c35d5eeSXin Li 'g' + ('o' * 80) + 'gle\n' 428*8c35d5eeSXin Li ')";', 429*8c35d5eeSXin Li '') 430*8c35d5eeSXin Li self.TestMultiLineLint( 431*8c35d5eeSXin Li 'static const char kL' + ('o' * 50) + 'ngIdentifier[] = R"()";\n', 432*8c35d5eeSXin Li 'Lines should be <= 80 characters long' 433*8c35d5eeSXin Li ' [whitespace/line_length] [2]') 434*8c35d5eeSXin Li 435*8c35d5eeSXin Li # Test error suppression annotations. 436*8c35d5eeSXin Li def testErrorSuppression(self): 437*8c35d5eeSXin Li # Two errors on same line: 438*8c35d5eeSXin Li self.TestLint( 439*8c35d5eeSXin Li 'long a = (int64) 65;', 440*8c35d5eeSXin Li ['Using C-style cast. Use static_cast<int64>(...) instead' 441*8c35d5eeSXin Li ' [readability/casting] [4]', 442*8c35d5eeSXin Li 'Use int16/int64/etc, rather than the C type long' 443*8c35d5eeSXin Li ' [runtime/int] [4]', 444*8c35d5eeSXin Li ]) 445*8c35d5eeSXin Li # One category of error suppressed: 446*8c35d5eeSXin Li self.TestLint( 447*8c35d5eeSXin Li 'long a = (int64) 65; // NOLINT(runtime/int)', 448*8c35d5eeSXin Li 'Using C-style cast. Use static_cast<int64>(...) instead' 449*8c35d5eeSXin Li ' [readability/casting] [4]') 450*8c35d5eeSXin Li # All categories suppressed: (two aliases) 451*8c35d5eeSXin Li self.TestLint('long a = (int64) 65; // NOLINT', '') 452*8c35d5eeSXin Li self.TestLint('long a = (int64) 65; // NOLINT(*)', '') 453*8c35d5eeSXin Li # Malformed NOLINT directive: 454*8c35d5eeSXin Li self.TestLint( 455*8c35d5eeSXin Li 'long a = 65; // NOLINT(foo)', 456*8c35d5eeSXin Li ['Unknown NOLINT error category: foo' 457*8c35d5eeSXin Li ' [readability/nolint] [5]', 458*8c35d5eeSXin Li 'Use int16/int64/etc, rather than the C type long [runtime/int] [4]', 459*8c35d5eeSXin Li ]) 460*8c35d5eeSXin Li # Irrelevant NOLINT directive has no effect: 461*8c35d5eeSXin Li self.TestLint( 462*8c35d5eeSXin Li 'long a = 65; // NOLINT(readability/casting)', 463*8c35d5eeSXin Li 'Use int16/int64/etc, rather than the C type long' 464*8c35d5eeSXin Li ' [runtime/int] [4]') 465*8c35d5eeSXin Li # NOLINTNEXTLINE silences warning for the next line instead of current line 466*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 467*8c35d5eeSXin Li cpplint.ProcessFileData('test.cc', 'cc', 468*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 469*8c35d5eeSXin Li '// NOLINTNEXTLINE(whitespace/line_length)', 470*8c35d5eeSXin Li '// ./command' + (' -verbose' * 80), 471*8c35d5eeSXin Li ''], 472*8c35d5eeSXin Li error_collector) 473*8c35d5eeSXin Li self.assertEquals('', error_collector.Results()) 474*8c35d5eeSXin Li # LINT_C_FILE silences cast warnings for entire file. 475*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 476*8c35d5eeSXin Li cpplint.ProcessFileData('test.h', 'h', 477*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 478*8c35d5eeSXin Li '// NOLINT(build/header_guard)', 479*8c35d5eeSXin Li 'int64 a = (uint64) 65;', 480*8c35d5eeSXin Li '// LINT_C_FILE', 481*8c35d5eeSXin Li ''], 482*8c35d5eeSXin Li error_collector) 483*8c35d5eeSXin Li self.assertEquals('', error_collector.Results()) 484*8c35d5eeSXin Li # Vim modes silence cast warnings for entire file. 485*8c35d5eeSXin Li for modeline in ['vi:filetype=c', 486*8c35d5eeSXin Li 'vi:sw=8 filetype=c', 487*8c35d5eeSXin Li 'vi:sw=8 filetype=c ts=8', 488*8c35d5eeSXin Li 'vi: filetype=c', 489*8c35d5eeSXin Li 'vi: sw=8 filetype=c', 490*8c35d5eeSXin Li 'vi: sw=8 filetype=c ts=8', 491*8c35d5eeSXin Li 'vim:filetype=c', 492*8c35d5eeSXin Li 'vim:sw=8 filetype=c', 493*8c35d5eeSXin Li 'vim:sw=8 filetype=c ts=8', 494*8c35d5eeSXin Li 'vim: filetype=c', 495*8c35d5eeSXin Li 'vim: sw=8 filetype=c', 496*8c35d5eeSXin Li 'vim: sw=8 filetype=c ts=8', 497*8c35d5eeSXin Li 'vim: set filetype=c:', 498*8c35d5eeSXin Li 'vim: set sw=8 filetype=c:', 499*8c35d5eeSXin Li 'vim: set sw=8 filetype=c ts=8:', 500*8c35d5eeSXin Li 'vim: set filetype=c :', 501*8c35d5eeSXin Li 'vim: set sw=8 filetype=c :', 502*8c35d5eeSXin Li 'vim: set sw=8 filetype=c ts=8 :', 503*8c35d5eeSXin Li 'vim: se filetype=c:', 504*8c35d5eeSXin Li 'vim: se sw=8 filetype=c:', 505*8c35d5eeSXin Li 'vim: se sw=8 filetype=c ts=8:', 506*8c35d5eeSXin Li 'vim: se filetype=c :', 507*8c35d5eeSXin Li 'vim: se sw=8 filetype=c :', 508*8c35d5eeSXin Li 'vim: se sw=8 filetype=c ts=8 :']: 509*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 510*8c35d5eeSXin Li cpplint.ProcessFileData('test.h', 'h', 511*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 512*8c35d5eeSXin Li '// NOLINT(build/header_guard)', 513*8c35d5eeSXin Li 'int64 a = (uint64) 65;', 514*8c35d5eeSXin Li '/* Prevent warnings about the modeline', 515*8c35d5eeSXin Li modeline, 516*8c35d5eeSXin Li '*/', 517*8c35d5eeSXin Li ''], 518*8c35d5eeSXin Li error_collector) 519*8c35d5eeSXin Li self.assertEquals('', error_collector.Results()) 520*8c35d5eeSXin Li # LINT_KERNEL_FILE silences whitespace/tab warnings for entire file. 521*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 522*8c35d5eeSXin Li cpplint.ProcessFileData('test.h', 'h', 523*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 524*8c35d5eeSXin Li '// NOLINT(build/header_guard)', 525*8c35d5eeSXin Li 'struct test {', 526*8c35d5eeSXin Li '\tint member;', 527*8c35d5eeSXin Li '};', 528*8c35d5eeSXin Li '// LINT_KERNEL_FILE', 529*8c35d5eeSXin Li ''], 530*8c35d5eeSXin Li error_collector) 531*8c35d5eeSXin Li self.assertEquals('', error_collector.Results()) 532*8c35d5eeSXin Li # NOLINT, NOLINTNEXTLINE silences the readability/braces warning for "};". 533*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 534*8c35d5eeSXin Li cpplint.ProcessFileData('test.cc', 'cc', 535*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 536*8c35d5eeSXin Li 'for (int i = 0; i != 100; ++i) {', 537*8c35d5eeSXin Li '\tstd::cout << i << std::endl;', 538*8c35d5eeSXin Li '}; // NOLINT', 539*8c35d5eeSXin Li 'for (int i = 0; i != 100; ++i) {', 540*8c35d5eeSXin Li '\tstd::cout << i << std::endl;', 541*8c35d5eeSXin Li '// NOLINTNEXTLINE', 542*8c35d5eeSXin Li '};', 543*8c35d5eeSXin Li '// LINT_KERNEL_FILE', 544*8c35d5eeSXin Li ''], 545*8c35d5eeSXin Li error_collector) 546*8c35d5eeSXin Li self.assertEquals('', error_collector.Results()) 547*8c35d5eeSXin Li 548*8c35d5eeSXin Li # Test Variable Declarations. 549*8c35d5eeSXin Li def testVariableDeclarations(self): 550*8c35d5eeSXin Li self.TestLint( 551*8c35d5eeSXin Li 'long a = 65;', 552*8c35d5eeSXin Li 'Use int16/int64/etc, rather than the C type long' 553*8c35d5eeSXin Li ' [runtime/int] [4]') 554*8c35d5eeSXin Li self.TestLint( 555*8c35d5eeSXin Li 'long double b = 65.0;', 556*8c35d5eeSXin Li '') 557*8c35d5eeSXin Li self.TestLint( 558*8c35d5eeSXin Li 'long long aa = 6565;', 559*8c35d5eeSXin Li 'Use int16/int64/etc, rather than the C type long' 560*8c35d5eeSXin Li ' [runtime/int] [4]') 561*8c35d5eeSXin Li 562*8c35d5eeSXin Li # Test C-style cast cases. 563*8c35d5eeSXin Li def testCStyleCast(self): 564*8c35d5eeSXin Li self.TestLint( 565*8c35d5eeSXin Li 'int a = (int)1.0;', 566*8c35d5eeSXin Li 'Using C-style cast. Use static_cast<int>(...) instead' 567*8c35d5eeSXin Li ' [readability/casting] [4]') 568*8c35d5eeSXin Li self.TestLint( 569*8c35d5eeSXin Li 'int a = (int)-1.0;', 570*8c35d5eeSXin Li 'Using C-style cast. Use static_cast<int>(...) instead' 571*8c35d5eeSXin Li ' [readability/casting] [4]') 572*8c35d5eeSXin Li self.TestLint( 573*8c35d5eeSXin Li 'int *a = (int *)NULL;', 574*8c35d5eeSXin Li 'Using C-style cast. Use reinterpret_cast<int *>(...) instead' 575*8c35d5eeSXin Li ' [readability/casting] [4]') 576*8c35d5eeSXin Li 577*8c35d5eeSXin Li self.TestLint( 578*8c35d5eeSXin Li 'uint16 a = (uint16)1.0;', 579*8c35d5eeSXin Li 'Using C-style cast. Use static_cast<uint16>(...) instead' 580*8c35d5eeSXin Li ' [readability/casting] [4]') 581*8c35d5eeSXin Li self.TestLint( 582*8c35d5eeSXin Li 'int32 a = (int32)1.0;', 583*8c35d5eeSXin Li 'Using C-style cast. Use static_cast<int32>(...) instead' 584*8c35d5eeSXin Li ' [readability/casting] [4]') 585*8c35d5eeSXin Li self.TestLint( 586*8c35d5eeSXin Li 'uint64 a = (uint64)1.0;', 587*8c35d5eeSXin Li 'Using C-style cast. Use static_cast<uint64>(...) instead' 588*8c35d5eeSXin Li ' [readability/casting] [4]') 589*8c35d5eeSXin Li 590*8c35d5eeSXin Li # These shouldn't be recognized casts. 591*8c35d5eeSXin Li self.TestLint('u a = (u)NULL;', '') 592*8c35d5eeSXin Li self.TestLint('uint a = (uint)NULL;', '') 593*8c35d5eeSXin Li self.TestLint('typedef MockCallback<int(int)> CallbackType;', '') 594*8c35d5eeSXin Li self.TestLint('scoped_ptr< MockCallback<int(int)> > callback_value;', '') 595*8c35d5eeSXin Li self.TestLint('std::function<int(bool)>', '') 596*8c35d5eeSXin Li self.TestLint('x = sizeof(int)', '') 597*8c35d5eeSXin Li self.TestLint('x = alignof(int)', '') 598*8c35d5eeSXin Li self.TestLint('alignas(int) char x[42]', '') 599*8c35d5eeSXin Li self.TestLint('alignas(alignof(x)) char y[42]', '') 600*8c35d5eeSXin Li self.TestLint('void F(int (func)(int));', '') 601*8c35d5eeSXin Li self.TestLint('void F(int (func)(int*));', '') 602*8c35d5eeSXin Li self.TestLint('void F(int (Class::member)(int));', '') 603*8c35d5eeSXin Li self.TestLint('void F(int (Class::member)(int*));', '') 604*8c35d5eeSXin Li self.TestLint('void F(int (Class::member)(int), int param);', '') 605*8c35d5eeSXin Li self.TestLint('void F(int (Class::member)(int*), int param);', '') 606*8c35d5eeSXin Li 607*8c35d5eeSXin Li # These should not be recognized (lambda functions without arg names). 608*8c35d5eeSXin Li self.TestLint('[](int/*unused*/) -> bool {', '') 609*8c35d5eeSXin Li self.TestLint('[](int /*unused*/) -> bool {', '') 610*8c35d5eeSXin Li self.TestLint('auto f = [](MyStruct* /*unused*/)->int {', '') 611*8c35d5eeSXin Li self.TestLint('[](int) -> bool {', '') 612*8c35d5eeSXin Li self.TestLint('auto f = [](MyStruct*)->int {', '') 613*8c35d5eeSXin Li 614*8c35d5eeSXin Li # Cast with brace initializers 615*8c35d5eeSXin Li self.TestLint('int64_t{4096} * 1000 * 1000', '') 616*8c35d5eeSXin Li self.TestLint('size_t{4096} * 1000 * 1000', '') 617*8c35d5eeSXin Li self.TestLint('uint_fast16_t{4096} * 1000 * 1000', '') 618*8c35d5eeSXin Li 619*8c35d5eeSXin Li # Brace initializer with templated type 620*8c35d5eeSXin Li self.TestMultiLineLint( 621*8c35d5eeSXin Li """ 622*8c35d5eeSXin Li template <typename Type1, 623*8c35d5eeSXin Li typename Type2> 624*8c35d5eeSXin Li void Function(int arg1, 625*8c35d5eeSXin Li int arg2) { 626*8c35d5eeSXin Li variable &= ~Type1{0} - 1; 627*8c35d5eeSXin Li }""", 628*8c35d5eeSXin Li '') 629*8c35d5eeSXin Li self.TestMultiLineLint( 630*8c35d5eeSXin Li """ 631*8c35d5eeSXin Li template <typename Type> 632*8c35d5eeSXin Li class Class { 633*8c35d5eeSXin Li void Function() { 634*8c35d5eeSXin Li variable &= ~Type{0} - 1; 635*8c35d5eeSXin Li } 636*8c35d5eeSXin Li };""", 637*8c35d5eeSXin Li '') 638*8c35d5eeSXin Li self.TestMultiLineLint( 639*8c35d5eeSXin Li """ 640*8c35d5eeSXin Li template <typename Type> 641*8c35d5eeSXin Li class Class { 642*8c35d5eeSXin Li void Function() { 643*8c35d5eeSXin Li variable &= ~Type{0} - 1; 644*8c35d5eeSXin Li } 645*8c35d5eeSXin Li };""", 646*8c35d5eeSXin Li '') 647*8c35d5eeSXin Li self.TestMultiLineLint( 648*8c35d5eeSXin Li """ 649*8c35d5eeSXin Li namespace { 650*8c35d5eeSXin Li template <typename Type> 651*8c35d5eeSXin Li class Class { 652*8c35d5eeSXin Li void Function() { 653*8c35d5eeSXin Li if (block) { 654*8c35d5eeSXin Li variable &= ~Type{0} - 1; 655*8c35d5eeSXin Li } 656*8c35d5eeSXin Li } 657*8c35d5eeSXin Li }; 658*8c35d5eeSXin Li }""", 659*8c35d5eeSXin Li '') 660*8c35d5eeSXin Li 661*8c35d5eeSXin Li # Test taking address of casts (runtime/casting) 662*8c35d5eeSXin Li def testRuntimeCasting(self): 663*8c35d5eeSXin Li error_msg = ('Are you taking an address of a cast? ' 664*8c35d5eeSXin Li 'This is dangerous: could be a temp var. ' 665*8c35d5eeSXin Li 'Take the address before doing the cast, rather than after' 666*8c35d5eeSXin Li ' [runtime/casting] [4]') 667*8c35d5eeSXin Li self.TestLint('int* x = &static_cast<int*>(foo);', error_msg) 668*8c35d5eeSXin Li self.TestLint('int* x = &reinterpret_cast<int *>(foo);', error_msg) 669*8c35d5eeSXin Li self.TestLint('int* x = &(int*)foo;', 670*8c35d5eeSXin Li ['Using C-style cast. Use reinterpret_cast<int*>(...) ' 671*8c35d5eeSXin Li 'instead [readability/casting] [4]', 672*8c35d5eeSXin Li error_msg]) 673*8c35d5eeSXin Li self.TestLint('BudgetBuckets&(BudgetWinHistory::*BucketFn)(void) const;', 674*8c35d5eeSXin Li '') 675*8c35d5eeSXin Li self.TestLint('&(*func_ptr)(arg)', '') 676*8c35d5eeSXin Li self.TestLint('Compute(arg, &(*func_ptr)(i, j));', '') 677*8c35d5eeSXin Li 678*8c35d5eeSXin Li # Alternative error message 679*8c35d5eeSXin Li alt_error_msg = ('Are you taking an address of something dereferenced ' 680*8c35d5eeSXin Li 'from a cast? Wrapping the dereferenced expression in ' 681*8c35d5eeSXin Li 'parentheses will make the binding more obvious' 682*8c35d5eeSXin Li ' [readability/casting] [4]') 683*8c35d5eeSXin Li self.TestLint('int* x = &down_cast<Obj*>(obj)->member_;', alt_error_msg) 684*8c35d5eeSXin Li self.TestLint('int* x = &down_cast<Obj*>(obj)[index];', alt_error_msg) 685*8c35d5eeSXin Li self.TestLint('int* x = &(down_cast<Obj*>(obj)->member_);', '') 686*8c35d5eeSXin Li self.TestLint('int* x = &(down_cast<Obj*>(obj)[index]);', '') 687*8c35d5eeSXin Li self.TestLint('int* x = &down_cast<Obj*>(obj)\n->member_;', alt_error_msg) 688*8c35d5eeSXin Li self.TestLint('int* x = &(down_cast<Obj*>(obj)\n->member_);', '') 689*8c35d5eeSXin Li 690*8c35d5eeSXin Li # It's OK to cast an address. 691*8c35d5eeSXin Li self.TestLint('int* x = reinterpret_cast<int *>(&foo);', '') 692*8c35d5eeSXin Li 693*8c35d5eeSXin Li # Function pointers returning references should not be confused 694*8c35d5eeSXin Li # with taking address of old-style casts. 695*8c35d5eeSXin Li self.TestLint('auto x = implicit_cast<string &(*)(int)>(&foo);', '') 696*8c35d5eeSXin Li 697*8c35d5eeSXin Li def testRuntimeSelfinit(self): 698*8c35d5eeSXin Li self.TestLint( 699*8c35d5eeSXin Li 'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }', 700*8c35d5eeSXin Li 'You seem to be initializing a member variable with itself.' 701*8c35d5eeSXin Li ' [runtime/init] [4]') 702*8c35d5eeSXin Li self.TestLint( 703*8c35d5eeSXin Li 'Foo::Foo(Bar r, Bel l) : r_(CHECK_NOTNULL(r_)) { }', 704*8c35d5eeSXin Li 'You seem to be initializing a member variable with itself.' 705*8c35d5eeSXin Li ' [runtime/init] [4]') 706*8c35d5eeSXin Li self.TestLint( 707*8c35d5eeSXin Li 'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }', 708*8c35d5eeSXin Li '') 709*8c35d5eeSXin Li self.TestLint( 710*8c35d5eeSXin Li 'Foo::Foo(Bar r) : r_(r), l_(r_), ll_(l_) { }', 711*8c35d5eeSXin Li '') 712*8c35d5eeSXin Li 713*8c35d5eeSXin Li # Test for unnamed arguments in a method. 714*8c35d5eeSXin Li def testCheckForUnnamedParams(self): 715*8c35d5eeSXin Li self.TestLint('virtual void Func(int*) const;', '') 716*8c35d5eeSXin Li self.TestLint('virtual void Func(int*);', '') 717*8c35d5eeSXin Li self.TestLint('void Method(char*) {', '') 718*8c35d5eeSXin Li self.TestLint('void Method(char*);', '') 719*8c35d5eeSXin Li self.TestLint('static void operator delete[](void*) throw();', '') 720*8c35d5eeSXin Li self.TestLint('int Method(int);', '') 721*8c35d5eeSXin Li 722*8c35d5eeSXin Li self.TestLint('virtual void Func(int* p);', '') 723*8c35d5eeSXin Li self.TestLint('void operator delete(void* x) throw();', '') 724*8c35d5eeSXin Li self.TestLint('void Method(char* x) {', '') 725*8c35d5eeSXin Li self.TestLint('void Method(char* /*x*/) {', '') 726*8c35d5eeSXin Li self.TestLint('void Method(char* x);', '') 727*8c35d5eeSXin Li self.TestLint('typedef void (*Method)(int32 x);', '') 728*8c35d5eeSXin Li self.TestLint('static void operator delete[](void* x) throw();', '') 729*8c35d5eeSXin Li self.TestLint('static void operator delete[](void* /*x*/) throw();', '') 730*8c35d5eeSXin Li 731*8c35d5eeSXin Li self.TestLint('X operator++(int);', '') 732*8c35d5eeSXin Li self.TestLint('X operator++(int) {', '') 733*8c35d5eeSXin Li self.TestLint('X operator--(int);', '') 734*8c35d5eeSXin Li self.TestLint('X operator--(int /*unused*/) {', '') 735*8c35d5eeSXin Li self.TestLint('MACRO(int);', '') 736*8c35d5eeSXin Li self.TestLint('MACRO(func(int));', '') 737*8c35d5eeSXin Li self.TestLint('MACRO(arg, func(int));', '') 738*8c35d5eeSXin Li 739*8c35d5eeSXin Li self.TestLint('void (*func)(void*);', '') 740*8c35d5eeSXin Li self.TestLint('void Func((*func)(void*)) {}', '') 741*8c35d5eeSXin Li self.TestLint('template <void Func(void*)> void func();', '') 742*8c35d5eeSXin Li self.TestLint('virtual void f(int /*unused*/) {', '') 743*8c35d5eeSXin Li self.TestLint('void f(int /*unused*/) override {', '') 744*8c35d5eeSXin Li self.TestLint('void f(int /*unused*/) final {', '') 745*8c35d5eeSXin Li 746*8c35d5eeSXin Li # Test deprecated casts such as int(d) 747*8c35d5eeSXin Li def testDeprecatedCast(self): 748*8c35d5eeSXin Li self.TestLint( 749*8c35d5eeSXin Li 'int a = int(2.2);', 750*8c35d5eeSXin Li 'Using deprecated casting style. ' 751*8c35d5eeSXin Li 'Use static_cast<int>(...) instead' 752*8c35d5eeSXin Li ' [readability/casting] [4]') 753*8c35d5eeSXin Li 754*8c35d5eeSXin Li self.TestLint( 755*8c35d5eeSXin Li '(char *) "foo"', 756*8c35d5eeSXin Li 'Using C-style cast. ' 757*8c35d5eeSXin Li 'Use const_cast<char *>(...) instead' 758*8c35d5eeSXin Li ' [readability/casting] [4]') 759*8c35d5eeSXin Li 760*8c35d5eeSXin Li self.TestLint( 761*8c35d5eeSXin Li '(int*)foo', 762*8c35d5eeSXin Li 'Using C-style cast. ' 763*8c35d5eeSXin Li 'Use reinterpret_cast<int*>(...) instead' 764*8c35d5eeSXin Li ' [readability/casting] [4]') 765*8c35d5eeSXin Li 766*8c35d5eeSXin Li # Checks for false positives... 767*8c35d5eeSXin Li self.TestLint('int a = int();', '') # constructor 768*8c35d5eeSXin Li self.TestLint('X::X() : a(int()) {}', '') # default constructor 769*8c35d5eeSXin Li self.TestLint('operator bool();', '') # Conversion operator 770*8c35d5eeSXin Li self.TestLint('new int64(123);', '') # "new" operator on basic type 771*8c35d5eeSXin Li self.TestLint('new int64(123);', '') # "new" operator on basic type 772*8c35d5eeSXin Li self.TestLint('new const int(42);', '') # "new" on const-qualified type 773*8c35d5eeSXin Li self.TestLint('using a = bool(int arg);', '') # C++11 alias-declaration 774*8c35d5eeSXin Li self.TestLint('x = bit_cast<double(*)[3]>(y);', '') # array of array 775*8c35d5eeSXin Li self.TestLint('void F(const char(&src)[N]);', '') # array of references 776*8c35d5eeSXin Li 777*8c35d5eeSXin Li # Placement new 778*8c35d5eeSXin Li self.TestLint( 779*8c35d5eeSXin Li 'new(field_ptr) int(field->default_value_enum()->number());', 780*8c35d5eeSXin Li '') 781*8c35d5eeSXin Li 782*8c35d5eeSXin Li # C++11 function wrappers 783*8c35d5eeSXin Li self.TestLint('std::function<int(bool)>', '') 784*8c35d5eeSXin Li self.TestLint('std::function<const int(bool)>', '') 785*8c35d5eeSXin Li self.TestLint('std::function< int(bool) >', '') 786*8c35d5eeSXin Li self.TestLint('mfunction<int(bool)>', '') 787*8c35d5eeSXin Li 788*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 789*8c35d5eeSXin Li cpplint.ProcessFileData( 790*8c35d5eeSXin Li 'test.cc', 'cc', 791*8c35d5eeSXin Li ['// Copyright 2014 Your Company. All Rights Reserved.', 792*8c35d5eeSXin Li 'typedef std::function<', 793*8c35d5eeSXin Li ' bool(int)> F;', 794*8c35d5eeSXin Li ''], 795*8c35d5eeSXin Li error_collector) 796*8c35d5eeSXin Li self.assertEquals('', error_collector.Results()) 797*8c35d5eeSXin Li 798*8c35d5eeSXin Li # Return types for function pointers 799*8c35d5eeSXin Li self.TestLint('typedef bool(FunctionPointer)();', '') 800*8c35d5eeSXin Li self.TestLint('typedef bool(FunctionPointer)(int param);', '') 801*8c35d5eeSXin Li self.TestLint('typedef bool(MyClass::*MemberFunctionPointer)();', '') 802*8c35d5eeSXin Li self.TestLint('typedef bool(MyClass::* MemberFunctionPointer)();', '') 803*8c35d5eeSXin Li self.TestLint('typedef bool(MyClass::*MemberFunctionPointer)() const;', '') 804*8c35d5eeSXin Li self.TestLint('void Function(bool(FunctionPointerArg)());', '') 805*8c35d5eeSXin Li self.TestLint('void Function(bool(FunctionPointerArg)()) {}', '') 806*8c35d5eeSXin Li self.TestLint('typedef set<int64, bool(*)(int64, int64)> SortedIdSet', '') 807*8c35d5eeSXin Li self.TestLint( 808*8c35d5eeSXin Li 'bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *t)) {}', 809*8c35d5eeSXin Li '') 810*8c35d5eeSXin Li 811*8c35d5eeSXin Li # The second parameter to a gMock method definition is a function signature 812*8c35d5eeSXin Li # that often looks like a bad cast but should not picked up by lint. 813*8c35d5eeSXin Li def testMockMethod(self): 814*8c35d5eeSXin Li self.TestLint( 815*8c35d5eeSXin Li 'MOCK_METHOD0(method, int());', 816*8c35d5eeSXin Li '') 817*8c35d5eeSXin Li self.TestLint( 818*8c35d5eeSXin Li 'MOCK_CONST_METHOD1(method, float(string));', 819*8c35d5eeSXin Li '') 820*8c35d5eeSXin Li self.TestLint( 821*8c35d5eeSXin Li 'MOCK_CONST_METHOD2_T(method, double(float, float));', 822*8c35d5eeSXin Li '') 823*8c35d5eeSXin Li self.TestLint( 824*8c35d5eeSXin Li 'MOCK_CONST_METHOD1(method, SomeType(int));', 825*8c35d5eeSXin Li '') 826*8c35d5eeSXin Li 827*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 828*8c35d5eeSXin Li cpplint.ProcessFileData('mock.cc', 'cc', 829*8c35d5eeSXin Li ['MOCK_METHOD1(method1,', 830*8c35d5eeSXin Li ' bool(int));', 831*8c35d5eeSXin Li 'MOCK_METHOD1(', 832*8c35d5eeSXin Li ' method2,', 833*8c35d5eeSXin Li ' bool(int));', 834*8c35d5eeSXin Li 'MOCK_CONST_METHOD2(', 835*8c35d5eeSXin Li ' method3, bool(int,', 836*8c35d5eeSXin Li ' int));', 837*8c35d5eeSXin Li 'MOCK_METHOD1(method4, int(bool));', 838*8c35d5eeSXin Li 'const int kConstant = int(42);'], # true positive 839*8c35d5eeSXin Li error_collector) 840*8c35d5eeSXin Li self.assertEquals( 841*8c35d5eeSXin Li 0, 842*8c35d5eeSXin Li error_collector.Results().count( 843*8c35d5eeSXin Li ('Using deprecated casting style. ' 844*8c35d5eeSXin Li 'Use static_cast<bool>(...) instead ' 845*8c35d5eeSXin Li '[readability/casting] [4]'))) 846*8c35d5eeSXin Li self.assertEquals( 847*8c35d5eeSXin Li 1, 848*8c35d5eeSXin Li error_collector.Results().count( 849*8c35d5eeSXin Li ('Using deprecated casting style. ' 850*8c35d5eeSXin Li 'Use static_cast<int>(...) instead ' 851*8c35d5eeSXin Li '[readability/casting] [4]'))) 852*8c35d5eeSXin Li 853*8c35d5eeSXin Li # Like gMock method definitions, MockCallback instantiations look very similar 854*8c35d5eeSXin Li # to bad casts. 855*8c35d5eeSXin Li def testMockCallback(self): 856*8c35d5eeSXin Li self.TestLint( 857*8c35d5eeSXin Li 'MockCallback<bool(int)>', 858*8c35d5eeSXin Li '') 859*8c35d5eeSXin Li self.TestLint( 860*8c35d5eeSXin Li 'MockCallback<int(float, char)>', 861*8c35d5eeSXin Li '') 862*8c35d5eeSXin Li 863*8c35d5eeSXin Li # Test false errors that happened with some include file names 864*8c35d5eeSXin Li def testIncludeFilenameFalseError(self): 865*8c35d5eeSXin Li self.TestLint( 866*8c35d5eeSXin Li '#include "foo/long-foo.h"', 867*8c35d5eeSXin Li '') 868*8c35d5eeSXin Li self.TestLint( 869*8c35d5eeSXin Li '#include "foo/sprintf.h"', 870*8c35d5eeSXin Li '') 871*8c35d5eeSXin Li 872*8c35d5eeSXin Li # Test typedef cases. There was a bug that cpplint misidentified 873*8c35d5eeSXin Li # typedef for pointer to function as C-style cast and produced 874*8c35d5eeSXin Li # false-positive error messages. 875*8c35d5eeSXin Li def testTypedefForPointerToFunction(self): 876*8c35d5eeSXin Li self.TestLint( 877*8c35d5eeSXin Li 'typedef void (*Func)(int x);', 878*8c35d5eeSXin Li '') 879*8c35d5eeSXin Li self.TestLint( 880*8c35d5eeSXin Li 'typedef void (*Func)(int *x);', 881*8c35d5eeSXin Li '') 882*8c35d5eeSXin Li self.TestLint( 883*8c35d5eeSXin Li 'typedef void Func(int x);', 884*8c35d5eeSXin Li '') 885*8c35d5eeSXin Li self.TestLint( 886*8c35d5eeSXin Li 'typedef void Func(int *x);', 887*8c35d5eeSXin Li '') 888*8c35d5eeSXin Li 889*8c35d5eeSXin Li def testIncludeWhatYouUseNoImplementationFiles(self): 890*8c35d5eeSXin Li code = 'std::vector<int> foo;' 891*8c35d5eeSXin Li self.assertEquals('Add #include <vector> for vector<>' 892*8c35d5eeSXin Li ' [build/include_what_you_use] [4]', 893*8c35d5eeSXin Li self.PerformIncludeWhatYouUse(code, 'foo.h')) 894*8c35d5eeSXin Li self.assertEquals('', 895*8c35d5eeSXin Li self.PerformIncludeWhatYouUse(code, 'foo.cc')) 896*8c35d5eeSXin Li 897*8c35d5eeSXin Li def testIncludeWhatYouUse(self): 898*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 899*8c35d5eeSXin Li """#include <vector> 900*8c35d5eeSXin Li std::vector<int> foo; 901*8c35d5eeSXin Li """, 902*8c35d5eeSXin Li '') 903*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 904*8c35d5eeSXin Li """#include <map> 905*8c35d5eeSXin Li std::pair<int,int> foo; 906*8c35d5eeSXin Li """, 907*8c35d5eeSXin Li 'Add #include <utility> for pair<>' 908*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 909*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 910*8c35d5eeSXin Li """#include <multimap> 911*8c35d5eeSXin Li std::pair<int,int> foo; 912*8c35d5eeSXin Li """, 913*8c35d5eeSXin Li 'Add #include <utility> for pair<>' 914*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 915*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 916*8c35d5eeSXin Li """#include <hash_map> 917*8c35d5eeSXin Li std::pair<int,int> foo; 918*8c35d5eeSXin Li """, 919*8c35d5eeSXin Li 'Add #include <utility> for pair<>' 920*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 921*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 922*8c35d5eeSXin Li """#include <hash_map> 923*8c35d5eeSXin Li auto foo = std::make_pair(1, 2); 924*8c35d5eeSXin Li """, 925*8c35d5eeSXin Li 'Add #include <utility> for make_pair' 926*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 927*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 928*8c35d5eeSXin Li """#include <utility> 929*8c35d5eeSXin Li std::pair<int,int> foo; 930*8c35d5eeSXin Li """, 931*8c35d5eeSXin Li '') 932*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 933*8c35d5eeSXin Li """#include <vector> 934*8c35d5eeSXin Li DECLARE_string(foobar); 935*8c35d5eeSXin Li """, 936*8c35d5eeSXin Li '') 937*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 938*8c35d5eeSXin Li """#include <vector> 939*8c35d5eeSXin Li DEFINE_string(foobar, "", ""); 940*8c35d5eeSXin Li """, 941*8c35d5eeSXin Li '') 942*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 943*8c35d5eeSXin Li """#include <vector> 944*8c35d5eeSXin Li std::pair<int,int> foo; 945*8c35d5eeSXin Li """, 946*8c35d5eeSXin Li 'Add #include <utility> for pair<>' 947*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 948*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 949*8c35d5eeSXin Li """#include "base/foobar.h" 950*8c35d5eeSXin Li std::vector<int> foo; 951*8c35d5eeSXin Li """, 952*8c35d5eeSXin Li 'Add #include <vector> for vector<>' 953*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 954*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 955*8c35d5eeSXin Li """#include <vector> 956*8c35d5eeSXin Li std::set<int> foo; 957*8c35d5eeSXin Li """, 958*8c35d5eeSXin Li 'Add #include <set> for set<>' 959*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 960*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 961*8c35d5eeSXin Li """#include "base/foobar.h" 962*8c35d5eeSXin Li hash_map<int, int> foobar; 963*8c35d5eeSXin Li """, 964*8c35d5eeSXin Li 'Add #include <hash_map> for hash_map<>' 965*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 966*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 967*8c35d5eeSXin Li """#include "base/containers/hash_tables.h" 968*8c35d5eeSXin Li base::hash_map<int, int> foobar; 969*8c35d5eeSXin Li """, 970*8c35d5eeSXin Li '') 971*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 972*8c35d5eeSXin Li """#include "base/foobar.h" 973*8c35d5eeSXin Li bool foobar = std::less<int>(0,1); 974*8c35d5eeSXin Li """, 975*8c35d5eeSXin Li 'Add #include <functional> for less<>' 976*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 977*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 978*8c35d5eeSXin Li """#include "base/foobar.h" 979*8c35d5eeSXin Li bool foobar = min<int>(0,1); 980*8c35d5eeSXin Li """, 981*8c35d5eeSXin Li 'Add #include <algorithm> for min [build/include_what_you_use] [4]') 982*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 983*8c35d5eeSXin Li 'void a(const string &foobar);', 984*8c35d5eeSXin Li 'Add #include <string> for string [build/include_what_you_use] [4]') 985*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 986*8c35d5eeSXin Li 'void a(const std::string &foobar);', 987*8c35d5eeSXin Li 'Add #include <string> for string [build/include_what_you_use] [4]') 988*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 989*8c35d5eeSXin Li 'void a(const my::string &foobar);', 990*8c35d5eeSXin Li '') # Avoid false positives on strings in other namespaces. 991*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 992*8c35d5eeSXin Li """#include "base/foobar.h" 993*8c35d5eeSXin Li bool foobar = swap(0,1); 994*8c35d5eeSXin Li """, 995*8c35d5eeSXin Li 'Add #include <utility> for swap [build/include_what_you_use] [4]') 996*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 997*8c35d5eeSXin Li """#include "base/foobar.h" 998*8c35d5eeSXin Li bool foobar = transform(a.begin(), a.end(), b.start(), Foo); 999*8c35d5eeSXin Li """, 1000*8c35d5eeSXin Li 'Add #include <algorithm> for transform ' 1001*8c35d5eeSXin Li '[build/include_what_you_use] [4]') 1002*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 1003*8c35d5eeSXin Li """#include "base/foobar.h" 1004*8c35d5eeSXin Li bool foobar = min_element(a.begin(), a.end()); 1005*8c35d5eeSXin Li """, 1006*8c35d5eeSXin Li 'Add #include <algorithm> for min_element ' 1007*8c35d5eeSXin Li '[build/include_what_you_use] [4]') 1008*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 1009*8c35d5eeSXin Li """foo->swap(0,1); 1010*8c35d5eeSXin Li foo.swap(0,1); 1011*8c35d5eeSXin Li """, 1012*8c35d5eeSXin Li '') 1013*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 1014*8c35d5eeSXin Li """#include <string> 1015*8c35d5eeSXin Li void a(const std::multimap<int,string> &foobar); 1016*8c35d5eeSXin Li """, 1017*8c35d5eeSXin Li 'Add #include <map> for multimap<>' 1018*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 1019*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 1020*8c35d5eeSXin Li """#include <string> 1021*8c35d5eeSXin Li void a(const std::unordered_map<int,string> &foobar); 1022*8c35d5eeSXin Li """, 1023*8c35d5eeSXin Li 'Add #include <unordered_map> for unordered_map<>' 1024*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 1025*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 1026*8c35d5eeSXin Li """#include <string> 1027*8c35d5eeSXin Li void a(const std::unordered_set<int> &foobar); 1028*8c35d5eeSXin Li """, 1029*8c35d5eeSXin Li 'Add #include <unordered_set> for unordered_set<>' 1030*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 1031*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 1032*8c35d5eeSXin Li """#include <queue> 1033*8c35d5eeSXin Li void a(const std::priority_queue<int> &foobar); 1034*8c35d5eeSXin Li """, 1035*8c35d5eeSXin Li '') 1036*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 1037*8c35d5eeSXin Li """#include <assert.h> 1038*8c35d5eeSXin Li #include <string> 1039*8c35d5eeSXin Li #include <vector> 1040*8c35d5eeSXin Li #include "base/basictypes.h" 1041*8c35d5eeSXin Li #include "base/port.h" 1042*8c35d5eeSXin Li vector<string> hajoa;""", '') 1043*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 1044*8c35d5eeSXin Li """#include <string> 1045*8c35d5eeSXin Li int i = numeric_limits<int>::max() 1046*8c35d5eeSXin Li """, 1047*8c35d5eeSXin Li 'Add #include <limits> for numeric_limits<>' 1048*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 1049*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 1050*8c35d5eeSXin Li """#include <limits> 1051*8c35d5eeSXin Li int i = numeric_limits<int>::max() 1052*8c35d5eeSXin Li """, 1053*8c35d5eeSXin Li '') 1054*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 1055*8c35d5eeSXin Li """#include <string> 1056*8c35d5eeSXin Li std::unique_ptr<int> x; 1057*8c35d5eeSXin Li """, 1058*8c35d5eeSXin Li 'Add #include <memory> for unique_ptr<>' 1059*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 1060*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 1061*8c35d5eeSXin Li """#include <string> 1062*8c35d5eeSXin Li auto x = std::make_unique<int>(0); 1063*8c35d5eeSXin Li """, 1064*8c35d5eeSXin Li 'Add #include <memory> for make_unique<>' 1065*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 1066*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 1067*8c35d5eeSXin Li """#include <vector> 1068*8c35d5eeSXin Li vector<int> foo(vector<int> x) { return std::move(x); } 1069*8c35d5eeSXin Li """, 1070*8c35d5eeSXin Li 'Add #include <utility> for move' 1071*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 1072*8c35d5eeSXin Li self.TestIncludeWhatYouUse( 1073*8c35d5eeSXin Li """#include <string> 1074*8c35d5eeSXin Li int a, b; 1075*8c35d5eeSXin Li std::swap(a, b); 1076*8c35d5eeSXin Li """, 1077*8c35d5eeSXin Li 'Add #include <utility> for swap' 1078*8c35d5eeSXin Li ' [build/include_what_you_use] [4]') 1079*8c35d5eeSXin Li 1080*8c35d5eeSXin Li # Test the UpdateIncludeState code path. 1081*8c35d5eeSXin Li mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"'] 1082*8c35d5eeSXin Li message = self.PerformIncludeWhatYouUse( 1083*8c35d5eeSXin Li '#include "blah/a.h"', 1084*8c35d5eeSXin Li filename='blah/a.cc', 1085*8c35d5eeSXin Li io=MockIo(mock_header_contents)) 1086*8c35d5eeSXin Li self.assertEquals(message, '') 1087*8c35d5eeSXin Li 1088*8c35d5eeSXin Li mock_header_contents = ['#include <set>'] 1089*8c35d5eeSXin Li message = self.PerformIncludeWhatYouUse( 1090*8c35d5eeSXin Li """#include "blah/a.h" 1091*8c35d5eeSXin Li std::set<int> foo;""", 1092*8c35d5eeSXin Li filename='blah/a.cc', 1093*8c35d5eeSXin Li io=MockIo(mock_header_contents)) 1094*8c35d5eeSXin Li self.assertEquals(message, '') 1095*8c35d5eeSXin Li 1096*8c35d5eeSXin Li # Make sure we can find the correct header file if the cc file seems to be 1097*8c35d5eeSXin Li # a temporary file generated by Emacs's flymake. 1098*8c35d5eeSXin Li mock_header_contents = [''] 1099*8c35d5eeSXin Li message = self.PerformIncludeWhatYouUse( 1100*8c35d5eeSXin Li """#include "blah/a.h" 1101*8c35d5eeSXin Li std::set<int> foo;""", 1102*8c35d5eeSXin Li filename='blah/a_flymake.cc', 1103*8c35d5eeSXin Li io=MockIo(mock_header_contents)) 1104*8c35d5eeSXin Li self.assertEquals(message, 'Add #include <set> for set<> ' 1105*8c35d5eeSXin Li '[build/include_what_you_use] [4]') 1106*8c35d5eeSXin Li 1107*8c35d5eeSXin Li # If there's just a cc and the header can't be found then it's ok. 1108*8c35d5eeSXin Li message = self.PerformIncludeWhatYouUse( 1109*8c35d5eeSXin Li """#include "blah/a.h" 1110*8c35d5eeSXin Li std::set<int> foo;""", 1111*8c35d5eeSXin Li filename='blah/a.cc') 1112*8c35d5eeSXin Li self.assertEquals(message, '') 1113*8c35d5eeSXin Li 1114*8c35d5eeSXin Li # Make sure we find the headers with relative paths. 1115*8c35d5eeSXin Li mock_header_contents = [''] 1116*8c35d5eeSXin Li message = self.PerformIncludeWhatYouUse( 1117*8c35d5eeSXin Li """#include "%s/a.h" 1118*8c35d5eeSXin Li std::set<int> foo;""" % os.path.basename(os.getcwd()), 1119*8c35d5eeSXin Li filename='a.cc', 1120*8c35d5eeSXin Li io=MockIo(mock_header_contents)) 1121*8c35d5eeSXin Li self.assertEquals(message, 'Add #include <set> for set<> ' 1122*8c35d5eeSXin Li '[build/include_what_you_use] [4]') 1123*8c35d5eeSXin Li 1124*8c35d5eeSXin Li def testFilesBelongToSameModule(self): 1125*8c35d5eeSXin Li f = cpplint.FilesBelongToSameModule 1126*8c35d5eeSXin Li self.assertEquals((True, ''), f('a.cc', 'a.h')) 1127*8c35d5eeSXin Li self.assertEquals((True, ''), f('base/google.cc', 'base/google.h')) 1128*8c35d5eeSXin Li self.assertEquals((True, ''), f('base/google_test.cc', 'base/google.h')) 1129*8c35d5eeSXin Li self.assertEquals((True, ''), 1130*8c35d5eeSXin Li f('base/google_unittest.cc', 'base/google.h')) 1131*8c35d5eeSXin Li self.assertEquals((True, ''), 1132*8c35d5eeSXin Li f('base/internal/google_unittest.cc', 1133*8c35d5eeSXin Li 'base/public/google.h')) 1134*8c35d5eeSXin Li self.assertEquals((True, 'xxx/yyy/'), 1135*8c35d5eeSXin Li f('xxx/yyy/base/internal/google_unittest.cc', 1136*8c35d5eeSXin Li 'base/public/google.h')) 1137*8c35d5eeSXin Li self.assertEquals((True, 'xxx/yyy/'), 1138*8c35d5eeSXin Li f('xxx/yyy/base/google_unittest.cc', 1139*8c35d5eeSXin Li 'base/public/google.h')) 1140*8c35d5eeSXin Li self.assertEquals((True, ''), 1141*8c35d5eeSXin Li f('base/google_unittest.cc', 'base/google-inl.h')) 1142*8c35d5eeSXin Li self.assertEquals((True, '/home/build/google3/'), 1143*8c35d5eeSXin Li f('/home/build/google3/base/google.cc', 'base/google.h')) 1144*8c35d5eeSXin Li 1145*8c35d5eeSXin Li self.assertEquals((False, ''), 1146*8c35d5eeSXin Li f('/home/build/google3/base/google.cc', 'basu/google.h')) 1147*8c35d5eeSXin Li self.assertEquals((False, ''), f('a.cc', 'b.h')) 1148*8c35d5eeSXin Li 1149*8c35d5eeSXin Li def testCleanseLine(self): 1150*8c35d5eeSXin Li self.assertEquals('int foo = 0;', 1151*8c35d5eeSXin Li cpplint.CleanseComments('int foo = 0; // danger!')) 1152*8c35d5eeSXin Li self.assertEquals('int o = 0;', 1153*8c35d5eeSXin Li cpplint.CleanseComments('int /* foo */ o = 0;')) 1154*8c35d5eeSXin Li self.assertEquals('foo(int a, int b);', 1155*8c35d5eeSXin Li cpplint.CleanseComments('foo(int a /* abc */, int b);')) 1156*8c35d5eeSXin Li self.assertEqual('f(a, b);', 1157*8c35d5eeSXin Li cpplint.CleanseComments('f(a, /* name */ b);')) 1158*8c35d5eeSXin Li self.assertEqual('f(a, b);', 1159*8c35d5eeSXin Li cpplint.CleanseComments('f(a /* name */, b);')) 1160*8c35d5eeSXin Li self.assertEqual('f(a, b);', 1161*8c35d5eeSXin Li cpplint.CleanseComments('f(a, /* name */b);')) 1162*8c35d5eeSXin Li self.assertEqual('f(a, b, c);', 1163*8c35d5eeSXin Li cpplint.CleanseComments('f(a, /**/b, /**/c);')) 1164*8c35d5eeSXin Li self.assertEqual('f(a, b, c);', 1165*8c35d5eeSXin Li cpplint.CleanseComments('f(a, /**/b/**/, c);')) 1166*8c35d5eeSXin Li 1167*8c35d5eeSXin Li def testRawStrings(self): 1168*8c35d5eeSXin Li self.TestMultiLineLint( 1169*8c35d5eeSXin Li """ 1170*8c35d5eeSXin Li void Func() { 1171*8c35d5eeSXin Li static const char kString[] = R"( 1172*8c35d5eeSXin Li #endif <- invalid preprocessor should be ignored 1173*8c35d5eeSXin Li */ <- invalid comment should be ignored too 1174*8c35d5eeSXin Li )"; 1175*8c35d5eeSXin Li }""", 1176*8c35d5eeSXin Li '') 1177*8c35d5eeSXin Li self.TestMultiLineLint( 1178*8c35d5eeSXin Li """ 1179*8c35d5eeSXin Li void Func() { 1180*8c35d5eeSXin Li string s = R"TrueDelimiter( 1181*8c35d5eeSXin Li )" 1182*8c35d5eeSXin Li )FalseDelimiter" 1183*8c35d5eeSXin Li )TrueDelimiter"; 1184*8c35d5eeSXin Li }""", 1185*8c35d5eeSXin Li '') 1186*8c35d5eeSXin Li self.TestMultiLineLint( 1187*8c35d5eeSXin Li """ 1188*8c35d5eeSXin Li void Func() { 1189*8c35d5eeSXin Li char char kString[] = R"( ";" )"; 1190*8c35d5eeSXin Li }""", 1191*8c35d5eeSXin Li '') 1192*8c35d5eeSXin Li self.TestMultiLineLint( 1193*8c35d5eeSXin Li """ 1194*8c35d5eeSXin Li static const char kRawString[] = R"( 1195*8c35d5eeSXin Li \tstatic const int kLineWithTab = 1; 1196*8c35d5eeSXin Li static const int kLineWithTrailingWhiteSpace = 1;\x20 1197*8c35d5eeSXin Li 1198*8c35d5eeSXin Li void WeirdNumberOfSpacesAtLineStart() { 1199*8c35d5eeSXin Li string x; 1200*8c35d5eeSXin Li x += StrCat("Use StrAppend instead"); 1201*8c35d5eeSXin Li } 1202*8c35d5eeSXin Li 1203*8c35d5eeSXin Li void BlankLineAtEndOfBlock() { 1204*8c35d5eeSXin Li // TODO incorrectly formatted 1205*8c35d5eeSXin Li //Badly formatted comment 1206*8c35d5eeSXin Li 1207*8c35d5eeSXin Li } 1208*8c35d5eeSXin Li 1209*8c35d5eeSXin Li )";""", 1210*8c35d5eeSXin Li '') 1211*8c35d5eeSXin Li self.TestMultiLineLint( 1212*8c35d5eeSXin Li """ 1213*8c35d5eeSXin Li void Func() { 1214*8c35d5eeSXin Li string s = StrCat(R"TrueDelimiter( 1215*8c35d5eeSXin Li )" 1216*8c35d5eeSXin Li )FalseDelimiter" 1217*8c35d5eeSXin Li )TrueDelimiter", R"TrueDelimiter2( 1218*8c35d5eeSXin Li )" 1219*8c35d5eeSXin Li )FalseDelimiter2" 1220*8c35d5eeSXin Li )TrueDelimiter2"); 1221*8c35d5eeSXin Li }""", 1222*8c35d5eeSXin Li '') 1223*8c35d5eeSXin Li self.TestMultiLineLint( 1224*8c35d5eeSXin Li """ 1225*8c35d5eeSXin Li static SomeStruct kData = { 1226*8c35d5eeSXin Li {0, R"(line1 1227*8c35d5eeSXin Li line2 1228*8c35d5eeSXin Li )"} 1229*8c35d5eeSXin Li };""", 1230*8c35d5eeSXin Li '') 1231*8c35d5eeSXin Li 1232*8c35d5eeSXin Li def testMultiLineComments(self): 1233*8c35d5eeSXin Li # missing explicit is bad 1234*8c35d5eeSXin Li self.TestMultiLineLint( 1235*8c35d5eeSXin Li r"""int a = 0; 1236*8c35d5eeSXin Li /* multi-liner 1237*8c35d5eeSXin Li class Foo { 1238*8c35d5eeSXin Li Foo(int f); // should cause a lint warning in code 1239*8c35d5eeSXin Li } 1240*8c35d5eeSXin Li */ """, 1241*8c35d5eeSXin Li '') 1242*8c35d5eeSXin Li self.TestMultiLineLint( 1243*8c35d5eeSXin Li r"""/* int a = 0; multi-liner 1244*8c35d5eeSXin Li static const int b = 0;""", 1245*8c35d5eeSXin Li 'Could not find end of multi-line comment' 1246*8c35d5eeSXin Li ' [readability/multiline_comment] [5]') 1247*8c35d5eeSXin Li self.TestMultiLineLint(r""" /* multi-line comment""", 1248*8c35d5eeSXin Li 'Could not find end of multi-line comment' 1249*8c35d5eeSXin Li ' [readability/multiline_comment] [5]') 1250*8c35d5eeSXin Li self.TestMultiLineLint(r""" // /* comment, but not multi-line""", '') 1251*8c35d5eeSXin Li self.TestMultiLineLint(r"""/********** 1252*8c35d5eeSXin Li */""", '') 1253*8c35d5eeSXin Li self.TestMultiLineLint(r"""/** 1254*8c35d5eeSXin Li * Doxygen comment 1255*8c35d5eeSXin Li */""", 1256*8c35d5eeSXin Li '') 1257*8c35d5eeSXin Li self.TestMultiLineLint(r"""/*! 1258*8c35d5eeSXin Li * Doxygen comment 1259*8c35d5eeSXin Li */""", 1260*8c35d5eeSXin Li '') 1261*8c35d5eeSXin Li 1262*8c35d5eeSXin Li def testMultilineStrings(self): 1263*8c35d5eeSXin Li multiline_string_error_message = ( 1264*8c35d5eeSXin Li 'Multi-line string ("...") found. This lint script doesn\'t ' 1265*8c35d5eeSXin Li 'do well with such strings, and may give bogus warnings. ' 1266*8c35d5eeSXin Li 'Use C++11 raw strings or concatenation instead.' 1267*8c35d5eeSXin Li ' [readability/multiline_string] [5]') 1268*8c35d5eeSXin Li 1269*8c35d5eeSXin Li file_path = 'mydir/foo.cc' 1270*8c35d5eeSXin Li 1271*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 1272*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'cc', 1273*8c35d5eeSXin Li ['const char* str = "This is a\\', 1274*8c35d5eeSXin Li ' multiline string.";'], 1275*8c35d5eeSXin Li error_collector) 1276*8c35d5eeSXin Li self.assertEquals( 1277*8c35d5eeSXin Li 2, # One per line. 1278*8c35d5eeSXin Li error_collector.ResultList().count(multiline_string_error_message)) 1279*8c35d5eeSXin Li 1280*8c35d5eeSXin Li # Test non-explicit single-argument constructors 1281*8c35d5eeSXin Li def testExplicitSingleArgumentConstructors(self): 1282*8c35d5eeSXin Li old_verbose_level = cpplint._cpplint_state.verbose_level 1283*8c35d5eeSXin Li cpplint._cpplint_state.verbose_level = 0 1284*8c35d5eeSXin Li 1285*8c35d5eeSXin Li try: 1286*8c35d5eeSXin Li # missing explicit is bad 1287*8c35d5eeSXin Li self.TestMultiLineLint( 1288*8c35d5eeSXin Li """ 1289*8c35d5eeSXin Li class Foo { 1290*8c35d5eeSXin Li Foo(int f); 1291*8c35d5eeSXin Li };""", 1292*8c35d5eeSXin Li 'Single-parameter constructors should be marked explicit.' 1293*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1294*8c35d5eeSXin Li # missing explicit is bad, even with whitespace 1295*8c35d5eeSXin Li self.TestMultiLineLint( 1296*8c35d5eeSXin Li """ 1297*8c35d5eeSXin Li class Foo { 1298*8c35d5eeSXin Li Foo (int f); 1299*8c35d5eeSXin Li };""", 1300*8c35d5eeSXin Li ['Extra space before ( in function call [whitespace/parens] [4]', 1301*8c35d5eeSXin Li 'Single-parameter constructors should be marked explicit.' 1302*8c35d5eeSXin Li ' [runtime/explicit] [5]']) 1303*8c35d5eeSXin Li # missing explicit, with distracting comment, is still bad 1304*8c35d5eeSXin Li self.TestMultiLineLint( 1305*8c35d5eeSXin Li """ 1306*8c35d5eeSXin Li class Foo { 1307*8c35d5eeSXin Li Foo(int f); // simpler than Foo(blargh, blarg) 1308*8c35d5eeSXin Li };""", 1309*8c35d5eeSXin Li 'Single-parameter constructors should be marked explicit.' 1310*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1311*8c35d5eeSXin Li # missing explicit, with qualified classname 1312*8c35d5eeSXin Li self.TestMultiLineLint( 1313*8c35d5eeSXin Li """ 1314*8c35d5eeSXin Li class Qualifier::AnotherOne::Foo { 1315*8c35d5eeSXin Li Foo(int f); 1316*8c35d5eeSXin Li };""", 1317*8c35d5eeSXin Li 'Single-parameter constructors should be marked explicit.' 1318*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1319*8c35d5eeSXin Li # missing explicit for inline constructors is bad as well 1320*8c35d5eeSXin Li self.TestMultiLineLint( 1321*8c35d5eeSXin Li """ 1322*8c35d5eeSXin Li class Foo { 1323*8c35d5eeSXin Li inline Foo(int f); 1324*8c35d5eeSXin Li };""", 1325*8c35d5eeSXin Li 'Single-parameter constructors should be marked explicit.' 1326*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1327*8c35d5eeSXin Li # missing explicit for constexpr constructors is bad as well 1328*8c35d5eeSXin Li self.TestMultiLineLint( 1329*8c35d5eeSXin Li """ 1330*8c35d5eeSXin Li class Foo { 1331*8c35d5eeSXin Li constexpr Foo(int f); 1332*8c35d5eeSXin Li };""", 1333*8c35d5eeSXin Li 'Single-parameter constructors should be marked explicit.' 1334*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1335*8c35d5eeSXin Li # missing explicit for constexpr+inline constructors is bad as well 1336*8c35d5eeSXin Li self.TestMultiLineLint( 1337*8c35d5eeSXin Li """ 1338*8c35d5eeSXin Li class Foo { 1339*8c35d5eeSXin Li constexpr inline Foo(int f); 1340*8c35d5eeSXin Li };""", 1341*8c35d5eeSXin Li 'Single-parameter constructors should be marked explicit.' 1342*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1343*8c35d5eeSXin Li self.TestMultiLineLint( 1344*8c35d5eeSXin Li """ 1345*8c35d5eeSXin Li class Foo { 1346*8c35d5eeSXin Li inline constexpr Foo(int f); 1347*8c35d5eeSXin Li };""", 1348*8c35d5eeSXin Li 'Single-parameter constructors should be marked explicit.' 1349*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1350*8c35d5eeSXin Li # explicit with inline is accepted 1351*8c35d5eeSXin Li self.TestMultiLineLint( 1352*8c35d5eeSXin Li """ 1353*8c35d5eeSXin Li class Foo { 1354*8c35d5eeSXin Li inline explicit Foo(int f); 1355*8c35d5eeSXin Li };""", 1356*8c35d5eeSXin Li '') 1357*8c35d5eeSXin Li self.TestMultiLineLint( 1358*8c35d5eeSXin Li """ 1359*8c35d5eeSXin Li class Foo { 1360*8c35d5eeSXin Li explicit inline Foo(int f); 1361*8c35d5eeSXin Li };""", 1362*8c35d5eeSXin Li '') 1363*8c35d5eeSXin Li # explicit with constexpr is accepted 1364*8c35d5eeSXin Li self.TestMultiLineLint( 1365*8c35d5eeSXin Li """ 1366*8c35d5eeSXin Li class Foo { 1367*8c35d5eeSXin Li constexpr explicit Foo(int f); 1368*8c35d5eeSXin Li };""", 1369*8c35d5eeSXin Li '') 1370*8c35d5eeSXin Li self.TestMultiLineLint( 1371*8c35d5eeSXin Li """ 1372*8c35d5eeSXin Li class Foo { 1373*8c35d5eeSXin Li explicit constexpr Foo(int f); 1374*8c35d5eeSXin Li };""", 1375*8c35d5eeSXin Li '') 1376*8c35d5eeSXin Li # explicit with constexpr+inline is accepted 1377*8c35d5eeSXin Li self.TestMultiLineLint( 1378*8c35d5eeSXin Li """ 1379*8c35d5eeSXin Li class Foo { 1380*8c35d5eeSXin Li inline constexpr explicit Foo(int f); 1381*8c35d5eeSXin Li };""", 1382*8c35d5eeSXin Li '') 1383*8c35d5eeSXin Li self.TestMultiLineLint( 1384*8c35d5eeSXin Li """ 1385*8c35d5eeSXin Li class Foo { 1386*8c35d5eeSXin Li explicit inline constexpr Foo(int f); 1387*8c35d5eeSXin Li };""", 1388*8c35d5eeSXin Li '') 1389*8c35d5eeSXin Li self.TestMultiLineLint( 1390*8c35d5eeSXin Li """ 1391*8c35d5eeSXin Li class Foo { 1392*8c35d5eeSXin Li constexpr inline explicit Foo(int f); 1393*8c35d5eeSXin Li };""", 1394*8c35d5eeSXin Li '') 1395*8c35d5eeSXin Li self.TestMultiLineLint( 1396*8c35d5eeSXin Li """ 1397*8c35d5eeSXin Li class Foo { 1398*8c35d5eeSXin Li explicit constexpr inline Foo(int f); 1399*8c35d5eeSXin Li };""", 1400*8c35d5eeSXin Li '') 1401*8c35d5eeSXin Li # structs are caught as well. 1402*8c35d5eeSXin Li self.TestMultiLineLint( 1403*8c35d5eeSXin Li """ 1404*8c35d5eeSXin Li struct Foo { 1405*8c35d5eeSXin Li Foo(int f); 1406*8c35d5eeSXin Li };""", 1407*8c35d5eeSXin Li 'Single-parameter constructors should be marked explicit.' 1408*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1409*8c35d5eeSXin Li # Templatized classes are caught as well. 1410*8c35d5eeSXin Li self.TestMultiLineLint( 1411*8c35d5eeSXin Li """ 1412*8c35d5eeSXin Li template<typename T> class Foo { 1413*8c35d5eeSXin Li Foo(int f); 1414*8c35d5eeSXin Li };""", 1415*8c35d5eeSXin Li 'Single-parameter constructors should be marked explicit.' 1416*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1417*8c35d5eeSXin Li # inline case for templatized classes. 1418*8c35d5eeSXin Li self.TestMultiLineLint( 1419*8c35d5eeSXin Li """ 1420*8c35d5eeSXin Li template<typename T> class Foo { 1421*8c35d5eeSXin Li inline Foo(int f); 1422*8c35d5eeSXin Li };""", 1423*8c35d5eeSXin Li 'Single-parameter constructors should be marked explicit.' 1424*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1425*8c35d5eeSXin Li # constructors with a default argument should still be marked explicit 1426*8c35d5eeSXin Li self.TestMultiLineLint( 1427*8c35d5eeSXin Li """ 1428*8c35d5eeSXin Li class Foo { 1429*8c35d5eeSXin Li Foo(int f = 0); 1430*8c35d5eeSXin Li };""", 1431*8c35d5eeSXin Li 'Constructors callable with one argument should be marked explicit.' 1432*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1433*8c35d5eeSXin Li # multi-argument constructors with all but one default argument should be 1434*8c35d5eeSXin Li # marked explicit 1435*8c35d5eeSXin Li self.TestMultiLineLint( 1436*8c35d5eeSXin Li """ 1437*8c35d5eeSXin Li class Foo { 1438*8c35d5eeSXin Li Foo(int f, int g = 0); 1439*8c35d5eeSXin Li };""", 1440*8c35d5eeSXin Li 'Constructors callable with one argument should be marked explicit.' 1441*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1442*8c35d5eeSXin Li # multi-argument constructors with all default arguments should be marked 1443*8c35d5eeSXin Li # explicit 1444*8c35d5eeSXin Li self.TestMultiLineLint( 1445*8c35d5eeSXin Li """ 1446*8c35d5eeSXin Li class Foo { 1447*8c35d5eeSXin Li Foo(int f = 0, int g = 0); 1448*8c35d5eeSXin Li };""", 1449*8c35d5eeSXin Li 'Constructors callable with one argument should be marked explicit.' 1450*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1451*8c35d5eeSXin Li # explicit no-argument constructors are bad 1452*8c35d5eeSXin Li self.TestMultiLineLint( 1453*8c35d5eeSXin Li """ 1454*8c35d5eeSXin Li class Foo { 1455*8c35d5eeSXin Li explicit Foo(); 1456*8c35d5eeSXin Li };""", 1457*8c35d5eeSXin Li 'Zero-parameter constructors should not be marked explicit.' 1458*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1459*8c35d5eeSXin Li # void constructors are considered no-argument 1460*8c35d5eeSXin Li self.TestMultiLineLint( 1461*8c35d5eeSXin Li """ 1462*8c35d5eeSXin Li class Foo { 1463*8c35d5eeSXin Li explicit Foo(void); 1464*8c35d5eeSXin Li };""", 1465*8c35d5eeSXin Li 'Zero-parameter constructors should not be marked explicit.' 1466*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1467*8c35d5eeSXin Li # No warning for multi-parameter constructors 1468*8c35d5eeSXin Li self.TestMultiLineLint( 1469*8c35d5eeSXin Li """ 1470*8c35d5eeSXin Li class Foo { 1471*8c35d5eeSXin Li explicit Foo(int f, int g); 1472*8c35d5eeSXin Li };""", 1473*8c35d5eeSXin Li '') 1474*8c35d5eeSXin Li self.TestMultiLineLint( 1475*8c35d5eeSXin Li """ 1476*8c35d5eeSXin Li class Foo { 1477*8c35d5eeSXin Li explicit Foo(int f, int g = 0); 1478*8c35d5eeSXin Li };""", 1479*8c35d5eeSXin Li '') 1480*8c35d5eeSXin Li # single-argument constructors that take a function that takes multiple 1481*8c35d5eeSXin Li # arguments should be explicit 1482*8c35d5eeSXin Li self.TestMultiLineLint( 1483*8c35d5eeSXin Li """ 1484*8c35d5eeSXin Li class Foo { 1485*8c35d5eeSXin Li Foo(void (*f)(int f, int g)); 1486*8c35d5eeSXin Li };""", 1487*8c35d5eeSXin Li 'Single-parameter constructors should be marked explicit.' 1488*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1489*8c35d5eeSXin Li # single-argument constructors that take a single template argument with 1490*8c35d5eeSXin Li # multiple parameters should be explicit 1491*8c35d5eeSXin Li self.TestMultiLineLint( 1492*8c35d5eeSXin Li """ 1493*8c35d5eeSXin Li template <typename T, typename S> 1494*8c35d5eeSXin Li class Foo { 1495*8c35d5eeSXin Li Foo(Bar<T, S> b); 1496*8c35d5eeSXin Li };""", 1497*8c35d5eeSXin Li 'Single-parameter constructors should be marked explicit.' 1498*8c35d5eeSXin Li ' [runtime/explicit] [5]') 1499*8c35d5eeSXin Li # but copy constructors that take multiple template parameters are OK 1500*8c35d5eeSXin Li self.TestMultiLineLint( 1501*8c35d5eeSXin Li """ 1502*8c35d5eeSXin Li template <typename T, S> 1503*8c35d5eeSXin Li class Foo { 1504*8c35d5eeSXin Li Foo(Foo<T, S>& f); 1505*8c35d5eeSXin Li };""", 1506*8c35d5eeSXin Li '') 1507*8c35d5eeSXin Li # proper style is okay 1508*8c35d5eeSXin Li self.TestMultiLineLint( 1509*8c35d5eeSXin Li """ 1510*8c35d5eeSXin Li class Foo { 1511*8c35d5eeSXin Li explicit Foo(int f); 1512*8c35d5eeSXin Li };""", 1513*8c35d5eeSXin Li '') 1514*8c35d5eeSXin Li # two argument constructor is okay 1515*8c35d5eeSXin Li self.TestMultiLineLint( 1516*8c35d5eeSXin Li """ 1517*8c35d5eeSXin Li class Foo { 1518*8c35d5eeSXin Li Foo(int f, int b); 1519*8c35d5eeSXin Li };""", 1520*8c35d5eeSXin Li '') 1521*8c35d5eeSXin Li # two argument constructor, across two lines, is okay 1522*8c35d5eeSXin Li self.TestMultiLineLint( 1523*8c35d5eeSXin Li """ 1524*8c35d5eeSXin Li class Foo { 1525*8c35d5eeSXin Li Foo(int f, 1526*8c35d5eeSXin Li int b); 1527*8c35d5eeSXin Li };""", 1528*8c35d5eeSXin Li '') 1529*8c35d5eeSXin Li # non-constructor (but similar name), is okay 1530*8c35d5eeSXin Li self.TestMultiLineLint( 1531*8c35d5eeSXin Li """ 1532*8c35d5eeSXin Li class Foo { 1533*8c35d5eeSXin Li aFoo(int f); 1534*8c35d5eeSXin Li };""", 1535*8c35d5eeSXin Li '') 1536*8c35d5eeSXin Li # constructor with void argument is okay 1537*8c35d5eeSXin Li self.TestMultiLineLint( 1538*8c35d5eeSXin Li """ 1539*8c35d5eeSXin Li class Foo { 1540*8c35d5eeSXin Li Foo(void); 1541*8c35d5eeSXin Li };""", 1542*8c35d5eeSXin Li '') 1543*8c35d5eeSXin Li # single argument method is okay 1544*8c35d5eeSXin Li self.TestMultiLineLint( 1545*8c35d5eeSXin Li """ 1546*8c35d5eeSXin Li class Foo { 1547*8c35d5eeSXin Li Bar(int b); 1548*8c35d5eeSXin Li };""", 1549*8c35d5eeSXin Li '') 1550*8c35d5eeSXin Li # comments should be ignored 1551*8c35d5eeSXin Li self.TestMultiLineLint( 1552*8c35d5eeSXin Li """ 1553*8c35d5eeSXin Li class Foo { 1554*8c35d5eeSXin Li // Foo(int f); 1555*8c35d5eeSXin Li };""", 1556*8c35d5eeSXin Li '') 1557*8c35d5eeSXin Li # single argument function following class definition is okay 1558*8c35d5eeSXin Li # (okay, it's not actually valid, but we don't want a false positive) 1559*8c35d5eeSXin Li self.TestMultiLineLint( 1560*8c35d5eeSXin Li """ 1561*8c35d5eeSXin Li class Foo { 1562*8c35d5eeSXin Li Foo(int f, int b); 1563*8c35d5eeSXin Li }; 1564*8c35d5eeSXin Li Foo(int f);""", 1565*8c35d5eeSXin Li '') 1566*8c35d5eeSXin Li # single argument function is okay 1567*8c35d5eeSXin Li self.TestMultiLineLint( 1568*8c35d5eeSXin Li """static Foo(int f);""", 1569*8c35d5eeSXin Li '') 1570*8c35d5eeSXin Li # single argument copy constructor is okay. 1571*8c35d5eeSXin Li self.TestMultiLineLint( 1572*8c35d5eeSXin Li """ 1573*8c35d5eeSXin Li class Foo { 1574*8c35d5eeSXin Li Foo(const Foo&); 1575*8c35d5eeSXin Li };""", 1576*8c35d5eeSXin Li '') 1577*8c35d5eeSXin Li self.TestMultiLineLint( 1578*8c35d5eeSXin Li """ 1579*8c35d5eeSXin Li class Foo { 1580*8c35d5eeSXin Li Foo(Foo const&); 1581*8c35d5eeSXin Li };""", 1582*8c35d5eeSXin Li '') 1583*8c35d5eeSXin Li self.TestMultiLineLint( 1584*8c35d5eeSXin Li """ 1585*8c35d5eeSXin Li class Foo { 1586*8c35d5eeSXin Li Foo(Foo&); 1587*8c35d5eeSXin Li };""", 1588*8c35d5eeSXin Li '') 1589*8c35d5eeSXin Li # templatized copy constructor is okay. 1590*8c35d5eeSXin Li self.TestMultiLineLint( 1591*8c35d5eeSXin Li """ 1592*8c35d5eeSXin Li template<typename T> class Foo { 1593*8c35d5eeSXin Li Foo(const Foo<T>&); 1594*8c35d5eeSXin Li };""", 1595*8c35d5eeSXin Li '') 1596*8c35d5eeSXin Li # Special case for std::initializer_list 1597*8c35d5eeSXin Li self.TestMultiLineLint( 1598*8c35d5eeSXin Li """ 1599*8c35d5eeSXin Li class Foo { 1600*8c35d5eeSXin Li Foo(std::initializer_list<T> &arg) {} 1601*8c35d5eeSXin Li };""", 1602*8c35d5eeSXin Li '') 1603*8c35d5eeSXin Li # Anything goes inside an assembly block 1604*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 1605*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', 1606*8c35d5eeSXin Li ['void Func() {', 1607*8c35d5eeSXin Li ' __asm__ (', 1608*8c35d5eeSXin Li ' "hlt"', 1609*8c35d5eeSXin Li ' );', 1610*8c35d5eeSXin Li ' asm {', 1611*8c35d5eeSXin Li ' movdqa [edx + 32], xmm2', 1612*8c35d5eeSXin Li ' }', 1613*8c35d5eeSXin Li '}'], 1614*8c35d5eeSXin Li error_collector) 1615*8c35d5eeSXin Li self.assertEquals( 1616*8c35d5eeSXin Li 0, 1617*8c35d5eeSXin Li error_collector.ResultList().count( 1618*8c35d5eeSXin Li 'Extra space before ( in function call [whitespace/parens] [4]')) 1619*8c35d5eeSXin Li self.assertEquals( 1620*8c35d5eeSXin Li 0, 1621*8c35d5eeSXin Li error_collector.ResultList().count( 1622*8c35d5eeSXin Li 'Closing ) should be moved to the previous line ' 1623*8c35d5eeSXin Li '[whitespace/parens] [2]')) 1624*8c35d5eeSXin Li self.assertEquals( 1625*8c35d5eeSXin Li 0, 1626*8c35d5eeSXin Li error_collector.ResultList().count( 1627*8c35d5eeSXin Li 'Extra space before [ [whitespace/braces] [5]')) 1628*8c35d5eeSXin Li finally: 1629*8c35d5eeSXin Li cpplint._cpplint_state.verbose_level = old_verbose_level 1630*8c35d5eeSXin Li 1631*8c35d5eeSXin Li def testSlashStarCommentOnSingleLine(self): 1632*8c35d5eeSXin Li self.TestMultiLineLint( 1633*8c35d5eeSXin Li """/* static */ Foo(int f);""", 1634*8c35d5eeSXin Li '') 1635*8c35d5eeSXin Li self.TestMultiLineLint( 1636*8c35d5eeSXin Li """/*/ static */ Foo(int f);""", 1637*8c35d5eeSXin Li '') 1638*8c35d5eeSXin Li self.TestMultiLineLint( 1639*8c35d5eeSXin Li """/*/ static Foo(int f);""", 1640*8c35d5eeSXin Li 'Could not find end of multi-line comment' 1641*8c35d5eeSXin Li ' [readability/multiline_comment] [5]') 1642*8c35d5eeSXin Li self.TestMultiLineLint( 1643*8c35d5eeSXin Li """ /*/ static Foo(int f);""", 1644*8c35d5eeSXin Li 'Could not find end of multi-line comment' 1645*8c35d5eeSXin Li ' [readability/multiline_comment] [5]') 1646*8c35d5eeSXin Li self.TestMultiLineLint( 1647*8c35d5eeSXin Li """ /**/ static Foo(int f);""", 1648*8c35d5eeSXin Li '') 1649*8c35d5eeSXin Li 1650*8c35d5eeSXin Li # Test suspicious usage of "if" like this: 1651*8c35d5eeSXin Li # if (a == b) { 1652*8c35d5eeSXin Li # DoSomething(); 1653*8c35d5eeSXin Li # } if (a == c) { // Should be "else if". 1654*8c35d5eeSXin Li # DoSomething(); // This gets called twice if a == b && a == c. 1655*8c35d5eeSXin Li # } 1656*8c35d5eeSXin Li def testSuspiciousUsageOfIf(self): 1657*8c35d5eeSXin Li self.TestLint( 1658*8c35d5eeSXin Li ' if (a == b) {', 1659*8c35d5eeSXin Li '') 1660*8c35d5eeSXin Li self.TestLint( 1661*8c35d5eeSXin Li ' } if (a == b) {', 1662*8c35d5eeSXin Li 'Did you mean "else if"? If not, start a new line for "if".' 1663*8c35d5eeSXin Li ' [readability/braces] [4]') 1664*8c35d5eeSXin Li 1665*8c35d5eeSXin Li # Test suspicious usage of memset. Specifically, a 0 1666*8c35d5eeSXin Li # as the final argument is almost certainly an error. 1667*8c35d5eeSXin Li def testSuspiciousUsageOfMemset(self): 1668*8c35d5eeSXin Li # Normal use is okay. 1669*8c35d5eeSXin Li self.TestLint( 1670*8c35d5eeSXin Li ' memset(buf, 0, sizeof(buf))', 1671*8c35d5eeSXin Li '') 1672*8c35d5eeSXin Li 1673*8c35d5eeSXin Li # A 0 as the final argument is almost certainly an error. 1674*8c35d5eeSXin Li self.TestLint( 1675*8c35d5eeSXin Li ' memset(buf, sizeof(buf), 0)', 1676*8c35d5eeSXin Li 'Did you mean "memset(buf, 0, sizeof(buf))"?' 1677*8c35d5eeSXin Li ' [runtime/memset] [4]') 1678*8c35d5eeSXin Li self.TestLint( 1679*8c35d5eeSXin Li ' memset(buf, xsize * ysize, 0)', 1680*8c35d5eeSXin Li 'Did you mean "memset(buf, 0, xsize * ysize)"?' 1681*8c35d5eeSXin Li ' [runtime/memset] [4]') 1682*8c35d5eeSXin Li 1683*8c35d5eeSXin Li # There is legitimate test code that uses this form. 1684*8c35d5eeSXin Li # This is okay since the second argument is a literal. 1685*8c35d5eeSXin Li self.TestLint( 1686*8c35d5eeSXin Li " memset(buf, 'y', 0)", 1687*8c35d5eeSXin Li '') 1688*8c35d5eeSXin Li self.TestLint( 1689*8c35d5eeSXin Li ' memset(buf, 4, 0)', 1690*8c35d5eeSXin Li '') 1691*8c35d5eeSXin Li self.TestLint( 1692*8c35d5eeSXin Li ' memset(buf, -1, 0)', 1693*8c35d5eeSXin Li '') 1694*8c35d5eeSXin Li self.TestLint( 1695*8c35d5eeSXin Li ' memset(buf, 0xF1, 0)', 1696*8c35d5eeSXin Li '') 1697*8c35d5eeSXin Li self.TestLint( 1698*8c35d5eeSXin Li ' memset(buf, 0xcd, 0)', 1699*8c35d5eeSXin Li '') 1700*8c35d5eeSXin Li 1701*8c35d5eeSXin Li def testRedundantVirtual(self): 1702*8c35d5eeSXin Li self.TestLint('virtual void F()', '') 1703*8c35d5eeSXin Li self.TestLint('virtual void F();', '') 1704*8c35d5eeSXin Li self.TestLint('virtual void F() {}', '') 1705*8c35d5eeSXin Li 1706*8c35d5eeSXin Li message_template = ('"%s" is redundant since function is already ' 1707*8c35d5eeSXin Li 'declared as "%s" [readability/inheritance] [4]') 1708*8c35d5eeSXin Li for virt_specifier in ['override', 'final']: 1709*8c35d5eeSXin Li error_message = message_template % ('virtual', virt_specifier) 1710*8c35d5eeSXin Li self.TestLint('virtual int F() %s' % virt_specifier, error_message) 1711*8c35d5eeSXin Li self.TestLint('virtual int F() %s;' % virt_specifier, error_message) 1712*8c35d5eeSXin Li self.TestLint('virtual int F() %s {' % virt_specifier, error_message) 1713*8c35d5eeSXin Li 1714*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 1715*8c35d5eeSXin Li cpplint.ProcessFileData( 1716*8c35d5eeSXin Li 'foo.cc', 'cc', 1717*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 1718*8c35d5eeSXin Li 'virtual void F(int a,', 1719*8c35d5eeSXin Li ' int b) ' + virt_specifier + ';', 1720*8c35d5eeSXin Li 'virtual void F(int a,', 1721*8c35d5eeSXin Li ' int b) LOCKS_EXCLUDED(lock) ' + virt_specifier + ';', 1722*8c35d5eeSXin Li 'virtual void F(int a,', 1723*8c35d5eeSXin Li ' int b)', 1724*8c35d5eeSXin Li ' LOCKS_EXCLUDED(lock) ' + virt_specifier + ';', 1725*8c35d5eeSXin Li ''], 1726*8c35d5eeSXin Li error_collector) 1727*8c35d5eeSXin Li self.assertEquals( 1728*8c35d5eeSXin Li [error_message, error_message, error_message], 1729*8c35d5eeSXin Li error_collector.Results()) 1730*8c35d5eeSXin Li 1731*8c35d5eeSXin Li error_message = message_template % ('override', 'final') 1732*8c35d5eeSXin Li self.TestLint('int F() override final', error_message) 1733*8c35d5eeSXin Li self.TestLint('int F() override final;', error_message) 1734*8c35d5eeSXin Li self.TestLint('int F() override final {}', error_message) 1735*8c35d5eeSXin Li self.TestLint('int F() final override', error_message) 1736*8c35d5eeSXin Li self.TestLint('int F() final override;', error_message) 1737*8c35d5eeSXin Li self.TestLint('int F() final override {}', error_message) 1738*8c35d5eeSXin Li 1739*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 1740*8c35d5eeSXin Li cpplint.ProcessFileData( 1741*8c35d5eeSXin Li 'foo.cc', 'cc', 1742*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 1743*8c35d5eeSXin Li 'struct A : virtual B {', 1744*8c35d5eeSXin Li ' ~A() override;' 1745*8c35d5eeSXin Li '};', 1746*8c35d5eeSXin Li 'class C', 1747*8c35d5eeSXin Li ' : public D,', 1748*8c35d5eeSXin Li ' public virtual E {', 1749*8c35d5eeSXin Li ' void Func() override;', 1750*8c35d5eeSXin Li '}', 1751*8c35d5eeSXin Li ''], 1752*8c35d5eeSXin Li error_collector) 1753*8c35d5eeSXin Li self.assertEquals('', error_collector.Results()) 1754*8c35d5eeSXin Li 1755*8c35d5eeSXin Li self.TestLint('void Finalize(AnnotationProto *final) override;', '') 1756*8c35d5eeSXin Li 1757*8c35d5eeSXin Li def testCheckDeprecated(self): 1758*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo_test.cc', '#include <iostream>', '') 1759*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo_unittest.cc', '#include <iostream>', '') 1760*8c35d5eeSXin Li 1761*8c35d5eeSXin Li def testCheckPosixThreading(self): 1762*8c35d5eeSXin Li self.TestLint('var = sctime_r()', '') 1763*8c35d5eeSXin Li self.TestLint('var = strtok_r()', '') 1764*8c35d5eeSXin Li self.TestLint('var = strtok_r(foo, ba, r)', '') 1765*8c35d5eeSXin Li self.TestLint('var = brand()', '') 1766*8c35d5eeSXin Li self.TestLint('_rand()', '') 1767*8c35d5eeSXin Li self.TestLint('.rand()', '') 1768*8c35d5eeSXin Li self.TestLint('->rand()', '') 1769*8c35d5eeSXin Li self.TestLint('ACMRandom rand(seed)', '') 1770*8c35d5eeSXin Li self.TestLint('ISAACRandom rand()', '') 1771*8c35d5eeSXin Li self.TestLint('var = rand()', 1772*8c35d5eeSXin Li 'Consider using rand_r(...) instead of rand(...)' 1773*8c35d5eeSXin Li ' for improved thread safety.' 1774*8c35d5eeSXin Li ' [runtime/threadsafe_fn] [2]') 1775*8c35d5eeSXin Li self.TestLint('var = strtok(str, delim)', 1776*8c35d5eeSXin Li 'Consider using strtok_r(...) ' 1777*8c35d5eeSXin Li 'instead of strtok(...)' 1778*8c35d5eeSXin Li ' for improved thread safety.' 1779*8c35d5eeSXin Li ' [runtime/threadsafe_fn] [2]') 1780*8c35d5eeSXin Li 1781*8c35d5eeSXin Li def testVlogMisuse(self): 1782*8c35d5eeSXin Li self.TestLint('VLOG(1)', '') 1783*8c35d5eeSXin Li self.TestLint('VLOG(99)', '') 1784*8c35d5eeSXin Li self.TestLint('LOG(ERROR)', '') 1785*8c35d5eeSXin Li self.TestLint('LOG(INFO)', '') 1786*8c35d5eeSXin Li self.TestLint('LOG(WARNING)', '') 1787*8c35d5eeSXin Li self.TestLint('LOG(FATAL)', '') 1788*8c35d5eeSXin Li self.TestLint('LOG(DFATAL)', '') 1789*8c35d5eeSXin Li self.TestLint('VLOG(SOMETHINGWEIRD)', '') 1790*8c35d5eeSXin Li self.TestLint('MYOWNVLOG(ERROR)', '') 1791*8c35d5eeSXin Li errmsg = ('VLOG() should be used with numeric verbosity level. ' 1792*8c35d5eeSXin Li 'Use LOG() if you want symbolic severity levels.' 1793*8c35d5eeSXin Li ' [runtime/vlog] [5]') 1794*8c35d5eeSXin Li self.TestLint('VLOG(ERROR)', errmsg) 1795*8c35d5eeSXin Li self.TestLint('VLOG(INFO)', errmsg) 1796*8c35d5eeSXin Li self.TestLint('VLOG(WARNING)', errmsg) 1797*8c35d5eeSXin Li self.TestLint('VLOG(FATAL)', errmsg) 1798*8c35d5eeSXin Li self.TestLint('VLOG(DFATAL)', errmsg) 1799*8c35d5eeSXin Li self.TestLint(' VLOG(ERROR)', errmsg) 1800*8c35d5eeSXin Li self.TestLint(' VLOG(INFO)', errmsg) 1801*8c35d5eeSXin Li self.TestLint(' VLOG(WARNING)', errmsg) 1802*8c35d5eeSXin Li self.TestLint(' VLOG(FATAL)', errmsg) 1803*8c35d5eeSXin Li self.TestLint(' VLOG(DFATAL)', errmsg) 1804*8c35d5eeSXin Li 1805*8c35d5eeSXin Li 1806*8c35d5eeSXin Li # Test potential format string bugs like printf(foo). 1807*8c35d5eeSXin Li def testFormatStrings(self): 1808*8c35d5eeSXin Li self.TestLint('printf("foo")', '') 1809*8c35d5eeSXin Li self.TestLint('printf("foo: %s", foo)', '') 1810*8c35d5eeSXin Li self.TestLint('DocidForPrintf(docid)', '') # Should not trigger. 1811*8c35d5eeSXin Li self.TestLint('printf(format, value)', '') # Should not trigger. 1812*8c35d5eeSXin Li self.TestLint('printf(__VA_ARGS__)', '') # Should not trigger. 1813*8c35d5eeSXin Li self.TestLint('printf(format.c_str(), value)', '') # Should not trigger. 1814*8c35d5eeSXin Li self.TestLint('printf(format(index).c_str(), value)', '') 1815*8c35d5eeSXin Li self.TestLint( 1816*8c35d5eeSXin Li 'printf(foo)', 1817*8c35d5eeSXin Li 'Potential format string bug. Do printf("%s", foo) instead.' 1818*8c35d5eeSXin Li ' [runtime/printf] [4]') 1819*8c35d5eeSXin Li self.TestLint( 1820*8c35d5eeSXin Li 'printf(foo.c_str())', 1821*8c35d5eeSXin Li 'Potential format string bug. ' 1822*8c35d5eeSXin Li 'Do printf("%s", foo.c_str()) instead.' 1823*8c35d5eeSXin Li ' [runtime/printf] [4]') 1824*8c35d5eeSXin Li self.TestLint( 1825*8c35d5eeSXin Li 'printf(foo->c_str())', 1826*8c35d5eeSXin Li 'Potential format string bug. ' 1827*8c35d5eeSXin Li 'Do printf("%s", foo->c_str()) instead.' 1828*8c35d5eeSXin Li ' [runtime/printf] [4]') 1829*8c35d5eeSXin Li self.TestLint( 1830*8c35d5eeSXin Li 'StringPrintf(foo)', 1831*8c35d5eeSXin Li 'Potential format string bug. Do StringPrintf("%s", foo) instead.' 1832*8c35d5eeSXin Li '' 1833*8c35d5eeSXin Li ' [runtime/printf] [4]') 1834*8c35d5eeSXin Li 1835*8c35d5eeSXin Li # Test disallowed use of operator& and other operators. 1836*8c35d5eeSXin Li def testIllegalOperatorOverloading(self): 1837*8c35d5eeSXin Li errmsg = ('Unary operator& is dangerous. Do not use it.' 1838*8c35d5eeSXin Li ' [runtime/operator] [4]') 1839*8c35d5eeSXin Li self.TestLint('void operator=(const Myclass&)', '') 1840*8c35d5eeSXin Li self.TestLint('void operator&(int a, int b)', '') # binary operator& ok 1841*8c35d5eeSXin Li self.TestLint('void operator&() { }', errmsg) 1842*8c35d5eeSXin Li self.TestLint('void operator & ( ) { }', 1843*8c35d5eeSXin Li ['Extra space after ( [whitespace/parens] [2]', errmsg]) 1844*8c35d5eeSXin Li 1845*8c35d5eeSXin Li # const string reference members are dangerous.. 1846*8c35d5eeSXin Li def testConstStringReferenceMembers(self): 1847*8c35d5eeSXin Li errmsg = ('const string& members are dangerous. It is much better to use ' 1848*8c35d5eeSXin Li 'alternatives, such as pointers or simple constants.' 1849*8c35d5eeSXin Li ' [runtime/member_string_references] [2]') 1850*8c35d5eeSXin Li 1851*8c35d5eeSXin Li members_declarations = ['const string& church', 1852*8c35d5eeSXin Li 'const string &turing', 1853*8c35d5eeSXin Li 'const string & godel'] 1854*8c35d5eeSXin Li # TODO(unknown): Enable also these tests if and when we ever 1855*8c35d5eeSXin Li # decide to check for arbitrary member references. 1856*8c35d5eeSXin Li # "const Turing & a", 1857*8c35d5eeSXin Li # "const Church& a", 1858*8c35d5eeSXin Li # "const vector<int>& a", 1859*8c35d5eeSXin Li # "const Kurt::Godel & godel", 1860*8c35d5eeSXin Li # "const Kazimierz::Kuratowski& kk" ] 1861*8c35d5eeSXin Li 1862*8c35d5eeSXin Li # The Good. 1863*8c35d5eeSXin Li 1864*8c35d5eeSXin Li self.TestLint('void f(const string&)', '') 1865*8c35d5eeSXin Li self.TestLint('const string& f(const string& a, const string& b)', '') 1866*8c35d5eeSXin Li self.TestLint('typedef const string& A;', '') 1867*8c35d5eeSXin Li 1868*8c35d5eeSXin Li for decl in members_declarations: 1869*8c35d5eeSXin Li self.TestLint(decl + ' = b;', '') 1870*8c35d5eeSXin Li self.TestLint(decl + ' =', '') 1871*8c35d5eeSXin Li 1872*8c35d5eeSXin Li # The Bad. 1873*8c35d5eeSXin Li 1874*8c35d5eeSXin Li for decl in members_declarations: 1875*8c35d5eeSXin Li self.TestLint(decl + ';', errmsg) 1876*8c35d5eeSXin Li 1877*8c35d5eeSXin Li # Variable-length arrays are not permitted. 1878*8c35d5eeSXin Li def testVariableLengthArrayDetection(self): 1879*8c35d5eeSXin Li errmsg = ('Do not use variable-length arrays. Use an appropriately named ' 1880*8c35d5eeSXin Li "('k' followed by CamelCase) compile-time constant for the size." 1881*8c35d5eeSXin Li ' [runtime/arrays] [1]') 1882*8c35d5eeSXin Li 1883*8c35d5eeSXin Li self.TestLint('int a[any_old_variable];', errmsg) 1884*8c35d5eeSXin Li self.TestLint('int doublesize[some_var * 2];', errmsg) 1885*8c35d5eeSXin Li self.TestLint('int a[afunction()];', errmsg) 1886*8c35d5eeSXin Li self.TestLint('int a[function(kMaxFooBars)];', errmsg) 1887*8c35d5eeSXin Li self.TestLint('bool a_list[items_->size()];', errmsg) 1888*8c35d5eeSXin Li self.TestLint('namespace::Type buffer[len+1];', errmsg) 1889*8c35d5eeSXin Li 1890*8c35d5eeSXin Li self.TestLint('int a[64];', '') 1891*8c35d5eeSXin Li self.TestLint('int a[0xFF];', '') 1892*8c35d5eeSXin Li self.TestLint('int first[256], second[256];', '') 1893*8c35d5eeSXin Li self.TestLint('int array_name[kCompileTimeConstant];', '') 1894*8c35d5eeSXin Li self.TestLint('char buf[somenamespace::kBufSize];', '') 1895*8c35d5eeSXin Li self.TestLint('int array_name[ALL_CAPS];', '') 1896*8c35d5eeSXin Li self.TestLint('AClass array1[foo::bar::ALL_CAPS];', '') 1897*8c35d5eeSXin Li self.TestLint('int a[kMaxStrLen + 1];', '') 1898*8c35d5eeSXin Li self.TestLint('int a[sizeof(foo)];', '') 1899*8c35d5eeSXin Li self.TestLint('int a[sizeof(*foo)];', '') 1900*8c35d5eeSXin Li self.TestLint('int a[sizeof foo];', '') 1901*8c35d5eeSXin Li self.TestLint('int a[sizeof(struct Foo)];', '') 1902*8c35d5eeSXin Li self.TestLint('int a[128 - sizeof(const bar)];', '') 1903*8c35d5eeSXin Li self.TestLint('int a[(sizeof(foo) * 4)];', '') 1904*8c35d5eeSXin Li self.TestLint('int a[(arraysize(fixed_size_array)/2) << 1];', '') 1905*8c35d5eeSXin Li self.TestLint('delete a[some_var];', '') 1906*8c35d5eeSXin Li self.TestLint('return a[some_var];', '') 1907*8c35d5eeSXin Li 1908*8c35d5eeSXin Li # DISALLOW_COPY_AND_ASSIGN and DISALLOW_IMPLICIT_CONSTRUCTORS should be at 1909*8c35d5eeSXin Li # end of class if present. 1910*8c35d5eeSXin Li def testDisallowMacrosAtEnd(self): 1911*8c35d5eeSXin Li for macro_name in ( 1912*8c35d5eeSXin Li 'DISALLOW_COPY_AND_ASSIGN', 1913*8c35d5eeSXin Li 'DISALLOW_IMPLICIT_CONSTRUCTORS'): 1914*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 1915*8c35d5eeSXin Li cpplint.ProcessFileData( 1916*8c35d5eeSXin Li 'foo.cc', 'cc', 1917*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 1918*8c35d5eeSXin Li 'class SomeClass {', 1919*8c35d5eeSXin Li ' private:', 1920*8c35d5eeSXin Li ' %s(SomeClass);' % macro_name, 1921*8c35d5eeSXin Li ' int member_;', 1922*8c35d5eeSXin Li '};', 1923*8c35d5eeSXin Li ''], 1924*8c35d5eeSXin Li error_collector) 1925*8c35d5eeSXin Li self.assertEquals( 1926*8c35d5eeSXin Li ('%s should be the last thing in the class' % macro_name) + 1927*8c35d5eeSXin Li ' [readability/constructors] [3]', 1928*8c35d5eeSXin Li error_collector.Results()) 1929*8c35d5eeSXin Li 1930*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 1931*8c35d5eeSXin Li cpplint.ProcessFileData( 1932*8c35d5eeSXin Li 'foo.cc', 'cc', 1933*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 1934*8c35d5eeSXin Li 'class OuterClass {', 1935*8c35d5eeSXin Li ' private:', 1936*8c35d5eeSXin Li ' struct InnerClass {', 1937*8c35d5eeSXin Li ' private:', 1938*8c35d5eeSXin Li ' %s(InnerClass);' % macro_name, 1939*8c35d5eeSXin Li ' int member;', 1940*8c35d5eeSXin Li ' };', 1941*8c35d5eeSXin Li '};', 1942*8c35d5eeSXin Li ''], 1943*8c35d5eeSXin Li error_collector) 1944*8c35d5eeSXin Li self.assertEquals( 1945*8c35d5eeSXin Li ('%s should be the last thing in the class' % macro_name) + 1946*8c35d5eeSXin Li ' [readability/constructors] [3]', 1947*8c35d5eeSXin Li error_collector.Results()) 1948*8c35d5eeSXin Li 1949*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 1950*8c35d5eeSXin Li cpplint.ProcessFileData( 1951*8c35d5eeSXin Li 'foo.cc', 'cc', 1952*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 1953*8c35d5eeSXin Li 'class OuterClass1 {', 1954*8c35d5eeSXin Li ' private:', 1955*8c35d5eeSXin Li ' struct InnerClass1 {', 1956*8c35d5eeSXin Li ' private:', 1957*8c35d5eeSXin Li ' %s(InnerClass1);' % macro_name, 1958*8c35d5eeSXin Li ' };', 1959*8c35d5eeSXin Li ' %s(OuterClass1);' % macro_name, 1960*8c35d5eeSXin Li '};', 1961*8c35d5eeSXin Li 'struct OuterClass2 {', 1962*8c35d5eeSXin Li ' private:', 1963*8c35d5eeSXin Li ' class InnerClass2 {', 1964*8c35d5eeSXin Li ' private:', 1965*8c35d5eeSXin Li ' %s(InnerClass2);' % macro_name, 1966*8c35d5eeSXin Li ' // comment', 1967*8c35d5eeSXin Li ' };', 1968*8c35d5eeSXin Li '', 1969*8c35d5eeSXin Li ' %s(OuterClass2);' % macro_name, 1970*8c35d5eeSXin Li '', 1971*8c35d5eeSXin Li ' // comment', 1972*8c35d5eeSXin Li '};', 1973*8c35d5eeSXin Li 'void Func() {', 1974*8c35d5eeSXin Li ' struct LocalClass {', 1975*8c35d5eeSXin Li ' private:', 1976*8c35d5eeSXin Li ' %s(LocalClass);' % macro_name, 1977*8c35d5eeSXin Li ' } variable;', 1978*8c35d5eeSXin Li '}', 1979*8c35d5eeSXin Li ''], 1980*8c35d5eeSXin Li error_collector) 1981*8c35d5eeSXin Li self.assertEquals('', error_collector.Results()) 1982*8c35d5eeSXin Li 1983*8c35d5eeSXin Li # Brace usage 1984*8c35d5eeSXin Li def testBraces(self): 1985*8c35d5eeSXin Li # Braces shouldn't be followed by a ; unless they're defining a struct 1986*8c35d5eeSXin Li # or initializing an array 1987*8c35d5eeSXin Li self.TestLint('int a[3] = { 1, 2, 3 };', '') 1988*8c35d5eeSXin Li self.TestLint( 1989*8c35d5eeSXin Li """const int foo[] = 1990*8c35d5eeSXin Li {1, 2, 3 };""", 1991*8c35d5eeSXin Li '') 1992*8c35d5eeSXin Li # For single line, unmatched '}' with a ';' is ignored (not enough context) 1993*8c35d5eeSXin Li self.TestMultiLineLint( 1994*8c35d5eeSXin Li """int a[3] = { 1, 1995*8c35d5eeSXin Li 2, 1996*8c35d5eeSXin Li 3 };""", 1997*8c35d5eeSXin Li '') 1998*8c35d5eeSXin Li self.TestMultiLineLint( 1999*8c35d5eeSXin Li """int a[2][3] = { { 1, 2 }, 2000*8c35d5eeSXin Li { 3, 4 } };""", 2001*8c35d5eeSXin Li '') 2002*8c35d5eeSXin Li self.TestMultiLineLint( 2003*8c35d5eeSXin Li """int a[2][3] = 2004*8c35d5eeSXin Li { { 1, 2 }, 2005*8c35d5eeSXin Li { 3, 4 } };""", 2006*8c35d5eeSXin Li '') 2007*8c35d5eeSXin Li 2008*8c35d5eeSXin Li # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements 2009*8c35d5eeSXin Li def testCheckCheck(self): 2010*8c35d5eeSXin Li self.TestLint('CHECK(x == 42);', 2011*8c35d5eeSXin Li 'Consider using CHECK_EQ instead of CHECK(a == b)' 2012*8c35d5eeSXin Li ' [readability/check] [2]') 2013*8c35d5eeSXin Li self.TestLint('CHECK(x != 42);', 2014*8c35d5eeSXin Li 'Consider using CHECK_NE instead of CHECK(a != b)' 2015*8c35d5eeSXin Li ' [readability/check] [2]') 2016*8c35d5eeSXin Li self.TestLint('CHECK(x >= 42);', 2017*8c35d5eeSXin Li 'Consider using CHECK_GE instead of CHECK(a >= b)' 2018*8c35d5eeSXin Li ' [readability/check] [2]') 2019*8c35d5eeSXin Li self.TestLint('CHECK(x > 42);', 2020*8c35d5eeSXin Li 'Consider using CHECK_GT instead of CHECK(a > b)' 2021*8c35d5eeSXin Li ' [readability/check] [2]') 2022*8c35d5eeSXin Li self.TestLint('CHECK(x <= 42);', 2023*8c35d5eeSXin Li 'Consider using CHECK_LE instead of CHECK(a <= b)' 2024*8c35d5eeSXin Li ' [readability/check] [2]') 2025*8c35d5eeSXin Li self.TestLint('CHECK(x < 42);', 2026*8c35d5eeSXin Li 'Consider using CHECK_LT instead of CHECK(a < b)' 2027*8c35d5eeSXin Li ' [readability/check] [2]') 2028*8c35d5eeSXin Li 2029*8c35d5eeSXin Li self.TestLint('DCHECK(x == 42);', 2030*8c35d5eeSXin Li 'Consider using DCHECK_EQ instead of DCHECK(a == b)' 2031*8c35d5eeSXin Li ' [readability/check] [2]') 2032*8c35d5eeSXin Li self.TestLint('DCHECK(x != 42);', 2033*8c35d5eeSXin Li 'Consider using DCHECK_NE instead of DCHECK(a != b)' 2034*8c35d5eeSXin Li ' [readability/check] [2]') 2035*8c35d5eeSXin Li self.TestLint('DCHECK(x >= 42);', 2036*8c35d5eeSXin Li 'Consider using DCHECK_GE instead of DCHECK(a >= b)' 2037*8c35d5eeSXin Li ' [readability/check] [2]') 2038*8c35d5eeSXin Li self.TestLint('DCHECK(x > 42);', 2039*8c35d5eeSXin Li 'Consider using DCHECK_GT instead of DCHECK(a > b)' 2040*8c35d5eeSXin Li ' [readability/check] [2]') 2041*8c35d5eeSXin Li self.TestLint('DCHECK(x <= 42);', 2042*8c35d5eeSXin Li 'Consider using DCHECK_LE instead of DCHECK(a <= b)' 2043*8c35d5eeSXin Li ' [readability/check] [2]') 2044*8c35d5eeSXin Li self.TestLint('DCHECK(x < 42);', 2045*8c35d5eeSXin Li 'Consider using DCHECK_LT instead of DCHECK(a < b)' 2046*8c35d5eeSXin Li ' [readability/check] [2]') 2047*8c35d5eeSXin Li 2048*8c35d5eeSXin Li self.TestLint( 2049*8c35d5eeSXin Li 'EXPECT_TRUE("42" == x);', 2050*8c35d5eeSXin Li 'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)' 2051*8c35d5eeSXin Li ' [readability/check] [2]') 2052*8c35d5eeSXin Li self.TestLint( 2053*8c35d5eeSXin Li 'EXPECT_TRUE("42" != x);', 2054*8c35d5eeSXin Li 'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)' 2055*8c35d5eeSXin Li ' [readability/check] [2]') 2056*8c35d5eeSXin Li self.TestLint( 2057*8c35d5eeSXin Li 'EXPECT_TRUE(+42 >= x);', 2058*8c35d5eeSXin Li 'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)' 2059*8c35d5eeSXin Li ' [readability/check] [2]') 2060*8c35d5eeSXin Li 2061*8c35d5eeSXin Li self.TestLint( 2062*8c35d5eeSXin Li 'EXPECT_FALSE(x == 42);', 2063*8c35d5eeSXin Li 'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)' 2064*8c35d5eeSXin Li ' [readability/check] [2]') 2065*8c35d5eeSXin Li self.TestLint( 2066*8c35d5eeSXin Li 'EXPECT_FALSE(x != 42);', 2067*8c35d5eeSXin Li 'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)' 2068*8c35d5eeSXin Li ' [readability/check] [2]') 2069*8c35d5eeSXin Li self.TestLint( 2070*8c35d5eeSXin Li 'EXPECT_FALSE(x >= 42);', 2071*8c35d5eeSXin Li 'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)' 2072*8c35d5eeSXin Li ' [readability/check] [2]') 2073*8c35d5eeSXin Li self.TestLint( 2074*8c35d5eeSXin Li 'ASSERT_FALSE(x > 42);', 2075*8c35d5eeSXin Li 'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)' 2076*8c35d5eeSXin Li ' [readability/check] [2]') 2077*8c35d5eeSXin Li self.TestLint( 2078*8c35d5eeSXin Li 'ASSERT_FALSE(x <= 42);', 2079*8c35d5eeSXin Li 'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)' 2080*8c35d5eeSXin Li ' [readability/check] [2]') 2081*8c35d5eeSXin Li 2082*8c35d5eeSXin Li self.TestLint('CHECK(x<42);', 2083*8c35d5eeSXin Li ['Missing spaces around <' 2084*8c35d5eeSXin Li ' [whitespace/operators] [3]', 2085*8c35d5eeSXin Li 'Consider using CHECK_LT instead of CHECK(a < b)' 2086*8c35d5eeSXin Li ' [readability/check] [2]']) 2087*8c35d5eeSXin Li self.TestLint('CHECK(x>42);', 2088*8c35d5eeSXin Li ['Missing spaces around >' 2089*8c35d5eeSXin Li ' [whitespace/operators] [3]', 2090*8c35d5eeSXin Li 'Consider using CHECK_GT instead of CHECK(a > b)' 2091*8c35d5eeSXin Li ' [readability/check] [2]']) 2092*8c35d5eeSXin Li 2093*8c35d5eeSXin Li self.TestLint('using some::namespace::operator<<;', '') 2094*8c35d5eeSXin Li self.TestLint('using some::namespace::operator>>;', '') 2095*8c35d5eeSXin Li 2096*8c35d5eeSXin Li self.TestLint('CHECK(x->y == 42);', 2097*8c35d5eeSXin Li 'Consider using CHECK_EQ instead of CHECK(a == b)' 2098*8c35d5eeSXin Li ' [readability/check] [2]') 2099*8c35d5eeSXin Li 2100*8c35d5eeSXin Li self.TestLint( 2101*8c35d5eeSXin Li ' EXPECT_TRUE(42 < x); // Random comment.', 2102*8c35d5eeSXin Li 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)' 2103*8c35d5eeSXin Li ' [readability/check] [2]') 2104*8c35d5eeSXin Li self.TestLint( 2105*8c35d5eeSXin Li 'EXPECT_TRUE( 42 < x );', 2106*8c35d5eeSXin Li ['Extra space after ( in function call' 2107*8c35d5eeSXin Li ' [whitespace/parens] [4]', 2108*8c35d5eeSXin Li 'Extra space before ) [whitespace/parens] [2]', 2109*8c35d5eeSXin Li 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)' 2110*8c35d5eeSXin Li ' [readability/check] [2]']) 2111*8c35d5eeSXin Li 2112*8c35d5eeSXin Li self.TestLint('CHECK(4\'2 == x);', 2113*8c35d5eeSXin Li 'Consider using CHECK_EQ instead of CHECK(a == b)' 2114*8c35d5eeSXin Li ' [readability/check] [2]') 2115*8c35d5eeSXin Li 2116*8c35d5eeSXin Li def testCheckCheckFalsePositives(self): 2117*8c35d5eeSXin Li self.TestLint('CHECK(some_iterator == obj.end());', '') 2118*8c35d5eeSXin Li self.TestLint('EXPECT_TRUE(some_iterator == obj.end());', '') 2119*8c35d5eeSXin Li self.TestLint('EXPECT_FALSE(some_iterator == obj.end());', '') 2120*8c35d5eeSXin Li self.TestLint('CHECK(some_pointer != NULL);', '') 2121*8c35d5eeSXin Li self.TestLint('EXPECT_TRUE(some_pointer != NULL);', '') 2122*8c35d5eeSXin Li self.TestLint('EXPECT_FALSE(some_pointer != NULL);', '') 2123*8c35d5eeSXin Li 2124*8c35d5eeSXin Li self.TestLint('CHECK(CreateTestFile(dir, (1 << 20)));', '') 2125*8c35d5eeSXin Li self.TestLint('CHECK(CreateTestFile(dir, (1 >> 20)));', '') 2126*8c35d5eeSXin Li 2127*8c35d5eeSXin Li self.TestLint('CHECK(x ^ (y < 42));', '') 2128*8c35d5eeSXin Li self.TestLint('CHECK((x > 42) ^ (x < 54));', '') 2129*8c35d5eeSXin Li self.TestLint('CHECK(a && b < 42);', '') 2130*8c35d5eeSXin Li self.TestLint('CHECK(42 < a && a < b);', '') 2131*8c35d5eeSXin Li self.TestLint('SOFT_CHECK(x > 42);', '') 2132*8c35d5eeSXin Li 2133*8c35d5eeSXin Li self.TestMultiLineLint( 2134*8c35d5eeSXin Li """_STLP_DEFINE_BINARY_OP_CHECK(==, _OP_EQUAL); 2135*8c35d5eeSXin Li _STLP_DEFINE_BINARY_OP_CHECK(!=, _OP_NOT_EQUAL); 2136*8c35d5eeSXin Li _STLP_DEFINE_BINARY_OP_CHECK(<, _OP_LESS_THAN); 2137*8c35d5eeSXin Li _STLP_DEFINE_BINARY_OP_CHECK(<=, _OP_LESS_EQUAL); 2138*8c35d5eeSXin Li _STLP_DEFINE_BINARY_OP_CHECK(>, _OP_GREATER_THAN); 2139*8c35d5eeSXin Li _STLP_DEFINE_BINARY_OP_CHECK(>=, _OP_GREATER_EQUAL); 2140*8c35d5eeSXin Li _STLP_DEFINE_BINARY_OP_CHECK(+, _OP_PLUS); 2141*8c35d5eeSXin Li _STLP_DEFINE_BINARY_OP_CHECK(*, _OP_TIMES); 2142*8c35d5eeSXin Li _STLP_DEFINE_BINARY_OP_CHECK(/, _OP_DIVIDE); 2143*8c35d5eeSXin Li _STLP_DEFINE_BINARY_OP_CHECK(-, _OP_SUBTRACT); 2144*8c35d5eeSXin Li _STLP_DEFINE_BINARY_OP_CHECK(%, _OP_MOD);""", 2145*8c35d5eeSXin Li '') 2146*8c35d5eeSXin Li 2147*8c35d5eeSXin Li self.TestLint('CHECK(x < 42) << "Custom error message";', '') 2148*8c35d5eeSXin Li 2149*8c35d5eeSXin Li # Alternative token to punctuation operator replacements 2150*8c35d5eeSXin Li def testCheckAltTokens(self): 2151*8c35d5eeSXin Li self.TestLint('true or true', 2152*8c35d5eeSXin Li 'Use operator || instead of or' 2153*8c35d5eeSXin Li ' [readability/alt_tokens] [2]') 2154*8c35d5eeSXin Li self.TestLint('true and true', 2155*8c35d5eeSXin Li 'Use operator && instead of and' 2156*8c35d5eeSXin Li ' [readability/alt_tokens] [2]') 2157*8c35d5eeSXin Li self.TestLint('if (not true)', 2158*8c35d5eeSXin Li 'Use operator ! instead of not' 2159*8c35d5eeSXin Li ' [readability/alt_tokens] [2]') 2160*8c35d5eeSXin Li self.TestLint('1 bitor 1', 2161*8c35d5eeSXin Li 'Use operator | instead of bitor' 2162*8c35d5eeSXin Li ' [readability/alt_tokens] [2]') 2163*8c35d5eeSXin Li self.TestLint('1 xor 1', 2164*8c35d5eeSXin Li 'Use operator ^ instead of xor' 2165*8c35d5eeSXin Li ' [readability/alt_tokens] [2]') 2166*8c35d5eeSXin Li self.TestLint('1 bitand 1', 2167*8c35d5eeSXin Li 'Use operator & instead of bitand' 2168*8c35d5eeSXin Li ' [readability/alt_tokens] [2]') 2169*8c35d5eeSXin Li self.TestLint('x = compl 1', 2170*8c35d5eeSXin Li 'Use operator ~ instead of compl' 2171*8c35d5eeSXin Li ' [readability/alt_tokens] [2]') 2172*8c35d5eeSXin Li self.TestLint('x and_eq y', 2173*8c35d5eeSXin Li 'Use operator &= instead of and_eq' 2174*8c35d5eeSXin Li ' [readability/alt_tokens] [2]') 2175*8c35d5eeSXin Li self.TestLint('x or_eq y', 2176*8c35d5eeSXin Li 'Use operator |= instead of or_eq' 2177*8c35d5eeSXin Li ' [readability/alt_tokens] [2]') 2178*8c35d5eeSXin Li self.TestLint('x xor_eq y', 2179*8c35d5eeSXin Li 'Use operator ^= instead of xor_eq' 2180*8c35d5eeSXin Li ' [readability/alt_tokens] [2]') 2181*8c35d5eeSXin Li self.TestLint('x not_eq y', 2182*8c35d5eeSXin Li 'Use operator != instead of not_eq' 2183*8c35d5eeSXin Li ' [readability/alt_tokens] [2]') 2184*8c35d5eeSXin Li self.TestLint('line_continuation or', 2185*8c35d5eeSXin Li 'Use operator || instead of or' 2186*8c35d5eeSXin Li ' [readability/alt_tokens] [2]') 2187*8c35d5eeSXin Li self.TestLint('if(true and(parentheses', 2188*8c35d5eeSXin Li 'Use operator && instead of and' 2189*8c35d5eeSXin Li ' [readability/alt_tokens] [2]') 2190*8c35d5eeSXin Li 2191*8c35d5eeSXin Li self.TestLint('#include "base/false-and-false.h"', '') 2192*8c35d5eeSXin Li self.TestLint('#error false or false', '') 2193*8c35d5eeSXin Li self.TestLint('false nor false', '') 2194*8c35d5eeSXin Li self.TestLint('false nand false', '') 2195*8c35d5eeSXin Li 2196*8c35d5eeSXin Li # Passing and returning non-const references 2197*8c35d5eeSXin Li def testNonConstReference(self): 2198*8c35d5eeSXin Li # Passing a non-const reference as function parameter is forbidden. 2199*8c35d5eeSXin Li operand_error_message = ('Is this a non-const reference? ' 2200*8c35d5eeSXin Li 'If so, make const or use a pointer: %s' 2201*8c35d5eeSXin Li ' [runtime/references] [2]') 2202*8c35d5eeSXin Li # Warn of use of a non-const reference in operators and functions 2203*8c35d5eeSXin Li self.TestLint('bool operator>(Foo& s, Foo& f);', 2204*8c35d5eeSXin Li [operand_error_message % 'Foo& s', 2205*8c35d5eeSXin Li operand_error_message % 'Foo& f']) 2206*8c35d5eeSXin Li self.TestLint('bool operator+(Foo& s, Foo& f);', 2207*8c35d5eeSXin Li [operand_error_message % 'Foo& s', 2208*8c35d5eeSXin Li operand_error_message % 'Foo& f']) 2209*8c35d5eeSXin Li self.TestLint('int len(Foo& s);', operand_error_message % 'Foo& s') 2210*8c35d5eeSXin Li # Allow use of non-const references in a few specific cases 2211*8c35d5eeSXin Li self.TestLint('stream& operator>>(stream& s, Foo& f);', '') 2212*8c35d5eeSXin Li self.TestLint('stream& operator<<(stream& s, Foo& f);', '') 2213*8c35d5eeSXin Li self.TestLint('void swap(Bar& a, Bar& b);', '') 2214*8c35d5eeSXin Li self.TestLint('ostream& LogFunc(ostream& s);', '') 2215*8c35d5eeSXin Li self.TestLint('ostringstream& LogFunc(ostringstream& s);', '') 2216*8c35d5eeSXin Li self.TestLint('istream& LogFunc(istream& s);', '') 2217*8c35d5eeSXin Li self.TestLint('istringstream& LogFunc(istringstream& s);', '') 2218*8c35d5eeSXin Li # Returning a non-const reference from a function is OK. 2219*8c35d5eeSXin Li self.TestLint('int& g();', '') 2220*8c35d5eeSXin Li # Passing a const reference to a struct (using the struct keyword) is OK. 2221*8c35d5eeSXin Li self.TestLint('void foo(const struct tm& tm);', '') 2222*8c35d5eeSXin Li # Passing a const reference to a typename is OK. 2223*8c35d5eeSXin Li self.TestLint('void foo(const typename tm& tm);', '') 2224*8c35d5eeSXin Li # Const reference to a pointer type is OK. 2225*8c35d5eeSXin Li self.TestLint('void foo(const Bar* const& p) {', '') 2226*8c35d5eeSXin Li self.TestLint('void foo(Bar const* const& p) {', '') 2227*8c35d5eeSXin Li self.TestLint('void foo(Bar* const& p) {', '') 2228*8c35d5eeSXin Li # Const reference to a templated type is OK. 2229*8c35d5eeSXin Li self.TestLint('void foo(const std::vector<std::string>& v);', '') 2230*8c35d5eeSXin Li # Non-const reference to a pointer type is not OK. 2231*8c35d5eeSXin Li self.TestLint('void foo(Bar*& p);', 2232*8c35d5eeSXin Li operand_error_message % 'Bar*& p') 2233*8c35d5eeSXin Li self.TestLint('void foo(const Bar*& p);', 2234*8c35d5eeSXin Li operand_error_message % 'const Bar*& p') 2235*8c35d5eeSXin Li self.TestLint('void foo(Bar const*& p);', 2236*8c35d5eeSXin Li operand_error_message % 'Bar const*& p') 2237*8c35d5eeSXin Li self.TestLint('void foo(struct Bar*& p);', 2238*8c35d5eeSXin Li operand_error_message % 'struct Bar*& p') 2239*8c35d5eeSXin Li self.TestLint('void foo(const struct Bar*& p);', 2240*8c35d5eeSXin Li operand_error_message % 'const struct Bar*& p') 2241*8c35d5eeSXin Li self.TestLint('void foo(struct Bar const*& p);', 2242*8c35d5eeSXin Li operand_error_message % 'struct Bar const*& p') 2243*8c35d5eeSXin Li # Non-const reference to a templated type is not OK. 2244*8c35d5eeSXin Li self.TestLint('void foo(std::vector<int>& p);', 2245*8c35d5eeSXin Li operand_error_message % 'std::vector<int>& p') 2246*8c35d5eeSXin Li # Returning an address of something is not prohibited. 2247*8c35d5eeSXin Li self.TestLint('return &something;', '') 2248*8c35d5eeSXin Li self.TestLint('if (condition) {return &something; }', '') 2249*8c35d5eeSXin Li self.TestLint('if (condition) return &something;', '') 2250*8c35d5eeSXin Li self.TestLint('if (condition) address = &something;', '') 2251*8c35d5eeSXin Li self.TestLint('if (condition) result = lhs&rhs;', '') 2252*8c35d5eeSXin Li self.TestLint('if (condition) result = lhs & rhs;', '') 2253*8c35d5eeSXin Li self.TestLint('a = (b+c) * sizeof &f;', '') 2254*8c35d5eeSXin Li self.TestLint('a = MySize(b) * sizeof &f;', '') 2255*8c35d5eeSXin Li # We don't get confused by C++11 range-based for loops. 2256*8c35d5eeSXin Li self.TestLint('for (const string& s : c)', '') 2257*8c35d5eeSXin Li self.TestLint('for (auto& r : c)', '') 2258*8c35d5eeSXin Li self.TestLint('for (typename Type& a : b)', '') 2259*8c35d5eeSXin Li # We don't get confused by some other uses of '&'. 2260*8c35d5eeSXin Li self.TestLint('T& operator=(const T& t);', '') 2261*8c35d5eeSXin Li self.TestLint('int g() { return (a & b); }', '') 2262*8c35d5eeSXin Li self.TestLint('T& r = (T&)*(vp());', '') 2263*8c35d5eeSXin Li self.TestLint('T& r = v', '') 2264*8c35d5eeSXin Li self.TestLint('static_assert((kBits & kMask) == 0, "text");', '') 2265*8c35d5eeSXin Li self.TestLint('COMPILE_ASSERT((kBits & kMask) == 0, text);', '') 2266*8c35d5eeSXin Li # Spaces before template arguments. This is poor style, but 2267*8c35d5eeSXin Li # happens 0.15% of the time. 2268*8c35d5eeSXin Li self.TestLint('void Func(const vector <int> &const_x, ' 2269*8c35d5eeSXin Li 'vector <int> &nonconst_x) {', 2270*8c35d5eeSXin Li operand_error_message % 'vector<int> &nonconst_x') 2271*8c35d5eeSXin Li 2272*8c35d5eeSXin Li # Derived member functions are spared from override check 2273*8c35d5eeSXin Li self.TestLint('void Func(X& x);', operand_error_message % 'X& x') 2274*8c35d5eeSXin Li self.TestLint('void Func(X& x) {}', operand_error_message % 'X& x') 2275*8c35d5eeSXin Li self.TestLint('void Func(X& x) override;', '') 2276*8c35d5eeSXin Li self.TestLint('void Func(X& x) override {', '') 2277*8c35d5eeSXin Li self.TestLint('void Func(X& x) const override;', '') 2278*8c35d5eeSXin Li self.TestLint('void Func(X& x) const override {', '') 2279*8c35d5eeSXin Li 2280*8c35d5eeSXin Li # Don't warn on out-of-line method definitions. 2281*8c35d5eeSXin Li self.TestLint('void NS::Func(X& x) {', '') 2282*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 2283*8c35d5eeSXin Li cpplint.ProcessFileData( 2284*8c35d5eeSXin Li 'foo.cc', 'cc', 2285*8c35d5eeSXin Li ['// Copyright 2014 Your Company. All Rights Reserved.', 2286*8c35d5eeSXin Li 'void a::b() {}', 2287*8c35d5eeSXin Li 'void f(int& q) {}', 2288*8c35d5eeSXin Li ''], 2289*8c35d5eeSXin Li error_collector) 2290*8c35d5eeSXin Li self.assertEquals( 2291*8c35d5eeSXin Li operand_error_message % 'int& q', 2292*8c35d5eeSXin Li error_collector.Results()) 2293*8c35d5eeSXin Li 2294*8c35d5eeSXin Li # Other potential false positives. These need full parser 2295*8c35d5eeSXin Li # state to reproduce as opposed to just TestLint. 2296*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 2297*8c35d5eeSXin Li cpplint.ProcessFileData( 2298*8c35d5eeSXin Li 'foo.cc', 'cc', 2299*8c35d5eeSXin Li ['// Copyright 2014 Your Company. All Rights Reserved.', 2300*8c35d5eeSXin Li 'void swap(int &x,', 2301*8c35d5eeSXin Li ' int &y) {', 2302*8c35d5eeSXin Li '}', 2303*8c35d5eeSXin Li 'void swap(', 2304*8c35d5eeSXin Li ' sparsegroup<T, GROUP_SIZE, Alloc> &x,', 2305*8c35d5eeSXin Li ' sparsegroup<T, GROUP_SIZE, Alloc> &y) {', 2306*8c35d5eeSXin Li '}', 2307*8c35d5eeSXin Li 'ostream& operator<<(', 2308*8c35d5eeSXin Li ' ostream& out', 2309*8c35d5eeSXin Li ' const dense_hash_set<Value, Hash, Equals, Alloc>& seq) {', 2310*8c35d5eeSXin Li '}', 2311*8c35d5eeSXin Li 'class A {', 2312*8c35d5eeSXin Li ' void Function(', 2313*8c35d5eeSXin Li ' string &x) override {', 2314*8c35d5eeSXin Li ' }', 2315*8c35d5eeSXin Li '};', 2316*8c35d5eeSXin Li 'void Derived::Function(', 2317*8c35d5eeSXin Li ' string &x) {', 2318*8c35d5eeSXin Li '}', 2319*8c35d5eeSXin Li '#define UNSUPPORTED_MASK(_mask) \\', 2320*8c35d5eeSXin Li ' if (flags & _mask) { \\', 2321*8c35d5eeSXin Li ' LOG(FATAL) << "Unsupported flag: " << #_mask; \\', 2322*8c35d5eeSXin Li ' }', 2323*8c35d5eeSXin Li 'Constructor::Constructor()', 2324*8c35d5eeSXin Li ' : initializer1_(a1 & b1),', 2325*8c35d5eeSXin Li ' initializer2_(a2 & b2) {', 2326*8c35d5eeSXin Li '}', 2327*8c35d5eeSXin Li 'Constructor::Constructor()', 2328*8c35d5eeSXin Li ' : initializer1_{a3 & b3},', 2329*8c35d5eeSXin Li ' initializer2_(a4 & b4) {', 2330*8c35d5eeSXin Li '}', 2331*8c35d5eeSXin Li 'Constructor::Constructor()', 2332*8c35d5eeSXin Li ' : initializer1_{a5 & b5},', 2333*8c35d5eeSXin Li ' initializer2_(a6 & b6) {}', 2334*8c35d5eeSXin Li ''], 2335*8c35d5eeSXin Li error_collector) 2336*8c35d5eeSXin Li self.assertEquals('', error_collector.Results()) 2337*8c35d5eeSXin Li 2338*8c35d5eeSXin Li # Multi-line references 2339*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 2340*8c35d5eeSXin Li cpplint.ProcessFileData( 2341*8c35d5eeSXin Li 'foo.cc', 'cc', 2342*8c35d5eeSXin Li ['// Copyright 2014 Your Company. All Rights Reserved.', 2343*8c35d5eeSXin Li 'void Func(const Outer::', 2344*8c35d5eeSXin Li ' Inner& const_x,', 2345*8c35d5eeSXin Li ' const Outer', 2346*8c35d5eeSXin Li ' ::Inner& const_y,', 2347*8c35d5eeSXin Li ' const Outer<', 2348*8c35d5eeSXin Li ' int>::Inner& const_z,', 2349*8c35d5eeSXin Li ' Outer::', 2350*8c35d5eeSXin Li ' Inner& nonconst_x,', 2351*8c35d5eeSXin Li ' Outer', 2352*8c35d5eeSXin Li ' ::Inner& nonconst_y,', 2353*8c35d5eeSXin Li ' Outer<', 2354*8c35d5eeSXin Li ' int>::Inner& nonconst_z) {', 2355*8c35d5eeSXin Li '}', 2356*8c35d5eeSXin Li ''], 2357*8c35d5eeSXin Li error_collector) 2358*8c35d5eeSXin Li self.assertEquals( 2359*8c35d5eeSXin Li [operand_error_message % 'Outer::Inner& nonconst_x', 2360*8c35d5eeSXin Li operand_error_message % 'Outer::Inner& nonconst_y', 2361*8c35d5eeSXin Li operand_error_message % 'Outer<int>::Inner& nonconst_z'], 2362*8c35d5eeSXin Li error_collector.Results()) 2363*8c35d5eeSXin Li 2364*8c35d5eeSXin Li # A peculiar false positive due to bad template argument parsing 2365*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 2366*8c35d5eeSXin Li cpplint.ProcessFileData( 2367*8c35d5eeSXin Li 'foo.cc', 'cc', 2368*8c35d5eeSXin Li ['// Copyright 2014 Your Company. All Rights Reserved.', 2369*8c35d5eeSXin Li 'inline RCULocked<X>::ReadPtr::ReadPtr(const RCULocked* rcu) {', 2370*8c35d5eeSXin Li ' DCHECK(!(data & kFlagMask)) << "Error";', 2371*8c35d5eeSXin Li '}', 2372*8c35d5eeSXin Li '', 2373*8c35d5eeSXin Li 'RCULocked<X>::WritePtr::WritePtr(RCULocked* rcu)', 2374*8c35d5eeSXin Li ' : lock_(&rcu_->mutex_) {', 2375*8c35d5eeSXin Li '}', 2376*8c35d5eeSXin Li ''], 2377*8c35d5eeSXin Li error_collector.Results()) 2378*8c35d5eeSXin Li self.assertEquals('', error_collector.Results()) 2379*8c35d5eeSXin Li 2380*8c35d5eeSXin Li def testBraceAtBeginOfLine(self): 2381*8c35d5eeSXin Li self.TestLint('{', 2382*8c35d5eeSXin Li '{ should almost always be at the end of the previous line' 2383*8c35d5eeSXin Li ' [whitespace/braces] [4]') 2384*8c35d5eeSXin Li 2385*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 2386*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', 2387*8c35d5eeSXin Li ['int function()', 2388*8c35d5eeSXin Li '{', # warning here 2389*8c35d5eeSXin Li ' MutexLock l(&mu);', 2390*8c35d5eeSXin Li '}', 2391*8c35d5eeSXin Li 'int variable;' 2392*8c35d5eeSXin Li '{', # no warning 2393*8c35d5eeSXin Li ' MutexLock l(&mu);', 2394*8c35d5eeSXin Li '}', 2395*8c35d5eeSXin Li 'MyType m = {', 2396*8c35d5eeSXin Li ' {value1, value2},', 2397*8c35d5eeSXin Li ' {', # no warning 2398*8c35d5eeSXin Li ' loooong_value1, looooong_value2', 2399*8c35d5eeSXin Li ' }', 2400*8c35d5eeSXin Li '};', 2401*8c35d5eeSXin Li '#if PREPROCESSOR', 2402*8c35d5eeSXin Li '{', # no warning 2403*8c35d5eeSXin Li ' MutexLock l(&mu);', 2404*8c35d5eeSXin Li '}', 2405*8c35d5eeSXin Li '#endif'], 2406*8c35d5eeSXin Li error_collector) 2407*8c35d5eeSXin Li self.assertEquals(1, error_collector.Results().count( 2408*8c35d5eeSXin Li '{ should almost always be at the end of the previous line' 2409*8c35d5eeSXin Li ' [whitespace/braces] [4]')) 2410*8c35d5eeSXin Li 2411*8c35d5eeSXin Li self.TestMultiLineLint( 2412*8c35d5eeSXin Li """ 2413*8c35d5eeSXin Li foo( 2414*8c35d5eeSXin Li { 2415*8c35d5eeSXin Li loooooooooooooooong_value, 2416*8c35d5eeSXin Li });""", 2417*8c35d5eeSXin Li '') 2418*8c35d5eeSXin Li 2419*8c35d5eeSXin Li def testMismatchingSpacesInParens(self): 2420*8c35d5eeSXin Li self.TestLint('if (foo ) {', 'Mismatching spaces inside () in if' 2421*8c35d5eeSXin Li ' [whitespace/parens] [5]') 2422*8c35d5eeSXin Li self.TestLint('switch ( foo) {', 'Mismatching spaces inside () in switch' 2423*8c35d5eeSXin Li ' [whitespace/parens] [5]') 2424*8c35d5eeSXin Li self.TestLint('for (foo; ba; bar ) {', 'Mismatching spaces inside () in for' 2425*8c35d5eeSXin Li ' [whitespace/parens] [5]') 2426*8c35d5eeSXin Li self.TestLint('for (; foo; bar) {', '') 2427*8c35d5eeSXin Li self.TestLint('for ( ; foo; bar) {', '') 2428*8c35d5eeSXin Li self.TestLint('for ( ; foo; bar ) {', '') 2429*8c35d5eeSXin Li self.TestLint('for (foo; bar; ) {', '') 2430*8c35d5eeSXin Li self.TestLint('while ( foo ) {', 'Should have zero or one spaces inside' 2431*8c35d5eeSXin Li ' ( and ) in while [whitespace/parens] [5]') 2432*8c35d5eeSXin Li 2433*8c35d5eeSXin Li def testSpacingForFncall(self): 2434*8c35d5eeSXin Li self.TestLint('if (foo) {', '') 2435*8c35d5eeSXin Li self.TestLint('for (foo; bar; baz) {', '') 2436*8c35d5eeSXin Li self.TestLint('for (;;) {', '') 2437*8c35d5eeSXin Li # Space should be allowed in placement new operators. 2438*8c35d5eeSXin Li self.TestLint('Something* p = new (place) Something();', '') 2439*8c35d5eeSXin Li # Test that there is no warning when increment statement is empty. 2440*8c35d5eeSXin Li self.TestLint('for (foo; baz;) {', '') 2441*8c35d5eeSXin Li self.TestLint('for (foo;bar;baz) {', 'Missing space after ;' 2442*8c35d5eeSXin Li ' [whitespace/semicolon] [3]') 2443*8c35d5eeSXin Li # we don't warn about this semicolon, at least for now 2444*8c35d5eeSXin Li self.TestLint('if (condition) {return &something; }', 2445*8c35d5eeSXin Li '') 2446*8c35d5eeSXin Li # seen in some macros 2447*8c35d5eeSXin Li self.TestLint('DoSth();\\', '') 2448*8c35d5eeSXin Li # Test that there is no warning about semicolon here. 2449*8c35d5eeSXin Li self.TestLint('abc;// this is abc', 2450*8c35d5eeSXin Li 'At least two spaces is best between code' 2451*8c35d5eeSXin Li ' and comments [whitespace/comments] [2]') 2452*8c35d5eeSXin Li self.TestLint('while (foo) {', '') 2453*8c35d5eeSXin Li self.TestLint('switch (foo) {', '') 2454*8c35d5eeSXin Li self.TestLint('foo( bar)', 'Extra space after ( in function call' 2455*8c35d5eeSXin Li ' [whitespace/parens] [4]') 2456*8c35d5eeSXin Li self.TestLint('foo( // comment', '') 2457*8c35d5eeSXin Li self.TestLint('foo( // comment', 2458*8c35d5eeSXin Li 'At least two spaces is best between code' 2459*8c35d5eeSXin Li ' and comments [whitespace/comments] [2]') 2460*8c35d5eeSXin Li self.TestLint('foobar( \\', '') 2461*8c35d5eeSXin Li self.TestLint('foobar( \\', '') 2462*8c35d5eeSXin Li self.TestLint('( a + b)', 'Extra space after (' 2463*8c35d5eeSXin Li ' [whitespace/parens] [2]') 2464*8c35d5eeSXin Li self.TestLint('((a+b))', '') 2465*8c35d5eeSXin Li self.TestLint('foo (foo)', 'Extra space before ( in function call' 2466*8c35d5eeSXin Li ' [whitespace/parens] [4]') 2467*8c35d5eeSXin Li # asm volatile () may have a space, as it isn't a function call. 2468*8c35d5eeSXin Li self.TestLint('asm volatile ("")', '') 2469*8c35d5eeSXin Li self.TestLint('__asm__ __volatile__ ("")', '') 2470*8c35d5eeSXin Li self.TestLint('} catch (const Foo& ex) {', '') 2471*8c35d5eeSXin Li self.TestLint('case (42):', '') 2472*8c35d5eeSXin Li self.TestLint('typedef foo (*foo)(foo)', '') 2473*8c35d5eeSXin Li self.TestLint('typedef foo (*foo12bar_)(foo)', '') 2474*8c35d5eeSXin Li self.TestLint('typedef foo (Foo::*bar)(foo)', '') 2475*8c35d5eeSXin Li self.TestLint('using foo = type (Foo::*bar)(foo)', '') 2476*8c35d5eeSXin Li self.TestLint('using foo = type (Foo::*bar)(', '') 2477*8c35d5eeSXin Li self.TestLint('using foo = type (Foo::*)(', '') 2478*8c35d5eeSXin Li self.TestLint('foo (Foo::*bar)(', '') 2479*8c35d5eeSXin Li self.TestLint('foo (x::y::*z)(', '') 2480*8c35d5eeSXin Li self.TestLint('foo (Foo::bar)(', 2481*8c35d5eeSXin Li 'Extra space before ( in function call' 2482*8c35d5eeSXin Li ' [whitespace/parens] [4]') 2483*8c35d5eeSXin Li self.TestLint('foo (*bar)(', '') 2484*8c35d5eeSXin Li self.TestLint('typedef foo (Foo::*bar)(', '') 2485*8c35d5eeSXin Li self.TestLint('(foo)(bar)', '') 2486*8c35d5eeSXin Li self.TestLint('Foo (*foo)(bar)', '') 2487*8c35d5eeSXin Li self.TestLint('Foo (*foo)(Bar bar,', '') 2488*8c35d5eeSXin Li self.TestLint('char (*p)[sizeof(foo)] = &foo', '') 2489*8c35d5eeSXin Li self.TestLint('char (&ref)[sizeof(foo)] = &foo', '') 2490*8c35d5eeSXin Li self.TestLint('const char32 (*table[])[6];', '') 2491*8c35d5eeSXin Li # The sizeof operator is often written as if it were a function call, with 2492*8c35d5eeSXin Li # an opening parenthesis directly following the operator name, but it can 2493*8c35d5eeSXin Li # also be written like any other operator, with a space following the 2494*8c35d5eeSXin Li # operator name, and the argument optionally in parentheses. 2495*8c35d5eeSXin Li self.TestLint('sizeof(foo)', '') 2496*8c35d5eeSXin Li self.TestLint('sizeof foo', '') 2497*8c35d5eeSXin Li self.TestLint('sizeof (foo)', '') 2498*8c35d5eeSXin Li 2499*8c35d5eeSXin Li def testSpacingBeforeBraces(self): 2500*8c35d5eeSXin Li self.TestLint('if (foo){', 'Missing space before {' 2501*8c35d5eeSXin Li ' [whitespace/braces] [5]') 2502*8c35d5eeSXin Li self.TestLint('for{', 'Missing space before {' 2503*8c35d5eeSXin Li ' [whitespace/braces] [5]') 2504*8c35d5eeSXin Li self.TestLint('for {', '') 2505*8c35d5eeSXin Li self.TestLint('EXPECT_DEBUG_DEATH({', '') 2506*8c35d5eeSXin Li self.TestLint('std::is_convertible<A, B>{}', '') 2507*8c35d5eeSXin Li self.TestLint('blah{32}', 'Missing space before {' 2508*8c35d5eeSXin Li ' [whitespace/braces] [5]') 2509*8c35d5eeSXin Li self.TestLint('int8_t{3}', '') 2510*8c35d5eeSXin Li self.TestLint('int16_t{3}', '') 2511*8c35d5eeSXin Li self.TestLint('int32_t{3}', '') 2512*8c35d5eeSXin Li self.TestLint('uint64_t{12345}', '') 2513*8c35d5eeSXin Li self.TestLint('constexpr int64_t kBatchGapMicros =' 2514*8c35d5eeSXin Li ' int64_t{7} * 24 * 3600 * 1000000; // 1 wk.', '') 2515*8c35d5eeSXin Li self.TestLint('MoveOnly(int i1, int i2) : ip1{new int{i1}}, ' 2516*8c35d5eeSXin Li 'ip2{new int{i2}} {}', 2517*8c35d5eeSXin Li '') 2518*8c35d5eeSXin Li 2519*8c35d5eeSXin Li def testSemiColonAfterBraces(self): 2520*8c35d5eeSXin Li self.TestLint('if (cond) { func(); };', 2521*8c35d5eeSXin Li 'You don\'t need a ; after a } [readability/braces] [4]') 2522*8c35d5eeSXin Li self.TestLint('void Func() {};', 2523*8c35d5eeSXin Li 'You don\'t need a ; after a } [readability/braces] [4]') 2524*8c35d5eeSXin Li self.TestLint('void Func() const {};', 2525*8c35d5eeSXin Li 'You don\'t need a ; after a } [readability/braces] [4]') 2526*8c35d5eeSXin Li self.TestLint('class X {};', '') 2527*8c35d5eeSXin Li for keyword in ['struct', 'union']: 2528*8c35d5eeSXin Li for align in ['', ' alignas(16)']: 2529*8c35d5eeSXin Li for typename in ['', ' X']: 2530*8c35d5eeSXin Li for identifier in ['', ' x']: 2531*8c35d5eeSXin Li self.TestLint(keyword + align + typename + ' {}' + identifier + ';', 2532*8c35d5eeSXin Li '') 2533*8c35d5eeSXin Li 2534*8c35d5eeSXin Li self.TestLint('class X : public Y {};', '') 2535*8c35d5eeSXin Li self.TestLint('class X : public MACRO() {};', '') 2536*8c35d5eeSXin Li self.TestLint('class X : public decltype(expr) {};', '') 2537*8c35d5eeSXin Li self.TestLint('DEFINE_FACADE(PCQueue::Watcher, PCQueue) {};', '') 2538*8c35d5eeSXin Li self.TestLint('VCLASS(XfaTest, XfaContextTest) {};', '') 2539*8c35d5eeSXin Li self.TestLint('class STUBBY_CLASS(H, E) {};', '') 2540*8c35d5eeSXin Li self.TestLint('class STUBBY2_CLASS(H, E) {};', '') 2541*8c35d5eeSXin Li self.TestLint('TEST(TestCase, TestName) {};', 2542*8c35d5eeSXin Li 'You don\'t need a ; after a } [readability/braces] [4]') 2543*8c35d5eeSXin Li self.TestLint('TEST_F(TestCase, TestName) {};', 2544*8c35d5eeSXin Li 'You don\'t need a ; after a } [readability/braces] [4]') 2545*8c35d5eeSXin Li 2546*8c35d5eeSXin Li self.TestLint('file_tocs_[i] = (FileToc) {a, b, c};', '') 2547*8c35d5eeSXin Li self.TestMultiLineLint('class X : public Y,\npublic Z {};', '') 2548*8c35d5eeSXin Li 2549*8c35d5eeSXin Li def testLambda(self): 2550*8c35d5eeSXin Li self.TestLint('auto x = []() {};', '') 2551*8c35d5eeSXin Li self.TestLint('return []() {};', '') 2552*8c35d5eeSXin Li self.TestMultiLineLint('auto x = []() {\n};\n', '') 2553*8c35d5eeSXin Li self.TestLint('int operator[](int x) {};', 2554*8c35d5eeSXin Li 'You don\'t need a ; after a } [readability/braces] [4]') 2555*8c35d5eeSXin Li 2556*8c35d5eeSXin Li self.TestMultiLineLint('auto x = [&a,\nb]() {};', '') 2557*8c35d5eeSXin Li self.TestMultiLineLint('auto x = [&a,\nb]\n() {};', '') 2558*8c35d5eeSXin Li self.TestMultiLineLint('auto x = [&a,\n' 2559*8c35d5eeSXin Li ' b](\n' 2560*8c35d5eeSXin Li ' int a,\n' 2561*8c35d5eeSXin Li ' int b) {\n' 2562*8c35d5eeSXin Li ' return a +\n' 2563*8c35d5eeSXin Li ' b;\n' 2564*8c35d5eeSXin Li '};\n', 2565*8c35d5eeSXin Li '') 2566*8c35d5eeSXin Li 2567*8c35d5eeSXin Li # Avoid false positives with operator[] 2568*8c35d5eeSXin Li self.TestLint('table_to_children[&*table].push_back(dependent);', '') 2569*8c35d5eeSXin Li 2570*8c35d5eeSXin Li def testBraceInitializerList(self): 2571*8c35d5eeSXin Li self.TestLint('MyStruct p = {1, 2};', '') 2572*8c35d5eeSXin Li self.TestLint('MyStruct p{1, 2};', '') 2573*8c35d5eeSXin Li self.TestLint('vector<int> p = {1, 2};', '') 2574*8c35d5eeSXin Li self.TestLint('vector<int> p{1, 2};', '') 2575*8c35d5eeSXin Li self.TestLint('x = vector<int>{1, 2};', '') 2576*8c35d5eeSXin Li self.TestLint('x = (struct in_addr){ 0 };', '') 2577*8c35d5eeSXin Li self.TestLint('Func(vector<int>{1, 2})', '') 2578*8c35d5eeSXin Li self.TestLint('Func((struct in_addr){ 0 })', '') 2579*8c35d5eeSXin Li self.TestLint('Func(vector<int>{1, 2}, 3)', '') 2580*8c35d5eeSXin Li self.TestLint('Func((struct in_addr){ 0 }, 3)', '') 2581*8c35d5eeSXin Li self.TestLint('LOG(INFO) << char{7};', '') 2582*8c35d5eeSXin Li self.TestLint('LOG(INFO) << char{7} << "!";', '') 2583*8c35d5eeSXin Li self.TestLint('int p[2] = {1, 2};', '') 2584*8c35d5eeSXin Li self.TestLint('return {1, 2};', '') 2585*8c35d5eeSXin Li self.TestLint('std::unique_ptr<Foo> foo{new Foo{}};', '') 2586*8c35d5eeSXin Li self.TestLint('auto foo = std::unique_ptr<Foo>{new Foo{}};', '') 2587*8c35d5eeSXin Li self.TestLint('static_assert(Max7String{}.IsValid(), "");', '') 2588*8c35d5eeSXin Li self.TestLint('map_of_pairs[{1, 2}] = 3;', '') 2589*8c35d5eeSXin Li self.TestLint('ItemView{has_offer() ? new Offer{offer()} : nullptr', '') 2590*8c35d5eeSXin Li self.TestLint('template <class T, EnableIf<::std::is_const<T>{}> = 0>', '') 2591*8c35d5eeSXin Li 2592*8c35d5eeSXin Li self.TestMultiLineLint('std::unique_ptr<Foo> foo{\n' 2593*8c35d5eeSXin Li ' new Foo{}\n' 2594*8c35d5eeSXin Li '};\n', '') 2595*8c35d5eeSXin Li self.TestMultiLineLint('std::unique_ptr<Foo> foo{\n' 2596*8c35d5eeSXin Li ' new Foo{\n' 2597*8c35d5eeSXin Li ' new Bar{}\n' 2598*8c35d5eeSXin Li ' }\n' 2599*8c35d5eeSXin Li '};\n', '') 2600*8c35d5eeSXin Li self.TestMultiLineLint('if (true) {\n' 2601*8c35d5eeSXin Li ' if (false){ func(); }\n' 2602*8c35d5eeSXin Li '}\n', 2603*8c35d5eeSXin Li 'Missing space before { [whitespace/braces] [5]') 2604*8c35d5eeSXin Li self.TestMultiLineLint('MyClass::MyClass()\n' 2605*8c35d5eeSXin Li ' : initializer_{\n' 2606*8c35d5eeSXin Li ' Func()} {\n' 2607*8c35d5eeSXin Li '}\n', '') 2608*8c35d5eeSXin Li self.TestLint('const pair<string, string> kCL' + 2609*8c35d5eeSXin Li ('o' * 41) + 'gStr[] = {\n', 2610*8c35d5eeSXin Li 'Lines should be <= 80 characters long' 2611*8c35d5eeSXin Li ' [whitespace/line_length] [2]') 2612*8c35d5eeSXin Li self.TestMultiLineLint('const pair<string, string> kCL' + 2613*8c35d5eeSXin Li ('o' * 40) + 'ngStr[] =\n' 2614*8c35d5eeSXin Li ' {\n' 2615*8c35d5eeSXin Li ' {"gooooo", "oooogle"},\n' 2616*8c35d5eeSXin Li '};\n', '') 2617*8c35d5eeSXin Li self.TestMultiLineLint('const pair<string, string> kCL' + 2618*8c35d5eeSXin Li ('o' * 39) + 'ngStr[] =\n' 2619*8c35d5eeSXin Li ' {\n' 2620*8c35d5eeSXin Li ' {"gooooo", "oooogle"},\n' 2621*8c35d5eeSXin Li '};\n', '{ should almost always be at the end of ' 2622*8c35d5eeSXin Li 'the previous line [whitespace/braces] [4]') 2623*8c35d5eeSXin Li 2624*8c35d5eeSXin Li def testSpacingAroundElse(self): 2625*8c35d5eeSXin Li self.TestLint('}else {', 'Missing space before else' 2626*8c35d5eeSXin Li ' [whitespace/braces] [5]') 2627*8c35d5eeSXin Li self.TestLint('} else{', 'Missing space before {' 2628*8c35d5eeSXin Li ' [whitespace/braces] [5]') 2629*8c35d5eeSXin Li self.TestLint('} else {', '') 2630*8c35d5eeSXin Li self.TestLint('} else if (foo) {', '') 2631*8c35d5eeSXin Li 2632*8c35d5eeSXin Li def testSpacingWithInitializerLists(self): 2633*8c35d5eeSXin Li self.TestLint('int v[1][3] = {{1, 2, 3}};', '') 2634*8c35d5eeSXin Li self.TestLint('int v[1][1] = {{0}};', '') 2635*8c35d5eeSXin Li 2636*8c35d5eeSXin Li def testSpacingForBinaryOps(self): 2637*8c35d5eeSXin Li self.TestLint('if (foo||bar) {', 'Missing spaces around ||' 2638*8c35d5eeSXin Li ' [whitespace/operators] [3]') 2639*8c35d5eeSXin Li self.TestLint('if (foo<=bar) {', 'Missing spaces around <=' 2640*8c35d5eeSXin Li ' [whitespace/operators] [3]') 2641*8c35d5eeSXin Li self.TestLint('if (foo<bar) {', 'Missing spaces around <' 2642*8c35d5eeSXin Li ' [whitespace/operators] [3]') 2643*8c35d5eeSXin Li self.TestLint('if (foo>bar) {', 'Missing spaces around >' 2644*8c35d5eeSXin Li ' [whitespace/operators] [3]') 2645*8c35d5eeSXin Li self.TestLint('if (foo<bar->baz) {', 'Missing spaces around <' 2646*8c35d5eeSXin Li ' [whitespace/operators] [3]') 2647*8c35d5eeSXin Li self.TestLint('if (foo<bar->bar) {', 'Missing spaces around <' 2648*8c35d5eeSXin Li ' [whitespace/operators] [3]') 2649*8c35d5eeSXin Li self.TestLint('template<typename T = double>', '') 2650*8c35d5eeSXin Li self.TestLint('std::unique_ptr<No<Spaces>>', '') 2651*8c35d5eeSXin Li self.TestLint('typedef hash_map<Foo, Bar>', '') 2652*8c35d5eeSXin Li self.TestLint('10<<20', '') 2653*8c35d5eeSXin Li self.TestLint('10<<a', 2654*8c35d5eeSXin Li 'Missing spaces around << [whitespace/operators] [3]') 2655*8c35d5eeSXin Li self.TestLint('a<<20', 2656*8c35d5eeSXin Li 'Missing spaces around << [whitespace/operators] [3]') 2657*8c35d5eeSXin Li self.TestLint('a<<b', 2658*8c35d5eeSXin Li 'Missing spaces around << [whitespace/operators] [3]') 2659*8c35d5eeSXin Li self.TestLint('10LL<<20', '') 2660*8c35d5eeSXin Li self.TestLint('10ULL<<20', '') 2661*8c35d5eeSXin Li self.TestLint('a>>b', 2662*8c35d5eeSXin Li 'Missing spaces around >> [whitespace/operators] [3]') 2663*8c35d5eeSXin Li self.TestLint('10>>b', 2664*8c35d5eeSXin Li 'Missing spaces around >> [whitespace/operators] [3]') 2665*8c35d5eeSXin Li self.TestLint('LOG(ERROR)<<*foo', 2666*8c35d5eeSXin Li 'Missing spaces around << [whitespace/operators] [3]') 2667*8c35d5eeSXin Li self.TestLint('LOG(ERROR)<<&foo', 2668*8c35d5eeSXin Li 'Missing spaces around << [whitespace/operators] [3]') 2669*8c35d5eeSXin Li self.TestLint('StringCoder<vector<string>>::ToString()', '') 2670*8c35d5eeSXin Li self.TestLint('map<pair<int, int>, map<int, int>>::iterator', '') 2671*8c35d5eeSXin Li self.TestLint('func<int, pair<int, pair<int, int>>>()', '') 2672*8c35d5eeSXin Li self.TestLint('MACRO1(list<list<int>>)', '') 2673*8c35d5eeSXin Li self.TestLint('MACRO2(list<list<int>>, 42)', '') 2674*8c35d5eeSXin Li self.TestLint('void DoFoo(const set<vector<string>>& arg1);', '') 2675*8c35d5eeSXin Li self.TestLint('void SetFoo(set<vector<string>>* arg1);', '') 2676*8c35d5eeSXin Li self.TestLint('foo = new set<vector<string>>;', '') 2677*8c35d5eeSXin Li self.TestLint('reinterpret_cast<set<vector<string>>*>(a);', '') 2678*8c35d5eeSXin Li self.TestLint('MACRO(<<)', '') 2679*8c35d5eeSXin Li self.TestLint('MACRO(<<, arg)', '') 2680*8c35d5eeSXin Li self.TestLint('MACRO(<<=)', '') 2681*8c35d5eeSXin Li self.TestLint('MACRO(<<=, arg)', '') 2682*8c35d5eeSXin Li 2683*8c35d5eeSXin Li self.TestLint('using Vector3<T>::operator==;', '') 2684*8c35d5eeSXin Li self.TestLint('using Vector3<T>::operator!=;', '') 2685*8c35d5eeSXin Li 2686*8c35d5eeSXin Li def testSpacingBeforeLastSemicolon(self): 2687*8c35d5eeSXin Li self.TestLint('call_function() ;', 2688*8c35d5eeSXin Li 'Extra space before last semicolon. If this should be an ' 2689*8c35d5eeSXin Li 'empty statement, use {} instead.' 2690*8c35d5eeSXin Li ' [whitespace/semicolon] [5]') 2691*8c35d5eeSXin Li self.TestLint('while (true) ;', 2692*8c35d5eeSXin Li 'Extra space before last semicolon. If this should be an ' 2693*8c35d5eeSXin Li 'empty statement, use {} instead.' 2694*8c35d5eeSXin Li ' [whitespace/semicolon] [5]') 2695*8c35d5eeSXin Li self.TestLint('default:;', 2696*8c35d5eeSXin Li 'Semicolon defining empty statement. Use {} instead.' 2697*8c35d5eeSXin Li ' [whitespace/semicolon] [5]') 2698*8c35d5eeSXin Li self.TestLint(' ;', 2699*8c35d5eeSXin Li 'Line contains only semicolon. If this should be an empty ' 2700*8c35d5eeSXin Li 'statement, use {} instead.' 2701*8c35d5eeSXin Li ' [whitespace/semicolon] [5]') 2702*8c35d5eeSXin Li self.TestLint('for (int i = 0; ;', '') 2703*8c35d5eeSXin Li 2704*8c35d5eeSXin Li def testEmptyBlockBody(self): 2705*8c35d5eeSXin Li self.TestLint('while (true);', 2706*8c35d5eeSXin Li 'Empty loop bodies should use {} or continue' 2707*8c35d5eeSXin Li ' [whitespace/empty_loop_body] [5]') 2708*8c35d5eeSXin Li self.TestLint('if (true);', 2709*8c35d5eeSXin Li 'Empty conditional bodies should use {}' 2710*8c35d5eeSXin Li ' [whitespace/empty_conditional_body] [5]') 2711*8c35d5eeSXin Li self.TestLint('while (true)', '') 2712*8c35d5eeSXin Li self.TestLint('while (true) continue;', '') 2713*8c35d5eeSXin Li self.TestLint('for (;;);', 2714*8c35d5eeSXin Li 'Empty loop bodies should use {} or continue' 2715*8c35d5eeSXin Li ' [whitespace/empty_loop_body] [5]') 2716*8c35d5eeSXin Li self.TestLint('for (;;)', '') 2717*8c35d5eeSXin Li self.TestLint('for (;;) continue;', '') 2718*8c35d5eeSXin Li self.TestLint('for (;;) func();', '') 2719*8c35d5eeSXin Li self.TestLint('if (test) {}', 2720*8c35d5eeSXin Li 'If statement had no body and no else clause' 2721*8c35d5eeSXin Li ' [whitespace/empty_if_body] [4]') 2722*8c35d5eeSXin Li self.TestLint('if (test) func();', '') 2723*8c35d5eeSXin Li self.TestLint('if (test) {} else {}', '') 2724*8c35d5eeSXin Li self.TestMultiLineLint("""while (true && 2725*8c35d5eeSXin Li false);""", 2726*8c35d5eeSXin Li 'Empty loop bodies should use {} or continue' 2727*8c35d5eeSXin Li ' [whitespace/empty_loop_body] [5]') 2728*8c35d5eeSXin Li self.TestMultiLineLint("""do { 2729*8c35d5eeSXin Li } while (false);""", 2730*8c35d5eeSXin Li '') 2731*8c35d5eeSXin Li self.TestMultiLineLint("""#define MACRO \\ 2732*8c35d5eeSXin Li do { \\ 2733*8c35d5eeSXin Li } while (false);""", 2734*8c35d5eeSXin Li '') 2735*8c35d5eeSXin Li self.TestMultiLineLint("""do { 2736*8c35d5eeSXin Li } while (false); // next line gets a warning 2737*8c35d5eeSXin Li while (false);""", 2738*8c35d5eeSXin Li 'Empty loop bodies should use {} or continue' 2739*8c35d5eeSXin Li ' [whitespace/empty_loop_body] [5]') 2740*8c35d5eeSXin Li self.TestMultiLineLint("""if (test) { 2741*8c35d5eeSXin Li }""", 2742*8c35d5eeSXin Li 'If statement had no body and no else clause' 2743*8c35d5eeSXin Li ' [whitespace/empty_if_body] [4]') 2744*8c35d5eeSXin Li self.TestMultiLineLint("""if (test, 2745*8c35d5eeSXin Li func({})) { 2746*8c35d5eeSXin Li }""", 2747*8c35d5eeSXin Li 'If statement had no body and no else clause' 2748*8c35d5eeSXin Li ' [whitespace/empty_if_body] [4]') 2749*8c35d5eeSXin Li self.TestMultiLineLint("""if (test) 2750*8c35d5eeSXin Li func();""", '') 2751*8c35d5eeSXin Li self.TestLint('if (test) { hello; }', '') 2752*8c35d5eeSXin Li self.TestLint('if (test({})) { hello; }', '') 2753*8c35d5eeSXin Li self.TestMultiLineLint("""if (test) { 2754*8c35d5eeSXin Li func(); 2755*8c35d5eeSXin Li }""", '') 2756*8c35d5eeSXin Li self.TestMultiLineLint("""if (test) { 2757*8c35d5eeSXin Li // multiline 2758*8c35d5eeSXin Li // comment 2759*8c35d5eeSXin Li }""", '') 2760*8c35d5eeSXin Li self.TestMultiLineLint("""if (test) { // comment 2761*8c35d5eeSXin Li }""", '') 2762*8c35d5eeSXin Li self.TestMultiLineLint("""if (test) { 2763*8c35d5eeSXin Li } else { 2764*8c35d5eeSXin Li }""", '') 2765*8c35d5eeSXin Li self.TestMultiLineLint("""if (func(p1, 2766*8c35d5eeSXin Li p2, 2767*8c35d5eeSXin Li p3)) { 2768*8c35d5eeSXin Li func(); 2769*8c35d5eeSXin Li }""", '') 2770*8c35d5eeSXin Li self.TestMultiLineLint("""if (func({}, p1)) { 2771*8c35d5eeSXin Li func(); 2772*8c35d5eeSXin Li }""", '') 2773*8c35d5eeSXin Li 2774*8c35d5eeSXin Li def testSpacingForRangeBasedFor(self): 2775*8c35d5eeSXin Li # Basic correctly formatted case: 2776*8c35d5eeSXin Li self.TestLint('for (int i : numbers) {', '') 2777*8c35d5eeSXin Li 2778*8c35d5eeSXin Li # Missing space before colon: 2779*8c35d5eeSXin Li self.TestLint('for (int i: numbers) {', 2780*8c35d5eeSXin Li 'Missing space around colon in range-based for loop' 2781*8c35d5eeSXin Li ' [whitespace/forcolon] [2]') 2782*8c35d5eeSXin Li # Missing space after colon: 2783*8c35d5eeSXin Li self.TestLint('for (int i :numbers) {', 2784*8c35d5eeSXin Li 'Missing space around colon in range-based for loop' 2785*8c35d5eeSXin Li ' [whitespace/forcolon] [2]') 2786*8c35d5eeSXin Li # Missing spaces both before and after the colon. 2787*8c35d5eeSXin Li self.TestLint('for (int i:numbers) {', 2788*8c35d5eeSXin Li 'Missing space around colon in range-based for loop' 2789*8c35d5eeSXin Li ' [whitespace/forcolon] [2]') 2790*8c35d5eeSXin Li 2791*8c35d5eeSXin Li # The scope operator '::' shouldn't cause warnings... 2792*8c35d5eeSXin Li self.TestLint('for (std::size_t i : sizes) {}', '') 2793*8c35d5eeSXin Li # ...but it shouldn't suppress them either. 2794*8c35d5eeSXin Li self.TestLint('for (std::size_t i: sizes) {}', 2795*8c35d5eeSXin Li 'Missing space around colon in range-based for loop' 2796*8c35d5eeSXin Li ' [whitespace/forcolon] [2]') 2797*8c35d5eeSXin Li 2798*8c35d5eeSXin Li 2799*8c35d5eeSXin Li # Static or global STL strings. 2800*8c35d5eeSXin Li def testStaticOrGlobalSTLStrings(self): 2801*8c35d5eeSXin Li # A template for the error message for a const global/static string. 2802*8c35d5eeSXin Li error_msg = ('For a static/global string constant, use a C style ' 2803*8c35d5eeSXin Li 'string instead: "%s[]". [runtime/string] [4]') 2804*8c35d5eeSXin Li 2805*8c35d5eeSXin Li # The error message for a non-const global/static string variable. 2806*8c35d5eeSXin Li nonconst_error_msg = ('Static/global string variables are not permitted.' 2807*8c35d5eeSXin Li ' [runtime/string] [4]') 2808*8c35d5eeSXin Li 2809*8c35d5eeSXin Li self.TestLint('string foo;', 2810*8c35d5eeSXin Li nonconst_error_msg) 2811*8c35d5eeSXin Li self.TestLint('string kFoo = "hello"; // English', 2812*8c35d5eeSXin Li nonconst_error_msg) 2813*8c35d5eeSXin Li self.TestLint('static string foo;', 2814*8c35d5eeSXin Li nonconst_error_msg) 2815*8c35d5eeSXin Li self.TestLint('static const string foo;', 2816*8c35d5eeSXin Li error_msg % 'static const char foo') 2817*8c35d5eeSXin Li self.TestLint('static const std::string foo;', 2818*8c35d5eeSXin Li error_msg % 'static const char foo') 2819*8c35d5eeSXin Li self.TestLint('string Foo::bar;', 2820*8c35d5eeSXin Li nonconst_error_msg) 2821*8c35d5eeSXin Li 2822*8c35d5eeSXin Li self.TestLint('std::string foo;', 2823*8c35d5eeSXin Li nonconst_error_msg) 2824*8c35d5eeSXin Li self.TestLint('std::string kFoo = "hello"; // English', 2825*8c35d5eeSXin Li nonconst_error_msg) 2826*8c35d5eeSXin Li self.TestLint('static std::string foo;', 2827*8c35d5eeSXin Li nonconst_error_msg) 2828*8c35d5eeSXin Li self.TestLint('static const std::string foo;', 2829*8c35d5eeSXin Li error_msg % 'static const char foo') 2830*8c35d5eeSXin Li self.TestLint('std::string Foo::bar;', 2831*8c35d5eeSXin Li nonconst_error_msg) 2832*8c35d5eeSXin Li 2833*8c35d5eeSXin Li self.TestLint('::std::string foo;', 2834*8c35d5eeSXin Li nonconst_error_msg) 2835*8c35d5eeSXin Li self.TestLint('::std::string kFoo = "hello"; // English', 2836*8c35d5eeSXin Li nonconst_error_msg) 2837*8c35d5eeSXin Li self.TestLint('static ::std::string foo;', 2838*8c35d5eeSXin Li nonconst_error_msg) 2839*8c35d5eeSXin Li self.TestLint('static const ::std::string foo;', 2840*8c35d5eeSXin Li error_msg % 'static const char foo') 2841*8c35d5eeSXin Li self.TestLint('::std::string Foo::bar;', 2842*8c35d5eeSXin Li nonconst_error_msg) 2843*8c35d5eeSXin Li 2844*8c35d5eeSXin Li self.TestLint('string* pointer', '') 2845*8c35d5eeSXin Li self.TestLint('string *pointer', '') 2846*8c35d5eeSXin Li self.TestLint('string* pointer = Func();', '') 2847*8c35d5eeSXin Li self.TestLint('string *pointer = Func();', '') 2848*8c35d5eeSXin Li self.TestLint('const string* pointer', '') 2849*8c35d5eeSXin Li self.TestLint('const string *pointer', '') 2850*8c35d5eeSXin Li self.TestLint('const string* pointer = Func();', '') 2851*8c35d5eeSXin Li self.TestLint('const string *pointer = Func();', '') 2852*8c35d5eeSXin Li self.TestLint('string const* pointer', '') 2853*8c35d5eeSXin Li self.TestLint('string const *pointer', '') 2854*8c35d5eeSXin Li self.TestLint('string const* pointer = Func();', '') 2855*8c35d5eeSXin Li self.TestLint('string const *pointer = Func();', '') 2856*8c35d5eeSXin Li self.TestLint('string* const pointer', '') 2857*8c35d5eeSXin Li self.TestLint('string *const pointer', '') 2858*8c35d5eeSXin Li self.TestLint('string* const pointer = Func();', '') 2859*8c35d5eeSXin Li self.TestLint('string *const pointer = Func();', '') 2860*8c35d5eeSXin Li self.TestLint('string Foo::bar() {}', '') 2861*8c35d5eeSXin Li self.TestLint('string Foo::operator*() {}', '') 2862*8c35d5eeSXin Li # Rare case. 2863*8c35d5eeSXin Li self.TestLint('string foo("foobar");', nonconst_error_msg) 2864*8c35d5eeSXin Li # Should not catch local or member variables. 2865*8c35d5eeSXin Li self.TestLint(' string foo', '') 2866*8c35d5eeSXin Li # Should not catch functions. 2867*8c35d5eeSXin Li self.TestLint('string EmptyString() { return ""; }', '') 2868*8c35d5eeSXin Li self.TestLint('string EmptyString () { return ""; }', '') 2869*8c35d5eeSXin Li self.TestLint('string const& FileInfo::Pathname() const;', '') 2870*8c35d5eeSXin Li self.TestLint('string const &FileInfo::Pathname() const;', '') 2871*8c35d5eeSXin Li self.TestLint('string VeryLongNameFunctionSometimesEndsWith(\n' 2872*8c35d5eeSXin Li ' VeryLongNameType very_long_name_variable) {}', '') 2873*8c35d5eeSXin Li self.TestLint('template<>\n' 2874*8c35d5eeSXin Li 'string FunctionTemplateSpecialization<SomeType>(\n' 2875*8c35d5eeSXin Li ' int x) { return ""; }', '') 2876*8c35d5eeSXin Li self.TestLint('template<>\n' 2877*8c35d5eeSXin Li 'string FunctionTemplateSpecialization<vector<A::B>* >(\n' 2878*8c35d5eeSXin Li ' int x) { return ""; }', '') 2879*8c35d5eeSXin Li 2880*8c35d5eeSXin Li # should not catch methods of template classes. 2881*8c35d5eeSXin Li self.TestLint('string Class<Type>::Method() const {\n' 2882*8c35d5eeSXin Li ' return "";\n' 2883*8c35d5eeSXin Li '}\n', '') 2884*8c35d5eeSXin Li self.TestLint('string Class<Type>::Method(\n' 2885*8c35d5eeSXin Li ' int arg) const {\n' 2886*8c35d5eeSXin Li ' return "";\n' 2887*8c35d5eeSXin Li '}\n', '') 2888*8c35d5eeSXin Li 2889*8c35d5eeSXin Li # Check multiline cases. 2890*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 2891*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', 2892*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 2893*8c35d5eeSXin Li 'string Class', 2894*8c35d5eeSXin Li '::MemberFunction1();', 2895*8c35d5eeSXin Li 'string Class::', 2896*8c35d5eeSXin Li 'MemberFunction2();', 2897*8c35d5eeSXin Li 'string Class::', 2898*8c35d5eeSXin Li 'NestedClass::MemberFunction3();', 2899*8c35d5eeSXin Li 'string TemplateClass<T>::', 2900*8c35d5eeSXin Li 'NestedClass::MemberFunction4();', 2901*8c35d5eeSXin Li 'const string Class', 2902*8c35d5eeSXin Li '::static_member_variable1;', 2903*8c35d5eeSXin Li 'const string Class::', 2904*8c35d5eeSXin Li 'static_member_variable2;', 2905*8c35d5eeSXin Li 'const string Class', 2906*8c35d5eeSXin Li '::static_member_variable3 = "initial value";', 2907*8c35d5eeSXin Li 'const string Class::', 2908*8c35d5eeSXin Li 'static_member_variable4 = "initial value";', 2909*8c35d5eeSXin Li 'string Class::', 2910*8c35d5eeSXin Li 'static_member_variable5;', 2911*8c35d5eeSXin Li ''], 2912*8c35d5eeSXin Li error_collector) 2913*8c35d5eeSXin Li self.assertEquals(error_collector.Results(), 2914*8c35d5eeSXin Li [error_msg % 'const char Class::static_member_variable1', 2915*8c35d5eeSXin Li error_msg % 'const char Class::static_member_variable2', 2916*8c35d5eeSXin Li error_msg % 'const char Class::static_member_variable3', 2917*8c35d5eeSXin Li error_msg % 'const char Class::static_member_variable4', 2918*8c35d5eeSXin Li nonconst_error_msg]) 2919*8c35d5eeSXin Li 2920*8c35d5eeSXin Li def testNoSpacesInFunctionCalls(self): 2921*8c35d5eeSXin Li self.TestLint('TellStory(1, 3);', 2922*8c35d5eeSXin Li '') 2923*8c35d5eeSXin Li self.TestLint('TellStory(1, 3 );', 2924*8c35d5eeSXin Li 'Extra space before )' 2925*8c35d5eeSXin Li ' [whitespace/parens] [2]') 2926*8c35d5eeSXin Li self.TestLint('TellStory(1 /* wolf */, 3 /* pigs */);', 2927*8c35d5eeSXin Li '') 2928*8c35d5eeSXin Li self.TestMultiLineLint("""TellStory(1, 3 2929*8c35d5eeSXin Li );""", 2930*8c35d5eeSXin Li 'Closing ) should be moved to the previous line' 2931*8c35d5eeSXin Li ' [whitespace/parens] [2]') 2932*8c35d5eeSXin Li self.TestMultiLineLint("""TellStory(Wolves(1), 2933*8c35d5eeSXin Li Pigs(3 2934*8c35d5eeSXin Li ));""", 2935*8c35d5eeSXin Li 'Closing ) should be moved to the previous line' 2936*8c35d5eeSXin Li ' [whitespace/parens] [2]') 2937*8c35d5eeSXin Li self.TestMultiLineLint("""TellStory(1, 2938*8c35d5eeSXin Li 3 );""", 2939*8c35d5eeSXin Li 'Extra space before )' 2940*8c35d5eeSXin Li ' [whitespace/parens] [2]') 2941*8c35d5eeSXin Li 2942*8c35d5eeSXin Li def testToDoComments(self): 2943*8c35d5eeSXin Li start_space = ('Too many spaces before TODO' 2944*8c35d5eeSXin Li ' [whitespace/todo] [2]') 2945*8c35d5eeSXin Li missing_username = ('Missing username in TODO; it should look like ' 2946*8c35d5eeSXin Li '"// TODO(my_username): Stuff."' 2947*8c35d5eeSXin Li ' [readability/todo] [2]') 2948*8c35d5eeSXin Li end_space = ('TODO(my_username) should be followed by a space' 2949*8c35d5eeSXin Li ' [whitespace/todo] [2]') 2950*8c35d5eeSXin Li 2951*8c35d5eeSXin Li self.TestLint('// TODOfix this', 2952*8c35d5eeSXin Li [start_space, missing_username, end_space]) 2953*8c35d5eeSXin Li self.TestLint('// TODO(ljenkins)fix this', 2954*8c35d5eeSXin Li [start_space, end_space]) 2955*8c35d5eeSXin Li self.TestLint('// TODO fix this', 2956*8c35d5eeSXin Li [start_space, missing_username]) 2957*8c35d5eeSXin Li self.TestLint('// TODO fix this', missing_username) 2958*8c35d5eeSXin Li self.TestLint('// TODO: fix this', missing_username) 2959*8c35d5eeSXin Li self.TestLint('//TODO(ljenkins): Fix this', 2960*8c35d5eeSXin Li 'Should have a space between // and comment' 2961*8c35d5eeSXin Li ' [whitespace/comments] [4]') 2962*8c35d5eeSXin Li self.TestLint('// TODO(ljenkins):Fix this', end_space) 2963*8c35d5eeSXin Li self.TestLint('// TODO(ljenkins):', '') 2964*8c35d5eeSXin Li self.TestLint('// TODO(ljenkins): fix this', '') 2965*8c35d5eeSXin Li self.TestLint('// TODO(ljenkins): Fix this', '') 2966*8c35d5eeSXin Li self.TestLint('#if 1 // TEST_URLTODOCID_WHICH_HAS_THAT_WORD_IN_IT_H_', '') 2967*8c35d5eeSXin Li self.TestLint('// See also similar TODO above', '') 2968*8c35d5eeSXin Li self.TestLint(r'EXPECT_EQ("\\", ' 2969*8c35d5eeSXin Li r'NormalizePath("/./../foo///bar/..//x/../..", ""));', 2970*8c35d5eeSXin Li '') 2971*8c35d5eeSXin Li 2972*8c35d5eeSXin Li def testTwoSpacesBetweenCodeAndComments(self): 2973*8c35d5eeSXin Li self.TestLint('} // namespace foo', 2974*8c35d5eeSXin Li 'At least two spaces is best between code and comments' 2975*8c35d5eeSXin Li ' [whitespace/comments] [2]') 2976*8c35d5eeSXin Li self.TestLint('}// namespace foo', 2977*8c35d5eeSXin Li 'At least two spaces is best between code and comments' 2978*8c35d5eeSXin Li ' [whitespace/comments] [2]') 2979*8c35d5eeSXin Li self.TestLint('printf("foo"); // Outside quotes.', 2980*8c35d5eeSXin Li 'At least two spaces is best between code and comments' 2981*8c35d5eeSXin Li ' [whitespace/comments] [2]') 2982*8c35d5eeSXin Li self.TestLint('int i = 0; // Having two spaces is fine.', '') 2983*8c35d5eeSXin Li self.TestLint('int i = 0; // Having three spaces is OK.', '') 2984*8c35d5eeSXin Li self.TestLint('// Top level comment', '') 2985*8c35d5eeSXin Li self.TestLint(' // Line starts with two spaces.', '') 2986*8c35d5eeSXin Li self.TestMultiLineLint('void foo() {\n' 2987*8c35d5eeSXin Li ' { // A scope is opening.\n' 2988*8c35d5eeSXin Li ' int a;', '') 2989*8c35d5eeSXin Li self.TestMultiLineLint('void foo() {\n' 2990*8c35d5eeSXin Li ' { // A scope is opening.\n' 2991*8c35d5eeSXin Li '#define A a', 2992*8c35d5eeSXin Li 'At least two spaces is best between code and ' 2993*8c35d5eeSXin Li 'comments [whitespace/comments] [2]') 2994*8c35d5eeSXin Li self.TestMultiLineLint(' foo();\n' 2995*8c35d5eeSXin Li ' { // An indented scope is opening.\n' 2996*8c35d5eeSXin Li ' int a;', '') 2997*8c35d5eeSXin Li self.TestMultiLineLint('vector<int> my_elements = {// first\n' 2998*8c35d5eeSXin Li ' 1,', '') 2999*8c35d5eeSXin Li self.TestMultiLineLint('vector<int> my_elements = {// my_elements is ..\n' 3000*8c35d5eeSXin Li ' 1,', 3001*8c35d5eeSXin Li 'At least two spaces is best between code and ' 3002*8c35d5eeSXin Li 'comments [whitespace/comments] [2]') 3003*8c35d5eeSXin Li self.TestLint('if (foo) { // not a pure scope; comment is too close!', 3004*8c35d5eeSXin Li 'At least two spaces is best between code and comments' 3005*8c35d5eeSXin Li ' [whitespace/comments] [2]') 3006*8c35d5eeSXin Li self.TestLint('printf("// In quotes.")', '') 3007*8c35d5eeSXin Li self.TestLint('printf("\\"%s // In quotes.")', '') 3008*8c35d5eeSXin Li self.TestLint('printf("%s", "// In quotes.")', '') 3009*8c35d5eeSXin Li 3010*8c35d5eeSXin Li def testSpaceAfterCommentMarker(self): 3011*8c35d5eeSXin Li self.TestLint('//', '') 3012*8c35d5eeSXin Li self.TestLint('//x', 'Should have a space between // and comment' 3013*8c35d5eeSXin Li ' [whitespace/comments] [4]') 3014*8c35d5eeSXin Li self.TestLint('// x', '') 3015*8c35d5eeSXin Li self.TestLint('///', '') 3016*8c35d5eeSXin Li self.TestLint('/// x', '') 3017*8c35d5eeSXin Li self.TestLint('//!', '') 3018*8c35d5eeSXin Li self.TestLint('//----', '') 3019*8c35d5eeSXin Li self.TestLint('//====', '') 3020*8c35d5eeSXin Li self.TestLint('//////', '') 3021*8c35d5eeSXin Li self.TestLint('////// x', '') 3022*8c35d5eeSXin Li self.TestLint('///< x', '') # After-member Doxygen comment 3023*8c35d5eeSXin Li self.TestLint('//!< x', '') # After-member Doxygen comment 3024*8c35d5eeSXin Li self.TestLint('////x', 'Should have a space between // and comment' 3025*8c35d5eeSXin Li ' [whitespace/comments] [4]') 3026*8c35d5eeSXin Li self.TestLint('//}', '') 3027*8c35d5eeSXin Li self.TestLint('//}x', 'Should have a space between // and comment' 3028*8c35d5eeSXin Li ' [whitespace/comments] [4]') 3029*8c35d5eeSXin Li self.TestLint('//!<x', 'Should have a space between // and comment' 3030*8c35d5eeSXin Li ' [whitespace/comments] [4]') 3031*8c35d5eeSXin Li self.TestLint('///<x', 'Should have a space between // and comment' 3032*8c35d5eeSXin Li ' [whitespace/comments] [4]') 3033*8c35d5eeSXin Li 3034*8c35d5eeSXin Li # Test a line preceded by empty or comment lines. There was a bug 3035*8c35d5eeSXin Li # that caused it to print the same warning N times if the erroneous 3036*8c35d5eeSXin Li # line was preceded by N lines of empty or comment lines. To be 3037*8c35d5eeSXin Li # precise, the '// marker so line numbers and indices both start at 3038*8c35d5eeSXin Li # 1' line was also causing the issue. 3039*8c35d5eeSXin Li def testLinePrecededByEmptyOrCommentLines(self): 3040*8c35d5eeSXin Li def DoTest(self, lines): 3041*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3042*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', lines, error_collector) 3043*8c35d5eeSXin Li # The warning appears only once. 3044*8c35d5eeSXin Li self.assertEquals( 3045*8c35d5eeSXin Li 1, 3046*8c35d5eeSXin Li error_collector.Results().count( 3047*8c35d5eeSXin Li 'Do not use namespace using-directives. ' 3048*8c35d5eeSXin Li 'Use using-declarations instead.' 3049*8c35d5eeSXin Li ' [build/namespaces] [5]')) 3050*8c35d5eeSXin Li DoTest(self, ['using namespace foo;']) 3051*8c35d5eeSXin Li DoTest(self, ['', '', '', 'using namespace foo;']) 3052*8c35d5eeSXin Li DoTest(self, ['// hello', 'using namespace foo;']) 3053*8c35d5eeSXin Li 3054*8c35d5eeSXin Li def testNewlineAtEOF(self): 3055*8c35d5eeSXin Li def DoTest(self, data, is_missing_eof): 3056*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3057*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', data.split('\n'), 3058*8c35d5eeSXin Li error_collector) 3059*8c35d5eeSXin Li # The warning appears only once. 3060*8c35d5eeSXin Li self.assertEquals( 3061*8c35d5eeSXin Li int(is_missing_eof), 3062*8c35d5eeSXin Li error_collector.Results().count( 3063*8c35d5eeSXin Li 'Could not find a newline character at the end of the file.' 3064*8c35d5eeSXin Li ' [whitespace/ending_newline] [5]')) 3065*8c35d5eeSXin Li 3066*8c35d5eeSXin Li DoTest(self, '// Newline\n// at EOF\n', False) 3067*8c35d5eeSXin Li DoTest(self, '// No newline\n// at EOF', True) 3068*8c35d5eeSXin Li 3069*8c35d5eeSXin Li def testInvalidUtf8(self): 3070*8c35d5eeSXin Li def DoTest(self, raw_bytes, has_invalid_utf8): 3071*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3072*8c35d5eeSXin Li cpplint.ProcessFileData( 3073*8c35d5eeSXin Li 'foo.cc', 'cc', 3074*8c35d5eeSXin Li unicode(raw_bytes, 'utf8', 'replace').split('\n'), 3075*8c35d5eeSXin Li error_collector) 3076*8c35d5eeSXin Li # The warning appears only once. 3077*8c35d5eeSXin Li self.assertEquals( 3078*8c35d5eeSXin Li int(has_invalid_utf8), 3079*8c35d5eeSXin Li error_collector.Results().count( 3080*8c35d5eeSXin Li 'Line contains invalid UTF-8' 3081*8c35d5eeSXin Li ' (or Unicode replacement character).' 3082*8c35d5eeSXin Li ' [readability/utf8] [5]')) 3083*8c35d5eeSXin Li 3084*8c35d5eeSXin Li DoTest(self, 'Hello world\n', False) 3085*8c35d5eeSXin Li DoTest(self, '\xe9\x8e\xbd\n', False) 3086*8c35d5eeSXin Li DoTest(self, '\xe9x\x8e\xbd\n', True) 3087*8c35d5eeSXin Li # This is the encoding of the replacement character itself (which 3088*8c35d5eeSXin Li # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')). 3089*8c35d5eeSXin Li DoTest(self, '\xef\xbf\xbd\n', True) 3090*8c35d5eeSXin Li 3091*8c35d5eeSXin Li def testBadCharacters(self): 3092*8c35d5eeSXin Li # Test for NUL bytes only 3093*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3094*8c35d5eeSXin Li cpplint.ProcessFileData('nul.cc', 'cc', 3095*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 3096*8c35d5eeSXin Li '\0', ''], error_collector) 3097*8c35d5eeSXin Li self.assertEquals( 3098*8c35d5eeSXin Li error_collector.Results(), 3099*8c35d5eeSXin Li 'Line contains NUL byte. [readability/nul] [5]') 3100*8c35d5eeSXin Li 3101*8c35d5eeSXin Li # Make sure both NUL bytes and UTF-8 are caught if they appear on 3102*8c35d5eeSXin Li # the same line. 3103*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3104*8c35d5eeSXin Li cpplint.ProcessFileData( 3105*8c35d5eeSXin Li 'nul_utf8.cc', 'cc', 3106*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 3107*8c35d5eeSXin Li unicode('\xe9x\0', 'utf8', 'replace'), ''], 3108*8c35d5eeSXin Li error_collector) 3109*8c35d5eeSXin Li self.assertEquals( 3110*8c35d5eeSXin Li error_collector.Results(), 3111*8c35d5eeSXin Li ['Line contains invalid UTF-8 (or Unicode replacement character).' 3112*8c35d5eeSXin Li ' [readability/utf8] [5]', 3113*8c35d5eeSXin Li 'Line contains NUL byte. [readability/nul] [5]']) 3114*8c35d5eeSXin Li 3115*8c35d5eeSXin Li def testIsBlankLine(self): 3116*8c35d5eeSXin Li self.assert_(cpplint.IsBlankLine('')) 3117*8c35d5eeSXin Li self.assert_(cpplint.IsBlankLine(' ')) 3118*8c35d5eeSXin Li self.assert_(cpplint.IsBlankLine(' \t\r\n')) 3119*8c35d5eeSXin Li self.assert_(not cpplint.IsBlankLine('int a;')) 3120*8c35d5eeSXin Li self.assert_(not cpplint.IsBlankLine('{')) 3121*8c35d5eeSXin Li 3122*8c35d5eeSXin Li def testBlankLinesCheck(self): 3123*8c35d5eeSXin Li self.TestBlankLinesCheck(['{\n', '\n', '\n', '}\n'], 1, 1) 3124*8c35d5eeSXin Li self.TestBlankLinesCheck([' if (foo) {\n', '\n', ' }\n'], 1, 1) 3125*8c35d5eeSXin Li self.TestBlankLinesCheck( 3126*8c35d5eeSXin Li ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0) 3127*8c35d5eeSXin Li self.TestBlankLinesCheck(['\n', 'run("{");\n', '\n'], 0, 0) 3128*8c35d5eeSXin Li self.TestBlankLinesCheck(['\n', ' if (foo) { return 0; }\n', '\n'], 0, 0) 3129*8c35d5eeSXin Li self.TestBlankLinesCheck( 3130*8c35d5eeSXin Li ['int x(\n', ' int a) {\n', '\n', 'return 0;\n', '}'], 0, 0) 3131*8c35d5eeSXin Li self.TestBlankLinesCheck( 3132*8c35d5eeSXin Li ['int x(\n', ' int a) const {\n', '\n', 'return 0;\n', '}'], 0, 0) 3133*8c35d5eeSXin Li self.TestBlankLinesCheck( 3134*8c35d5eeSXin Li ['int x(\n', ' int a) {\n', '\n', 'return 0;\n', '}'], 1, 0) 3135*8c35d5eeSXin Li self.TestBlankLinesCheck( 3136*8c35d5eeSXin Li ['int x(\n', ' int a) {\n', '\n', 'return 0;\n', '}'], 1, 0) 3137*8c35d5eeSXin Li 3138*8c35d5eeSXin Li def testAllowBlankLineBeforeClosingNamespace(self): 3139*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3140*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', 3141*8c35d5eeSXin Li ['namespace {', 3142*8c35d5eeSXin Li '', 3143*8c35d5eeSXin Li '} // namespace', 3144*8c35d5eeSXin Li 'namespace another_namespace {', 3145*8c35d5eeSXin Li '', 3146*8c35d5eeSXin Li '}', 3147*8c35d5eeSXin Li 'namespace {', 3148*8c35d5eeSXin Li '', 3149*8c35d5eeSXin Li 'template<class T, ', 3150*8c35d5eeSXin Li ' class A = hoge<T>, ', 3151*8c35d5eeSXin Li ' class B = piyo<T>, ', 3152*8c35d5eeSXin Li ' class C = fuga<T> >', 3153*8c35d5eeSXin Li 'class D {', 3154*8c35d5eeSXin Li ' public:', 3155*8c35d5eeSXin Li '};', 3156*8c35d5eeSXin Li '', '', '', '', 3157*8c35d5eeSXin Li '}'], 3158*8c35d5eeSXin Li error_collector) 3159*8c35d5eeSXin Li self.assertEquals(0, error_collector.Results().count( 3160*8c35d5eeSXin Li 'Redundant blank line at the end of a code block should be deleted.' 3161*8c35d5eeSXin Li ' [whitespace/blank_line] [3]')) 3162*8c35d5eeSXin Li 3163*8c35d5eeSXin Li def testAllowBlankLineBeforeIfElseChain(self): 3164*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3165*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', 3166*8c35d5eeSXin Li ['if (hoge) {', 3167*8c35d5eeSXin Li '', # No warning 3168*8c35d5eeSXin Li '} else if (piyo) {', 3169*8c35d5eeSXin Li '', # No warning 3170*8c35d5eeSXin Li '} else if (piyopiyo) {', 3171*8c35d5eeSXin Li ' hoge = true;', # No warning 3172*8c35d5eeSXin Li '} else {', 3173*8c35d5eeSXin Li '', # Warning on this line 3174*8c35d5eeSXin Li '}'], 3175*8c35d5eeSXin Li error_collector) 3176*8c35d5eeSXin Li self.assertEquals(1, error_collector.Results().count( 3177*8c35d5eeSXin Li 'Redundant blank line at the end of a code block should be deleted.' 3178*8c35d5eeSXin Li ' [whitespace/blank_line] [3]')) 3179*8c35d5eeSXin Li 3180*8c35d5eeSXin Li def testAllowBlankLineAfterExtern(self): 3181*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3182*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', 3183*8c35d5eeSXin Li ['extern "C" {', 3184*8c35d5eeSXin Li '', 3185*8c35d5eeSXin Li 'EXPORTAPI void APICALL Some_function() {}', 3186*8c35d5eeSXin Li '', 3187*8c35d5eeSXin Li '}'], 3188*8c35d5eeSXin Li error_collector) 3189*8c35d5eeSXin Li self.assertEquals(0, error_collector.Results().count( 3190*8c35d5eeSXin Li 'Redundant blank line at the start of a code block should be deleted.' 3191*8c35d5eeSXin Li ' [whitespace/blank_line] [2]')) 3192*8c35d5eeSXin Li self.assertEquals(0, error_collector.Results().count( 3193*8c35d5eeSXin Li 'Redundant blank line at the end of a code block should be deleted.' 3194*8c35d5eeSXin Li ' [whitespace/blank_line] [3]')) 3195*8c35d5eeSXin Li 3196*8c35d5eeSXin Li def testBlankLineBeforeSectionKeyword(self): 3197*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3198*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', 3199*8c35d5eeSXin Li ['class A {', 3200*8c35d5eeSXin Li ' public:', 3201*8c35d5eeSXin Li ' protected:', # warning 1 3202*8c35d5eeSXin Li ' private:', # warning 2 3203*8c35d5eeSXin Li ' struct B {', 3204*8c35d5eeSXin Li ' public:', 3205*8c35d5eeSXin Li ' private:'] + # warning 3 3206*8c35d5eeSXin Li ([''] * 100) + # Make A and B longer than 100 lines 3207*8c35d5eeSXin Li [' };', 3208*8c35d5eeSXin Li ' struct C {', 3209*8c35d5eeSXin Li ' protected:', 3210*8c35d5eeSXin Li ' private:', # C is too short for warnings 3211*8c35d5eeSXin Li ' };', 3212*8c35d5eeSXin Li '};', 3213*8c35d5eeSXin Li 'class D', 3214*8c35d5eeSXin Li ' : public {', 3215*8c35d5eeSXin Li ' public:', # no warning 3216*8c35d5eeSXin Li '};', 3217*8c35d5eeSXin Li 'class E {\\', 3218*8c35d5eeSXin Li ' public:\\'] + 3219*8c35d5eeSXin Li (['\\'] * 100) + # Makes E > 100 lines 3220*8c35d5eeSXin Li [' int non_empty_line;\\', 3221*8c35d5eeSXin Li ' private:\\', # no warning 3222*8c35d5eeSXin Li ' int a;\\', 3223*8c35d5eeSXin Li '};'], 3224*8c35d5eeSXin Li error_collector) 3225*8c35d5eeSXin Li self.assertEquals(2, error_collector.Results().count( 3226*8c35d5eeSXin Li '"private:" should be preceded by a blank line' 3227*8c35d5eeSXin Li ' [whitespace/blank_line] [3]')) 3228*8c35d5eeSXin Li self.assertEquals(1, error_collector.Results().count( 3229*8c35d5eeSXin Li '"protected:" should be preceded by a blank line' 3230*8c35d5eeSXin Li ' [whitespace/blank_line] [3]')) 3231*8c35d5eeSXin Li 3232*8c35d5eeSXin Li def testNoBlankLineAfterSectionKeyword(self): 3233*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3234*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', 3235*8c35d5eeSXin Li ['class A {', 3236*8c35d5eeSXin Li ' public:', 3237*8c35d5eeSXin Li '', # warning 1 3238*8c35d5eeSXin Li ' private:', 3239*8c35d5eeSXin Li '', # warning 2 3240*8c35d5eeSXin Li ' struct B {', 3241*8c35d5eeSXin Li ' protected:', 3242*8c35d5eeSXin Li '', # warning 3 3243*8c35d5eeSXin Li ' };', 3244*8c35d5eeSXin Li '};'], 3245*8c35d5eeSXin Li error_collector) 3246*8c35d5eeSXin Li self.assertEquals(1, error_collector.Results().count( 3247*8c35d5eeSXin Li 'Do not leave a blank line after "public:"' 3248*8c35d5eeSXin Li ' [whitespace/blank_line] [3]')) 3249*8c35d5eeSXin Li self.assertEquals(1, error_collector.Results().count( 3250*8c35d5eeSXin Li 'Do not leave a blank line after "protected:"' 3251*8c35d5eeSXin Li ' [whitespace/blank_line] [3]')) 3252*8c35d5eeSXin Li self.assertEquals(1, error_collector.Results().count( 3253*8c35d5eeSXin Li 'Do not leave a blank line after "private:"' 3254*8c35d5eeSXin Li ' [whitespace/blank_line] [3]')) 3255*8c35d5eeSXin Li 3256*8c35d5eeSXin Li def testAllowBlankLinesInRawStrings(self): 3257*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3258*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', 3259*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 3260*8c35d5eeSXin Li 'static const char *kData[] = {R"(', 3261*8c35d5eeSXin Li '', 3262*8c35d5eeSXin Li ')", R"(', 3263*8c35d5eeSXin Li '', 3264*8c35d5eeSXin Li ')"};', 3265*8c35d5eeSXin Li ''], 3266*8c35d5eeSXin Li error_collector) 3267*8c35d5eeSXin Li self.assertEquals('', error_collector.Results()) 3268*8c35d5eeSXin Li 3269*8c35d5eeSXin Li def testElseOnSameLineAsClosingBraces(self): 3270*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3271*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', 3272*8c35d5eeSXin Li ['if (hoge) {', 3273*8c35d5eeSXin Li '}', 3274*8c35d5eeSXin Li 'else if (piyo) {', # Warning on this line 3275*8c35d5eeSXin Li '}', 3276*8c35d5eeSXin Li ' else {' # Warning on this line 3277*8c35d5eeSXin Li '', 3278*8c35d5eeSXin Li '}'], 3279*8c35d5eeSXin Li error_collector) 3280*8c35d5eeSXin Li self.assertEquals(2, error_collector.Results().count( 3281*8c35d5eeSXin Li 'An else should appear on the same line as the preceding }' 3282*8c35d5eeSXin Li ' [whitespace/newline] [4]')) 3283*8c35d5eeSXin Li 3284*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3285*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', 3286*8c35d5eeSXin Li ['if (hoge) {', 3287*8c35d5eeSXin Li '', 3288*8c35d5eeSXin Li '}', 3289*8c35d5eeSXin Li 'else', # Warning on this line 3290*8c35d5eeSXin Li '{', 3291*8c35d5eeSXin Li '', 3292*8c35d5eeSXin Li '}'], 3293*8c35d5eeSXin Li error_collector) 3294*8c35d5eeSXin Li self.assertEquals(1, error_collector.Results().count( 3295*8c35d5eeSXin Li 'An else should appear on the same line as the preceding }' 3296*8c35d5eeSXin Li ' [whitespace/newline] [4]')) 3297*8c35d5eeSXin Li 3298*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3299*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', 3300*8c35d5eeSXin Li ['if (hoge) {', 3301*8c35d5eeSXin Li '', 3302*8c35d5eeSXin Li '}', 3303*8c35d5eeSXin Li 'else_function();'], 3304*8c35d5eeSXin Li error_collector) 3305*8c35d5eeSXin Li self.assertEquals(0, error_collector.Results().count( 3306*8c35d5eeSXin Li 'An else should appear on the same line as the preceding }' 3307*8c35d5eeSXin Li ' [whitespace/newline] [4]')) 3308*8c35d5eeSXin Li 3309*8c35d5eeSXin Li def testMultipleStatementsOnSameLine(self): 3310*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3311*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', 3312*8c35d5eeSXin Li ['for (int i = 0; i < 1; i++) {}', 3313*8c35d5eeSXin Li 'switch (x) {', 3314*8c35d5eeSXin Li ' case 0: func(); break; ', 3315*8c35d5eeSXin Li '}', 3316*8c35d5eeSXin Li 'sum += MathUtil::SafeIntRound(x); x += 0.1;'], 3317*8c35d5eeSXin Li error_collector) 3318*8c35d5eeSXin Li self.assertEquals(0, error_collector.Results().count( 3319*8c35d5eeSXin Li 'More than one command on the same line [whitespace/newline] [0]')) 3320*8c35d5eeSXin Li 3321*8c35d5eeSXin Li old_verbose_level = cpplint._cpplint_state.verbose_level 3322*8c35d5eeSXin Li cpplint._cpplint_state.verbose_level = 0 3323*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', 3324*8c35d5eeSXin Li ['sum += MathUtil::SafeIntRound(x); x += 0.1;'], 3325*8c35d5eeSXin Li error_collector) 3326*8c35d5eeSXin Li cpplint._cpplint_state.verbose_level = old_verbose_level 3327*8c35d5eeSXin Li 3328*8c35d5eeSXin Li def testEndOfNamespaceComments(self): 3329*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3330*8c35d5eeSXin Li cpplint.ProcessFileData('foo.cc', 'cc', 3331*8c35d5eeSXin Li ['namespace {', 3332*8c35d5eeSXin Li '', 3333*8c35d5eeSXin Li '}', # No warning (too short) 3334*8c35d5eeSXin Li 'namespace expected {', 3335*8c35d5eeSXin Li '} // namespace mismatched', # Warning here 3336*8c35d5eeSXin Li 'namespace {', 3337*8c35d5eeSXin Li '} // namespace mismatched', # Warning here 3338*8c35d5eeSXin Li 'namespace outer { namespace nested {'] + 3339*8c35d5eeSXin Li ([''] * 10) + 3340*8c35d5eeSXin Li ['}', # Warning here 3341*8c35d5eeSXin Li '}', # Warning here 3342*8c35d5eeSXin Li 'namespace {'] + 3343*8c35d5eeSXin Li ([''] * 10) + 3344*8c35d5eeSXin Li ['}', # Warning here 3345*8c35d5eeSXin Li 'namespace {'] + 3346*8c35d5eeSXin Li ([''] * 10) + 3347*8c35d5eeSXin Li ['} // namespace some description', # Anon warning 3348*8c35d5eeSXin Li 'namespace {'] + 3349*8c35d5eeSXin Li ([''] * 10) + 3350*8c35d5eeSXin Li ['} // namespace anonymous', # Variant warning 3351*8c35d5eeSXin Li 'namespace {'] + 3352*8c35d5eeSXin Li ([''] * 10) + 3353*8c35d5eeSXin Li ['} // anonymous namespace (utils)', # Variant 3354*8c35d5eeSXin Li 'namespace {'] + 3355*8c35d5eeSXin Li ([''] * 10) + 3356*8c35d5eeSXin Li ['} // anonymous namespace', # No warning 3357*8c35d5eeSXin Li 'namespace missing_comment {'] + 3358*8c35d5eeSXin Li ([''] * 10) + 3359*8c35d5eeSXin Li ['}', # Warning here 3360*8c35d5eeSXin Li 'namespace no_warning {'] + 3361*8c35d5eeSXin Li ([''] * 10) + 3362*8c35d5eeSXin Li ['} // namespace no_warning', 3363*8c35d5eeSXin Li 'namespace no_warning {'] + 3364*8c35d5eeSXin Li ([''] * 10) + 3365*8c35d5eeSXin Li ['}; // end namespace no_warning', 3366*8c35d5eeSXin Li '#define MACRO \\', 3367*8c35d5eeSXin Li 'namespace c_style { \\'] + 3368*8c35d5eeSXin Li (['\\'] * 10) + 3369*8c35d5eeSXin Li ['} /* namespace c_style. */ \\', 3370*8c35d5eeSXin Li ';'], 3371*8c35d5eeSXin Li error_collector) 3372*8c35d5eeSXin Li self.assertEquals(1, error_collector.Results().count( 3373*8c35d5eeSXin Li 'Namespace should be terminated with "// namespace expected"' 3374*8c35d5eeSXin Li ' [readability/namespace] [5]')) 3375*8c35d5eeSXin Li self.assertEquals(1, error_collector.Results().count( 3376*8c35d5eeSXin Li 'Namespace should be terminated with "// namespace outer"' 3377*8c35d5eeSXin Li ' [readability/namespace] [5]')) 3378*8c35d5eeSXin Li self.assertEquals(1, error_collector.Results().count( 3379*8c35d5eeSXin Li 'Namespace should be terminated with "// namespace nested"' 3380*8c35d5eeSXin Li ' [readability/namespace] [5]')) 3381*8c35d5eeSXin Li self.assertEquals(3, error_collector.Results().count( 3382*8c35d5eeSXin Li 'Anonymous namespace should be terminated with "// namespace"' 3383*8c35d5eeSXin Li ' [readability/namespace] [5]')) 3384*8c35d5eeSXin Li self.assertEquals(2, error_collector.Results().count( 3385*8c35d5eeSXin Li 'Anonymous namespace should be terminated with "// namespace" or' 3386*8c35d5eeSXin Li ' "// anonymous namespace"' 3387*8c35d5eeSXin Li ' [readability/namespace] [5]')) 3388*8c35d5eeSXin Li self.assertEquals(1, error_collector.Results().count( 3389*8c35d5eeSXin Li 'Namespace should be terminated with "// namespace missing_comment"' 3390*8c35d5eeSXin Li ' [readability/namespace] [5]')) 3391*8c35d5eeSXin Li self.assertEquals(0, error_collector.Results().count( 3392*8c35d5eeSXin Li 'Namespace should be terminated with "// namespace no_warning"' 3393*8c35d5eeSXin Li ' [readability/namespace] [5]')) 3394*8c35d5eeSXin Li 3395*8c35d5eeSXin Li def testElseClauseNotOnSameLineAsElse(self): 3396*8c35d5eeSXin Li self.TestLint(' else DoSomethingElse();', 3397*8c35d5eeSXin Li 'Else clause should never be on same line as else ' 3398*8c35d5eeSXin Li '(use 2 lines) [whitespace/newline] [4]') 3399*8c35d5eeSXin Li self.TestLint(' else ifDoSomethingElse();', 3400*8c35d5eeSXin Li 'Else clause should never be on same line as else ' 3401*8c35d5eeSXin Li '(use 2 lines) [whitespace/newline] [4]') 3402*8c35d5eeSXin Li self.TestLint(' } else if (blah) {', '') 3403*8c35d5eeSXin Li self.TestLint(' variable_ends_in_else = true;', '') 3404*8c35d5eeSXin Li 3405*8c35d5eeSXin Li def testComma(self): 3406*8c35d5eeSXin Li self.TestLint('a = f(1,2);', 3407*8c35d5eeSXin Li 'Missing space after , [whitespace/comma] [3]') 3408*8c35d5eeSXin Li self.TestLint('int tmp=a,a=b,b=tmp;', 3409*8c35d5eeSXin Li ['Missing spaces around = [whitespace/operators] [4]', 3410*8c35d5eeSXin Li 'Missing space after , [whitespace/comma] [3]']) 3411*8c35d5eeSXin Li self.TestLint('f(a, /* name */ b);', '') 3412*8c35d5eeSXin Li self.TestLint('f(a, /* name */b);', '') 3413*8c35d5eeSXin Li self.TestLint('f(a, /* name */-1);', '') 3414*8c35d5eeSXin Li self.TestLint('f(a, /* name */"1");', '') 3415*8c35d5eeSXin Li self.TestLint('f(1, /* empty macro arg */, 2)', '') 3416*8c35d5eeSXin Li self.TestLint('f(1,, 2)', '') 3417*8c35d5eeSXin Li self.TestLint('operator,()', '') 3418*8c35d5eeSXin Li self.TestLint('operator,(a,b)', 3419*8c35d5eeSXin Li 'Missing space after , [whitespace/comma] [3]') 3420*8c35d5eeSXin Li 3421*8c35d5eeSXin Li def testEqualsOperatorSpacing(self): 3422*8c35d5eeSXin Li self.TestLint('int tmp= a;', 3423*8c35d5eeSXin Li 'Missing spaces around = [whitespace/operators] [4]') 3424*8c35d5eeSXin Li self.TestLint('int tmp =a;', 3425*8c35d5eeSXin Li 'Missing spaces around = [whitespace/operators] [4]') 3426*8c35d5eeSXin Li self.TestLint('int tmp=a;', 3427*8c35d5eeSXin Li 'Missing spaces around = [whitespace/operators] [4]') 3428*8c35d5eeSXin Li self.TestLint('int tmp= 7;', 3429*8c35d5eeSXin Li 'Missing spaces around = [whitespace/operators] [4]') 3430*8c35d5eeSXin Li self.TestLint('int tmp =7;', 3431*8c35d5eeSXin Li 'Missing spaces around = [whitespace/operators] [4]') 3432*8c35d5eeSXin Li self.TestLint('int tmp=7;', 3433*8c35d5eeSXin Li 'Missing spaces around = [whitespace/operators] [4]') 3434*8c35d5eeSXin Li self.TestLint('int* tmp=*p;', 3435*8c35d5eeSXin Li 'Missing spaces around = [whitespace/operators] [4]') 3436*8c35d5eeSXin Li self.TestLint('int* tmp= *p;', 3437*8c35d5eeSXin Li 'Missing spaces around = [whitespace/operators] [4]') 3438*8c35d5eeSXin Li self.TestMultiLineLint( 3439*8c35d5eeSXin Li TrimExtraIndent(''' 3440*8c35d5eeSXin Li lookahead_services_= 3441*8c35d5eeSXin Li ::strings::Split(FLAGS_ls, ",", ::strings::SkipEmpty());'''), 3442*8c35d5eeSXin Li 'Missing spaces around = [whitespace/operators] [4]') 3443*8c35d5eeSXin Li self.TestLint('bool result = a>=42;', 3444*8c35d5eeSXin Li 'Missing spaces around >= [whitespace/operators] [3]') 3445*8c35d5eeSXin Li self.TestLint('bool result = a<=42;', 3446*8c35d5eeSXin Li 'Missing spaces around <= [whitespace/operators] [3]') 3447*8c35d5eeSXin Li self.TestLint('bool result = a==42;', 3448*8c35d5eeSXin Li 'Missing spaces around == [whitespace/operators] [3]') 3449*8c35d5eeSXin Li self.TestLint('auto result = a!=42;', 3450*8c35d5eeSXin Li 'Missing spaces around != [whitespace/operators] [3]') 3451*8c35d5eeSXin Li self.TestLint('int a = b!=c;', 3452*8c35d5eeSXin Li 'Missing spaces around != [whitespace/operators] [3]') 3453*8c35d5eeSXin Li self.TestLint('a&=42;', '') 3454*8c35d5eeSXin Li self.TestLint('a|=42;', '') 3455*8c35d5eeSXin Li self.TestLint('a^=42;', '') 3456*8c35d5eeSXin Li self.TestLint('a+=42;', '') 3457*8c35d5eeSXin Li self.TestLint('a*=42;', '') 3458*8c35d5eeSXin Li self.TestLint('a/=42;', '') 3459*8c35d5eeSXin Li self.TestLint('a%=42;', '') 3460*8c35d5eeSXin Li self.TestLint('a>>=5;', '') 3461*8c35d5eeSXin Li self.TestLint('a<<=5;', '') 3462*8c35d5eeSXin Li 3463*8c35d5eeSXin Li def testShiftOperatorSpacing(self): 3464*8c35d5eeSXin Li self.TestLint('a<<b', 3465*8c35d5eeSXin Li 'Missing spaces around << [whitespace/operators] [3]') 3466*8c35d5eeSXin Li self.TestLint('a>>b', 3467*8c35d5eeSXin Li 'Missing spaces around >> [whitespace/operators] [3]') 3468*8c35d5eeSXin Li self.TestLint('1<<20', '') 3469*8c35d5eeSXin Li self.TestLint('1024>>10', '') 3470*8c35d5eeSXin Li self.TestLint('Kernel<<<1, 2>>>()', '') 3471*8c35d5eeSXin Li 3472*8c35d5eeSXin Li def testIndent(self): 3473*8c35d5eeSXin Li self.TestLint('static int noindent;', '') 3474*8c35d5eeSXin Li self.TestLint(' int two_space_indent;', '') 3475*8c35d5eeSXin Li self.TestLint(' int four_space_indent;', '') 3476*8c35d5eeSXin Li self.TestLint(' int one_space_indent;', 3477*8c35d5eeSXin Li 'Weird number of spaces at line-start. ' 3478*8c35d5eeSXin Li 'Are you using a 2-space indent? [whitespace/indent] [3]') 3479*8c35d5eeSXin Li self.TestLint(' int three_space_indent;', 3480*8c35d5eeSXin Li 'Weird number of spaces at line-start. ' 3481*8c35d5eeSXin Li 'Are you using a 2-space indent? [whitespace/indent] [3]') 3482*8c35d5eeSXin Li self.TestLint(' char* one_space_indent = "public:";', 3483*8c35d5eeSXin Li 'Weird number of spaces at line-start. ' 3484*8c35d5eeSXin Li 'Are you using a 2-space indent? [whitespace/indent] [3]') 3485*8c35d5eeSXin Li self.TestLint(' public:', '') 3486*8c35d5eeSXin Li self.TestLint(' protected:', '') 3487*8c35d5eeSXin Li self.TestLint(' private:', '') 3488*8c35d5eeSXin Li self.TestLint(' protected: \\', '') 3489*8c35d5eeSXin Li self.TestLint(' public: \\', '') 3490*8c35d5eeSXin Li self.TestLint(' private: \\', '') 3491*8c35d5eeSXin Li self.TestMultiLineLint( 3492*8c35d5eeSXin Li TrimExtraIndent(""" 3493*8c35d5eeSXin Li class foo { 3494*8c35d5eeSXin Li public slots: 3495*8c35d5eeSXin Li void bar(); 3496*8c35d5eeSXin Li };"""), 3497*8c35d5eeSXin Li 'Weird number of spaces at line-start. ' 3498*8c35d5eeSXin Li 'Are you using a 2-space indent? [whitespace/indent] [3]') 3499*8c35d5eeSXin Li self.TestMultiLineLint( 3500*8c35d5eeSXin Li TrimExtraIndent(''' 3501*8c35d5eeSXin Li static const char kRawString[] = R"(" 3502*8c35d5eeSXin Li ")";'''), 3503*8c35d5eeSXin Li '') 3504*8c35d5eeSXin Li self.TestMultiLineLint( 3505*8c35d5eeSXin Li TrimExtraIndent(''' 3506*8c35d5eeSXin Li KV<Query, 3507*8c35d5eeSXin Li Tuple<TaxonomyId, PetacatCategoryId, double>>'''), 3508*8c35d5eeSXin Li '') 3509*8c35d5eeSXin Li self.TestMultiLineLint( 3510*8c35d5eeSXin Li ' static const char kSingleLineRawString[] = R"(...)";', 3511*8c35d5eeSXin Li 'Weird number of spaces at line-start. ' 3512*8c35d5eeSXin Li 'Are you using a 2-space indent? [whitespace/indent] [3]') 3513*8c35d5eeSXin Li 3514*8c35d5eeSXin Li def testSectionIndent(self): 3515*8c35d5eeSXin Li self.TestMultiLineLint( 3516*8c35d5eeSXin Li """ 3517*8c35d5eeSXin Li class A { 3518*8c35d5eeSXin Li public: // no warning 3519*8c35d5eeSXin Li private: // warning here 3520*8c35d5eeSXin Li };""", 3521*8c35d5eeSXin Li 'private: should be indented +1 space inside class A' 3522*8c35d5eeSXin Li ' [whitespace/indent] [3]') 3523*8c35d5eeSXin Li self.TestMultiLineLint( 3524*8c35d5eeSXin Li """ 3525*8c35d5eeSXin Li class B { 3526*8c35d5eeSXin Li public: // no warning 3527*8c35d5eeSXin Li template<> struct C { 3528*8c35d5eeSXin Li public: // warning here 3529*8c35d5eeSXin Li protected: // no warning 3530*8c35d5eeSXin Li }; 3531*8c35d5eeSXin Li };""", 3532*8c35d5eeSXin Li 'public: should be indented +1 space inside struct C' 3533*8c35d5eeSXin Li ' [whitespace/indent] [3]') 3534*8c35d5eeSXin Li self.TestMultiLineLint( 3535*8c35d5eeSXin Li """ 3536*8c35d5eeSXin Li struct D { 3537*8c35d5eeSXin Li };""", 3538*8c35d5eeSXin Li 'Closing brace should be aligned with beginning of struct D' 3539*8c35d5eeSXin Li ' [whitespace/indent] [3]') 3540*8c35d5eeSXin Li self.TestMultiLineLint( 3541*8c35d5eeSXin Li """ 3542*8c35d5eeSXin Li template<typename E> class F { 3543*8c35d5eeSXin Li };""", 3544*8c35d5eeSXin Li 'Closing brace should be aligned with beginning of class F' 3545*8c35d5eeSXin Li ' [whitespace/indent] [3]') 3546*8c35d5eeSXin Li self.TestMultiLineLint( 3547*8c35d5eeSXin Li """ 3548*8c35d5eeSXin Li class G { 3549*8c35d5eeSXin Li Q_OBJECT 3550*8c35d5eeSXin Li public slots: 3551*8c35d5eeSXin Li signals: 3552*8c35d5eeSXin Li };""", 3553*8c35d5eeSXin Li ['public slots: should be indented +1 space inside class G' 3554*8c35d5eeSXin Li ' [whitespace/indent] [3]', 3555*8c35d5eeSXin Li 'signals: should be indented +1 space inside class G' 3556*8c35d5eeSXin Li ' [whitespace/indent] [3]']) 3557*8c35d5eeSXin Li self.TestMultiLineLint( 3558*8c35d5eeSXin Li """ 3559*8c35d5eeSXin Li class H { 3560*8c35d5eeSXin Li /* comments */ class I { 3561*8c35d5eeSXin Li public: // no warning 3562*8c35d5eeSXin Li private: // warning here 3563*8c35d5eeSXin Li }; 3564*8c35d5eeSXin Li };""", 3565*8c35d5eeSXin Li 'private: should be indented +1 space inside class I' 3566*8c35d5eeSXin Li ' [whitespace/indent] [3]') 3567*8c35d5eeSXin Li self.TestMultiLineLint( 3568*8c35d5eeSXin Li """ 3569*8c35d5eeSXin Li class J 3570*8c35d5eeSXin Li : public ::K { 3571*8c35d5eeSXin Li public: // no warning 3572*8c35d5eeSXin Li protected: // warning here 3573*8c35d5eeSXin Li };""", 3574*8c35d5eeSXin Li 'protected: should be indented +1 space inside class J' 3575*8c35d5eeSXin Li ' [whitespace/indent] [3]') 3576*8c35d5eeSXin Li self.TestMultiLineLint( 3577*8c35d5eeSXin Li """ 3578*8c35d5eeSXin Li class L 3579*8c35d5eeSXin Li : public M, 3580*8c35d5eeSXin Li public ::N { 3581*8c35d5eeSXin Li };""", 3582*8c35d5eeSXin Li '') 3583*8c35d5eeSXin Li self.TestMultiLineLint( 3584*8c35d5eeSXin Li """ 3585*8c35d5eeSXin Li template <class O, 3586*8c35d5eeSXin Li class P, 3587*8c35d5eeSXin Li class Q, 3588*8c35d5eeSXin Li typename R> 3589*8c35d5eeSXin Li static void Func() { 3590*8c35d5eeSXin Li }""", 3591*8c35d5eeSXin Li '') 3592*8c35d5eeSXin Li 3593*8c35d5eeSXin Li def testConditionals(self): 3594*8c35d5eeSXin Li self.TestMultiLineLint( 3595*8c35d5eeSXin Li """ 3596*8c35d5eeSXin Li if (foo) 3597*8c35d5eeSXin Li goto fail; 3598*8c35d5eeSXin Li goto fail;""", 3599*8c35d5eeSXin Li 'If/else bodies with multiple statements require braces' 3600*8c35d5eeSXin Li ' [readability/braces] [4]') 3601*8c35d5eeSXin Li self.TestMultiLineLint( 3602*8c35d5eeSXin Li """ 3603*8c35d5eeSXin Li if (foo) 3604*8c35d5eeSXin Li goto fail; goto fail;""", 3605*8c35d5eeSXin Li 'If/else bodies with multiple statements require braces' 3606*8c35d5eeSXin Li ' [readability/braces] [4]') 3607*8c35d5eeSXin Li self.TestMultiLineLint( 3608*8c35d5eeSXin Li """ 3609*8c35d5eeSXin Li if (foo) 3610*8c35d5eeSXin Li foo; 3611*8c35d5eeSXin Li else 3612*8c35d5eeSXin Li goto fail; 3613*8c35d5eeSXin Li goto fail;""", 3614*8c35d5eeSXin Li 'If/else bodies with multiple statements require braces' 3615*8c35d5eeSXin Li ' [readability/braces] [4]') 3616*8c35d5eeSXin Li self.TestMultiLineLint( 3617*8c35d5eeSXin Li """ 3618*8c35d5eeSXin Li if (foo) goto fail; 3619*8c35d5eeSXin Li goto fail;""", 3620*8c35d5eeSXin Li 'If/else bodies with multiple statements require braces' 3621*8c35d5eeSXin Li ' [readability/braces] [4]') 3622*8c35d5eeSXin Li self.TestMultiLineLint( 3623*8c35d5eeSXin Li """ 3624*8c35d5eeSXin Li if (foo) 3625*8c35d5eeSXin Li if (bar) 3626*8c35d5eeSXin Li baz; 3627*8c35d5eeSXin Li else 3628*8c35d5eeSXin Li qux;""", 3629*8c35d5eeSXin Li 'Else clause should be indented at the same level as if. Ambiguous' 3630*8c35d5eeSXin Li ' nested if/else chains require braces. [readability/braces] [4]') 3631*8c35d5eeSXin Li self.TestMultiLineLint( 3632*8c35d5eeSXin Li """ 3633*8c35d5eeSXin Li if (foo) 3634*8c35d5eeSXin Li if (bar) 3635*8c35d5eeSXin Li baz; 3636*8c35d5eeSXin Li else 3637*8c35d5eeSXin Li qux;""", 3638*8c35d5eeSXin Li 'Else clause should be indented at the same level as if. Ambiguous' 3639*8c35d5eeSXin Li ' nested if/else chains require braces. [readability/braces] [4]') 3640*8c35d5eeSXin Li self.TestMultiLineLint( 3641*8c35d5eeSXin Li """ 3642*8c35d5eeSXin Li if (foo) { 3643*8c35d5eeSXin Li bar; 3644*8c35d5eeSXin Li baz; 3645*8c35d5eeSXin Li } else 3646*8c35d5eeSXin Li qux;""", 3647*8c35d5eeSXin Li 'If an else has a brace on one side, it should have it on both' 3648*8c35d5eeSXin Li ' [readability/braces] [5]') 3649*8c35d5eeSXin Li self.TestMultiLineLint( 3650*8c35d5eeSXin Li """ 3651*8c35d5eeSXin Li if (foo) 3652*8c35d5eeSXin Li bar; 3653*8c35d5eeSXin Li else { 3654*8c35d5eeSXin Li baz; 3655*8c35d5eeSXin Li }""", 3656*8c35d5eeSXin Li 'If an else has a brace on one side, it should have it on both' 3657*8c35d5eeSXin Li ' [readability/braces] [5]') 3658*8c35d5eeSXin Li self.TestMultiLineLint( 3659*8c35d5eeSXin Li """ 3660*8c35d5eeSXin Li if (foo) 3661*8c35d5eeSXin Li bar; 3662*8c35d5eeSXin Li else if (baz) { 3663*8c35d5eeSXin Li qux; 3664*8c35d5eeSXin Li }""", 3665*8c35d5eeSXin Li 'If an else has a brace on one side, it should have it on both' 3666*8c35d5eeSXin Li ' [readability/braces] [5]') 3667*8c35d5eeSXin Li self.TestMultiLineLint( 3668*8c35d5eeSXin Li """ 3669*8c35d5eeSXin Li if (foo) { 3670*8c35d5eeSXin Li bar; 3671*8c35d5eeSXin Li } else if (baz) 3672*8c35d5eeSXin Li qux;""", 3673*8c35d5eeSXin Li 'If an else has a brace on one side, it should have it on both' 3674*8c35d5eeSXin Li ' [readability/braces] [5]') 3675*8c35d5eeSXin Li self.TestMultiLineLint( 3676*8c35d5eeSXin Li """ 3677*8c35d5eeSXin Li if (foo) 3678*8c35d5eeSXin Li goto fail; 3679*8c35d5eeSXin Li bar;""", 3680*8c35d5eeSXin Li '') 3681*8c35d5eeSXin Li self.TestMultiLineLint( 3682*8c35d5eeSXin Li """ 3683*8c35d5eeSXin Li if (foo 3684*8c35d5eeSXin Li && bar) { 3685*8c35d5eeSXin Li baz; 3686*8c35d5eeSXin Li qux; 3687*8c35d5eeSXin Li }""", 3688*8c35d5eeSXin Li '') 3689*8c35d5eeSXin Li self.TestMultiLineLint( 3690*8c35d5eeSXin Li """ 3691*8c35d5eeSXin Li if (foo) 3692*8c35d5eeSXin Li goto 3693*8c35d5eeSXin Li fail;""", 3694*8c35d5eeSXin Li '') 3695*8c35d5eeSXin Li self.TestMultiLineLint( 3696*8c35d5eeSXin Li """ 3697*8c35d5eeSXin Li if (foo) 3698*8c35d5eeSXin Li bar; 3699*8c35d5eeSXin Li else 3700*8c35d5eeSXin Li baz; 3701*8c35d5eeSXin Li qux;""", 3702*8c35d5eeSXin Li '') 3703*8c35d5eeSXin Li self.TestMultiLineLint( 3704*8c35d5eeSXin Li """ 3705*8c35d5eeSXin Li for (;;) { 3706*8c35d5eeSXin Li if (foo) 3707*8c35d5eeSXin Li bar; 3708*8c35d5eeSXin Li else 3709*8c35d5eeSXin Li baz; 3710*8c35d5eeSXin Li }""", 3711*8c35d5eeSXin Li '') 3712*8c35d5eeSXin Li self.TestMultiLineLint( 3713*8c35d5eeSXin Li """ 3714*8c35d5eeSXin Li if (foo) 3715*8c35d5eeSXin Li bar; 3716*8c35d5eeSXin Li else if (baz) 3717*8c35d5eeSXin Li baz;""", 3718*8c35d5eeSXin Li '') 3719*8c35d5eeSXin Li self.TestMultiLineLint( 3720*8c35d5eeSXin Li """ 3721*8c35d5eeSXin Li if (foo) 3722*8c35d5eeSXin Li bar; 3723*8c35d5eeSXin Li else 3724*8c35d5eeSXin Li baz;""", 3725*8c35d5eeSXin Li '') 3726*8c35d5eeSXin Li self.TestMultiLineLint( 3727*8c35d5eeSXin Li """ 3728*8c35d5eeSXin Li if (foo) { 3729*8c35d5eeSXin Li bar; 3730*8c35d5eeSXin Li } else { 3731*8c35d5eeSXin Li baz; 3732*8c35d5eeSXin Li }""", 3733*8c35d5eeSXin Li '') 3734*8c35d5eeSXin Li self.TestMultiLineLint( 3735*8c35d5eeSXin Li """ 3736*8c35d5eeSXin Li if (foo) { 3737*8c35d5eeSXin Li bar; 3738*8c35d5eeSXin Li } else if (baz) { 3739*8c35d5eeSXin Li qux; 3740*8c35d5eeSXin Li }""", 3741*8c35d5eeSXin Li '') 3742*8c35d5eeSXin Li # Note: this is an error for a different reason, but should not trigger the 3743*8c35d5eeSXin Li # single-line if error. 3744*8c35d5eeSXin Li self.TestMultiLineLint( 3745*8c35d5eeSXin Li """ 3746*8c35d5eeSXin Li if (foo) 3747*8c35d5eeSXin Li { 3748*8c35d5eeSXin Li bar; 3749*8c35d5eeSXin Li baz; 3750*8c35d5eeSXin Li }""", 3751*8c35d5eeSXin Li '{ should almost always be at the end of the previous line' 3752*8c35d5eeSXin Li ' [whitespace/braces] [4]') 3753*8c35d5eeSXin Li self.TestMultiLineLint( 3754*8c35d5eeSXin Li """ 3755*8c35d5eeSXin Li if (foo) { \\ 3756*8c35d5eeSXin Li bar; \\ 3757*8c35d5eeSXin Li baz; \\ 3758*8c35d5eeSXin Li }""", 3759*8c35d5eeSXin Li '') 3760*8c35d5eeSXin Li self.TestMultiLineLint( 3761*8c35d5eeSXin Li """ 3762*8c35d5eeSXin Li void foo() { if (bar) baz; }""", 3763*8c35d5eeSXin Li '') 3764*8c35d5eeSXin Li self.TestMultiLineLint( 3765*8c35d5eeSXin Li """ 3766*8c35d5eeSXin Li #if foo 3767*8c35d5eeSXin Li bar; 3768*8c35d5eeSXin Li #else 3769*8c35d5eeSXin Li baz; 3770*8c35d5eeSXin Li qux; 3771*8c35d5eeSXin Li #endif""", 3772*8c35d5eeSXin Li '') 3773*8c35d5eeSXin Li self.TestMultiLineLint( 3774*8c35d5eeSXin Li """void F() { 3775*8c35d5eeSXin Li variable = [] { if (true); }; 3776*8c35d5eeSXin Li variable = 3777*8c35d5eeSXin Li [] { if (true); }; 3778*8c35d5eeSXin Li Call( 3779*8c35d5eeSXin Li [] { if (true); }, 3780*8c35d5eeSXin Li [] { if (true); }); 3781*8c35d5eeSXin Li }""", 3782*8c35d5eeSXin Li '') 3783*8c35d5eeSXin Li 3784*8c35d5eeSXin Li def testTab(self): 3785*8c35d5eeSXin Li self.TestLint('\tint a;', 3786*8c35d5eeSXin Li 'Tab found; better to use spaces [whitespace/tab] [1]') 3787*8c35d5eeSXin Li self.TestLint('int a = 5;\t\t// set a to 5', 3788*8c35d5eeSXin Li 'Tab found; better to use spaces [whitespace/tab] [1]') 3789*8c35d5eeSXin Li 3790*8c35d5eeSXin Li def testParseArguments(self): 3791*8c35d5eeSXin Li old_usage = cpplint._USAGE 3792*8c35d5eeSXin Li old_error_categories = cpplint._ERROR_CATEGORIES 3793*8c35d5eeSXin Li old_output_format = cpplint._cpplint_state.output_format 3794*8c35d5eeSXin Li old_verbose_level = cpplint._cpplint_state.verbose_level 3795*8c35d5eeSXin Li old_headers = cpplint._hpp_headers 3796*8c35d5eeSXin Li old_filters = cpplint._cpplint_state.filters 3797*8c35d5eeSXin Li old_line_length = cpplint._line_length 3798*8c35d5eeSXin Li old_valid_extensions = cpplint._valid_extensions 3799*8c35d5eeSXin Li try: 3800*8c35d5eeSXin Li # Don't print usage during the tests, or filter categories 3801*8c35d5eeSXin Li cpplint._USAGE = '' 3802*8c35d5eeSXin Li cpplint._ERROR_CATEGORIES = '' 3803*8c35d5eeSXin Li 3804*8c35d5eeSXin Li self.assertRaises(SystemExit, cpplint.ParseArguments, []) 3805*8c35d5eeSXin Li self.assertRaises(SystemExit, cpplint.ParseArguments, ['--badopt']) 3806*8c35d5eeSXin Li self.assertRaises(SystemExit, cpplint.ParseArguments, ['--help']) 3807*8c35d5eeSXin Li self.assertRaises(SystemExit, cpplint.ParseArguments, ['--v=0']) 3808*8c35d5eeSXin Li self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter=']) 3809*8c35d5eeSXin Li # This is illegal because all filters must start with + or - 3810*8c35d5eeSXin Li self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter=foo']) 3811*8c35d5eeSXin Li self.assertRaises(SystemExit, cpplint.ParseArguments, 3812*8c35d5eeSXin Li ['--filter=+a,b,-c']) 3813*8c35d5eeSXin Li self.assertRaises(SystemExit, cpplint.ParseArguments, ['--headers']) 3814*8c35d5eeSXin Li 3815*8c35d5eeSXin Li self.assertEquals(['foo.cc'], cpplint.ParseArguments(['foo.cc'])) 3816*8c35d5eeSXin Li self.assertEquals(old_output_format, cpplint._cpplint_state.output_format) 3817*8c35d5eeSXin Li self.assertEquals(old_verbose_level, cpplint._cpplint_state.verbose_level) 3818*8c35d5eeSXin Li 3819*8c35d5eeSXin Li self.assertEquals(['foo.cc'], 3820*8c35d5eeSXin Li cpplint.ParseArguments(['--v=1', 'foo.cc'])) 3821*8c35d5eeSXin Li self.assertEquals(1, cpplint._cpplint_state.verbose_level) 3822*8c35d5eeSXin Li self.assertEquals(['foo.h'], 3823*8c35d5eeSXin Li cpplint.ParseArguments(['--v=3', 'foo.h'])) 3824*8c35d5eeSXin Li self.assertEquals(3, cpplint._cpplint_state.verbose_level) 3825*8c35d5eeSXin Li self.assertEquals(['foo.cpp'], 3826*8c35d5eeSXin Li cpplint.ParseArguments(['--verbose=5', 'foo.cpp'])) 3827*8c35d5eeSXin Li self.assertEquals(5, cpplint._cpplint_state.verbose_level) 3828*8c35d5eeSXin Li self.assertRaises(ValueError, 3829*8c35d5eeSXin Li cpplint.ParseArguments, ['--v=f', 'foo.cc']) 3830*8c35d5eeSXin Li 3831*8c35d5eeSXin Li self.assertEquals(['foo.cc'], 3832*8c35d5eeSXin Li cpplint.ParseArguments(['--output=emacs', 'foo.cc'])) 3833*8c35d5eeSXin Li self.assertEquals('emacs', cpplint._cpplint_state.output_format) 3834*8c35d5eeSXin Li self.assertEquals(['foo.h'], 3835*8c35d5eeSXin Li cpplint.ParseArguments(['--output=vs7', 'foo.h'])) 3836*8c35d5eeSXin Li self.assertEquals('vs7', cpplint._cpplint_state.output_format) 3837*8c35d5eeSXin Li self.assertRaises(SystemExit, 3838*8c35d5eeSXin Li cpplint.ParseArguments, ['--output=blah', 'foo.cc']) 3839*8c35d5eeSXin Li 3840*8c35d5eeSXin Li filt = '-,+whitespace,-whitespace/indent' 3841*8c35d5eeSXin Li self.assertEquals(['foo.h'], 3842*8c35d5eeSXin Li cpplint.ParseArguments(['--filter='+filt, 'foo.h'])) 3843*8c35d5eeSXin Li self.assertEquals(['-', '+whitespace', '-whitespace/indent'], 3844*8c35d5eeSXin Li cpplint._cpplint_state.filters) 3845*8c35d5eeSXin Li 3846*8c35d5eeSXin Li self.assertEquals(['foo.cc', 'foo.h'], 3847*8c35d5eeSXin Li cpplint.ParseArguments(['foo.cc', 'foo.h'])) 3848*8c35d5eeSXin Li 3849*8c35d5eeSXin Li self.assertEqual(['foo.h'], 3850*8c35d5eeSXin Li cpplint.ParseArguments(['--linelength=120', 'foo.h'])) 3851*8c35d5eeSXin Li self.assertEqual(120, cpplint._line_length) 3852*8c35d5eeSXin Li 3853*8c35d5eeSXin Li self.assertEqual(['foo.h'], 3854*8c35d5eeSXin Li cpplint.ParseArguments(['--extensions=hpp,cpp,cpp', 'foo.h'])) 3855*8c35d5eeSXin Li self.assertEqual(set(['hpp', 'cpp']), cpplint._valid_extensions) 3856*8c35d5eeSXin Li 3857*8c35d5eeSXin Li self.assertEqual(set(['h']), cpplint._hpp_headers) # Default value 3858*8c35d5eeSXin Li self.assertEqual(['foo.h'], 3859*8c35d5eeSXin Li cpplint.ParseArguments(['--extensions=cpp,cpp', '--headers=hpp,h', 'foo.h'])) 3860*8c35d5eeSXin Li self.assertEqual(set(['hpp', 'h']), cpplint._hpp_headers) 3861*8c35d5eeSXin Li self.assertEqual(set(['hpp', 'h', 'cpp']), cpplint._valid_extensions) 3862*8c35d5eeSXin Li 3863*8c35d5eeSXin Li finally: 3864*8c35d5eeSXin Li cpplint._USAGE = old_usage 3865*8c35d5eeSXin Li cpplint._ERROR_CATEGORIES = old_error_categories 3866*8c35d5eeSXin Li cpplint._cpplint_state.output_format = old_output_format 3867*8c35d5eeSXin Li cpplint._cpplint_state.verbose_level = old_verbose_level 3868*8c35d5eeSXin Li cpplint._cpplint_state.filters = old_filters 3869*8c35d5eeSXin Li cpplint._line_length = old_line_length 3870*8c35d5eeSXin Li cpplint._valid_extensions = old_valid_extensions 3871*8c35d5eeSXin Li cpplint._hpp_headers = old_headers 3872*8c35d5eeSXin Li 3873*8c35d5eeSXin Li def testLineLength(self): 3874*8c35d5eeSXin Li old_line_length = cpplint._line_length 3875*8c35d5eeSXin Li try: 3876*8c35d5eeSXin Li cpplint._line_length = 80 3877*8c35d5eeSXin Li self.TestLint( 3878*8c35d5eeSXin Li '// H %s' % ('H' * 75), 3879*8c35d5eeSXin Li '') 3880*8c35d5eeSXin Li self.TestLint( 3881*8c35d5eeSXin Li '// H %s' % ('H' * 76), 3882*8c35d5eeSXin Li 'Lines should be <= 80 characters long' 3883*8c35d5eeSXin Li ' [whitespace/line_length] [2]') 3884*8c35d5eeSXin Li cpplint._line_length = 120 3885*8c35d5eeSXin Li self.TestLint( 3886*8c35d5eeSXin Li '// H %s' % ('H' * 115), 3887*8c35d5eeSXin Li '') 3888*8c35d5eeSXin Li self.TestLint( 3889*8c35d5eeSXin Li '// H %s' % ('H' * 116), 3890*8c35d5eeSXin Li 'Lines should be <= 120 characters long' 3891*8c35d5eeSXin Li ' [whitespace/line_length] [2]') 3892*8c35d5eeSXin Li finally: 3893*8c35d5eeSXin Li cpplint._line_length = old_line_length 3894*8c35d5eeSXin Li 3895*8c35d5eeSXin Li def testFilter(self): 3896*8c35d5eeSXin Li old_filters = cpplint._cpplint_state.filters 3897*8c35d5eeSXin Li try: 3898*8c35d5eeSXin Li cpplint._cpplint_state.SetFilters('-,+whitespace,-whitespace/indent') 3899*8c35d5eeSXin Li self.TestLint( 3900*8c35d5eeSXin Li '// Hello there ', 3901*8c35d5eeSXin Li 'Line ends in whitespace. Consider deleting these extra spaces.' 3902*8c35d5eeSXin Li ' [whitespace/end_of_line] [4]') 3903*8c35d5eeSXin Li self.TestLint('int a = (int)1.0;', '') 3904*8c35d5eeSXin Li self.TestLint(' weird opening space', '') 3905*8c35d5eeSXin Li finally: 3906*8c35d5eeSXin Li cpplint._cpplint_state.filters = old_filters 3907*8c35d5eeSXin Li 3908*8c35d5eeSXin Li def testDefaultFilter(self): 3909*8c35d5eeSXin Li default_filters = cpplint._DEFAULT_FILTERS 3910*8c35d5eeSXin Li old_filters = cpplint._cpplint_state.filters 3911*8c35d5eeSXin Li cpplint._DEFAULT_FILTERS = ['-whitespace'] 3912*8c35d5eeSXin Li try: 3913*8c35d5eeSXin Li # Reset filters 3914*8c35d5eeSXin Li cpplint._cpplint_state.SetFilters('') 3915*8c35d5eeSXin Li self.TestLint('// Hello there ', '') 3916*8c35d5eeSXin Li cpplint._cpplint_state.SetFilters('+whitespace/end_of_line') 3917*8c35d5eeSXin Li self.TestLint( 3918*8c35d5eeSXin Li '// Hello there ', 3919*8c35d5eeSXin Li 'Line ends in whitespace. Consider deleting these extra spaces.' 3920*8c35d5eeSXin Li ' [whitespace/end_of_line] [4]') 3921*8c35d5eeSXin Li self.TestLint(' weird opening space', '') 3922*8c35d5eeSXin Li finally: 3923*8c35d5eeSXin Li cpplint._cpplint_state.filters = old_filters 3924*8c35d5eeSXin Li cpplint._DEFAULT_FILTERS = default_filters 3925*8c35d5eeSXin Li 3926*8c35d5eeSXin Li def testDuplicateHeader(self): 3927*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 3928*8c35d5eeSXin Li cpplint.ProcessFileData('path/self.cc', 'cc', 3929*8c35d5eeSXin Li ['// Copyright 2014 Your Company. All Rights Reserved.', 3930*8c35d5eeSXin Li '#include "path/self.h"', 3931*8c35d5eeSXin Li '#include "path/duplicate.h"', 3932*8c35d5eeSXin Li '#include "path/duplicate.h"', 3933*8c35d5eeSXin Li '#ifdef MACRO', 3934*8c35d5eeSXin Li '#include "path/unique.h"', 3935*8c35d5eeSXin Li '#else', 3936*8c35d5eeSXin Li '#include "path/unique.h"', 3937*8c35d5eeSXin Li '#endif', 3938*8c35d5eeSXin Li ''], 3939*8c35d5eeSXin Li error_collector) 3940*8c35d5eeSXin Li self.assertEquals( 3941*8c35d5eeSXin Li ['"path/duplicate.h" already included at path/self.cc:3 ' 3942*8c35d5eeSXin Li '[build/include] [4]'], 3943*8c35d5eeSXin Li error_collector.ResultList()) 3944*8c35d5eeSXin Li 3945*8c35d5eeSXin Li def testUnnamedNamespacesInHeaders(self): 3946*8c35d5eeSXin Li self.TestLanguageRulesCheck( 3947*8c35d5eeSXin Li 'foo.h', 'namespace {', 3948*8c35d5eeSXin Li 'Do not use unnamed namespaces in header files. See' 3949*8c35d5eeSXin Li ' https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces' 3950*8c35d5eeSXin Li ' for more information. [build/namespaces] [4]') 3951*8c35d5eeSXin Li # namespace registration macros are OK. 3952*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo.h', 'namespace { \\', '') 3953*8c35d5eeSXin Li # named namespaces are OK. 3954*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo.h', 'namespace foo {', '') 3955*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo.h', 'namespace foonamespace {', '') 3956*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo.cc', 'namespace {', '') 3957*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo.cc', 'namespace foo {', '') 3958*8c35d5eeSXin Li 3959*8c35d5eeSXin Li def testBuildClass(self): 3960*8c35d5eeSXin Li # Test that the linter can parse to the end of class definitions, 3961*8c35d5eeSXin Li # and that it will report when it can't. 3962*8c35d5eeSXin Li # Use multi-line linter because it performs the ClassState check. 3963*8c35d5eeSXin Li self.TestMultiLineLint( 3964*8c35d5eeSXin Li 'class Foo {', 3965*8c35d5eeSXin Li 'Failed to find complete declaration of class Foo' 3966*8c35d5eeSXin Li ' [build/class] [5]') 3967*8c35d5eeSXin Li # Do the same for namespaces 3968*8c35d5eeSXin Li self.TestMultiLineLint( 3969*8c35d5eeSXin Li 'namespace Foo {', 3970*8c35d5eeSXin Li 'Failed to find complete declaration of namespace Foo' 3971*8c35d5eeSXin Li ' [build/namespaces] [5]') 3972*8c35d5eeSXin Li # Don't warn on forward declarations of various types. 3973*8c35d5eeSXin Li self.TestMultiLineLint( 3974*8c35d5eeSXin Li 'class Foo;', 3975*8c35d5eeSXin Li '') 3976*8c35d5eeSXin Li self.TestMultiLineLint( 3977*8c35d5eeSXin Li """struct Foo* 3978*8c35d5eeSXin Li foo = NewFoo();""", 3979*8c35d5eeSXin Li '') 3980*8c35d5eeSXin Li # Test preprocessor. 3981*8c35d5eeSXin Li self.TestMultiLineLint( 3982*8c35d5eeSXin Li """#ifdef DERIVE_FROM_GOO 3983*8c35d5eeSXin Li struct Foo : public Goo { 3984*8c35d5eeSXin Li #else 3985*8c35d5eeSXin Li struct Foo : public Hoo { 3986*8c35d5eeSXin Li #endif 3987*8c35d5eeSXin Li };""", 3988*8c35d5eeSXin Li '') 3989*8c35d5eeSXin Li self.TestMultiLineLint( 3990*8c35d5eeSXin Li """ 3991*8c35d5eeSXin Li class Foo 3992*8c35d5eeSXin Li #ifdef DERIVE_FROM_GOO 3993*8c35d5eeSXin Li : public Goo { 3994*8c35d5eeSXin Li #else 3995*8c35d5eeSXin Li : public Hoo { 3996*8c35d5eeSXin Li #endif 3997*8c35d5eeSXin Li };""", 3998*8c35d5eeSXin Li '') 3999*8c35d5eeSXin Li # Test incomplete class 4000*8c35d5eeSXin Li self.TestMultiLineLint( 4001*8c35d5eeSXin Li 'class Foo {', 4002*8c35d5eeSXin Li 'Failed to find complete declaration of class Foo' 4003*8c35d5eeSXin Li ' [build/class] [5]') 4004*8c35d5eeSXin Li 4005*8c35d5eeSXin Li def testBuildEndComment(self): 4006*8c35d5eeSXin Li # The crosstool compiler we currently use will fail to compile the 4007*8c35d5eeSXin Li # code in this test, so we might consider removing the lint check. 4008*8c35d5eeSXin Li self.TestMultiLineLint( 4009*8c35d5eeSXin Li """#if 0 4010*8c35d5eeSXin Li #endif Not a comment""", 4011*8c35d5eeSXin Li 'Uncommented text after #endif is non-standard. Use a comment.' 4012*8c35d5eeSXin Li ' [build/endif_comment] [5]') 4013*8c35d5eeSXin Li 4014*8c35d5eeSXin Li def testBuildForwardDecl(self): 4015*8c35d5eeSXin Li # The crosstool compiler we currently use will fail to compile the 4016*8c35d5eeSXin Li # code in this test, so we might consider removing the lint check. 4017*8c35d5eeSXin Li self.TestLint('class Foo::Goo;', 4018*8c35d5eeSXin Li 'Inner-style forward declarations are invalid.' 4019*8c35d5eeSXin Li ' Remove this line.' 4020*8c35d5eeSXin Li ' [build/forward_decl] [5]') 4021*8c35d5eeSXin Li 4022*8c35d5eeSXin Li def GetBuildHeaderGuardPreprocessorSymbol(self, file_path): 4023*8c35d5eeSXin Li # Figure out the expected header guard by processing an empty file. 4024*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4025*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'h', [], error_collector) 4026*8c35d5eeSXin Li for error in error_collector.ResultList(): 4027*8c35d5eeSXin Li matched = re.search( 4028*8c35d5eeSXin Li 'No #ifndef header guard found, suggested CPP variable is: ' 4029*8c35d5eeSXin Li '([A-Z0-9_]+)', 4030*8c35d5eeSXin Li error) 4031*8c35d5eeSXin Li if matched is not None: 4032*8c35d5eeSXin Li return matched.group(1) 4033*8c35d5eeSXin Li 4034*8c35d5eeSXin Li def testBuildHeaderGuard(self): 4035*8c35d5eeSXin Li file_path = 'mydir/foo.h' 4036*8c35d5eeSXin Li expected_guard = self.GetBuildHeaderGuardPreprocessorSymbol(file_path) 4037*8c35d5eeSXin Li self.assertTrue(re.search('MYDIR_FOO_H_$', expected_guard)) 4038*8c35d5eeSXin Li 4039*8c35d5eeSXin Li # No guard at all: expect one error. 4040*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4041*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'h', [], error_collector) 4042*8c35d5eeSXin Li self.assertEquals( 4043*8c35d5eeSXin Li 1, 4044*8c35d5eeSXin Li error_collector.ResultList().count( 4045*8c35d5eeSXin Li 'No #ifndef header guard found, suggested CPP variable is: %s' 4046*8c35d5eeSXin Li ' [build/header_guard] [5]' % expected_guard), 4047*8c35d5eeSXin Li error_collector.ResultList()) 4048*8c35d5eeSXin Li 4049*8c35d5eeSXin Li # No header guard, but the error is suppressed. 4050*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4051*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'h', 4052*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 4053*8c35d5eeSXin Li '// NOLINT(build/header_guard)', ''], 4054*8c35d5eeSXin Li error_collector) 4055*8c35d5eeSXin Li self.assertEquals([], error_collector.ResultList()) 4056*8c35d5eeSXin Li 4057*8c35d5eeSXin Li # Wrong guard 4058*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4059*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'h', 4060*8c35d5eeSXin Li ['#ifndef FOO_H', '#define FOO_H'], error_collector) 4061*8c35d5eeSXin Li self.assertEquals( 4062*8c35d5eeSXin Li 1, 4063*8c35d5eeSXin Li error_collector.ResultList().count( 4064*8c35d5eeSXin Li '#ifndef header guard has wrong style, please use: %s' 4065*8c35d5eeSXin Li ' [build/header_guard] [5]' % expected_guard), 4066*8c35d5eeSXin Li error_collector.ResultList()) 4067*8c35d5eeSXin Li 4068*8c35d5eeSXin Li # No define 4069*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4070*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'h', 4071*8c35d5eeSXin Li ['#ifndef %s' % expected_guard], error_collector) 4072*8c35d5eeSXin Li self.assertEquals( 4073*8c35d5eeSXin Li 1, 4074*8c35d5eeSXin Li error_collector.ResultList().count( 4075*8c35d5eeSXin Li 'No #ifndef header guard found, suggested CPP variable is: %s' 4076*8c35d5eeSXin Li ' [build/header_guard] [5]' % expected_guard), 4077*8c35d5eeSXin Li error_collector.ResultList()) 4078*8c35d5eeSXin Li 4079*8c35d5eeSXin Li # Mismatched define 4080*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4081*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'h', 4082*8c35d5eeSXin Li ['#ifndef %s' % expected_guard, 4083*8c35d5eeSXin Li '#define FOO_H'], 4084*8c35d5eeSXin Li error_collector) 4085*8c35d5eeSXin Li self.assertEquals( 4086*8c35d5eeSXin Li 1, 4087*8c35d5eeSXin Li error_collector.ResultList().count( 4088*8c35d5eeSXin Li 'No #ifndef header guard found, suggested CPP variable is: %s' 4089*8c35d5eeSXin Li ' [build/header_guard] [5]' % expected_guard), 4090*8c35d5eeSXin Li error_collector.ResultList()) 4091*8c35d5eeSXin Li 4092*8c35d5eeSXin Li # No endif 4093*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4094*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'h', 4095*8c35d5eeSXin Li ['#ifndef %s' % expected_guard, 4096*8c35d5eeSXin Li '#define %s' % expected_guard, 4097*8c35d5eeSXin Li ''], 4098*8c35d5eeSXin Li error_collector) 4099*8c35d5eeSXin Li self.assertEquals( 4100*8c35d5eeSXin Li 1, 4101*8c35d5eeSXin Li error_collector.ResultList().count( 4102*8c35d5eeSXin Li '#endif line should be "#endif // %s"' 4103*8c35d5eeSXin Li ' [build/header_guard] [5]' % expected_guard), 4104*8c35d5eeSXin Li error_collector.ResultList()) 4105*8c35d5eeSXin Li 4106*8c35d5eeSXin Li # Commentless endif 4107*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4108*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'h', 4109*8c35d5eeSXin Li ['#ifndef %s' % expected_guard, 4110*8c35d5eeSXin Li '#define %s' % expected_guard, 4111*8c35d5eeSXin Li '#endif'], 4112*8c35d5eeSXin Li error_collector) 4113*8c35d5eeSXin Li self.assertEquals( 4114*8c35d5eeSXin Li 1, 4115*8c35d5eeSXin Li error_collector.ResultList().count( 4116*8c35d5eeSXin Li '#endif line should be "#endif // %s"' 4117*8c35d5eeSXin Li ' [build/header_guard] [5]' % expected_guard), 4118*8c35d5eeSXin Li error_collector.ResultList()) 4119*8c35d5eeSXin Li 4120*8c35d5eeSXin Li # Commentless endif for old-style guard 4121*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4122*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'h', 4123*8c35d5eeSXin Li ['#ifndef %s_' % expected_guard, 4124*8c35d5eeSXin Li '#define %s_' % expected_guard, 4125*8c35d5eeSXin Li '#endif'], 4126*8c35d5eeSXin Li error_collector) 4127*8c35d5eeSXin Li self.assertEquals( 4128*8c35d5eeSXin Li 1, 4129*8c35d5eeSXin Li error_collector.ResultList().count( 4130*8c35d5eeSXin Li '#endif line should be "#endif // %s"' 4131*8c35d5eeSXin Li ' [build/header_guard] [5]' % expected_guard), 4132*8c35d5eeSXin Li error_collector.ResultList()) 4133*8c35d5eeSXin Li 4134*8c35d5eeSXin Li # No header guard errors 4135*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4136*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'h', 4137*8c35d5eeSXin Li ['#ifndef %s' % expected_guard, 4138*8c35d5eeSXin Li '#define %s' % expected_guard, 4139*8c35d5eeSXin Li '#endif // %s' % expected_guard], 4140*8c35d5eeSXin Li error_collector) 4141*8c35d5eeSXin Li for line in error_collector.ResultList(): 4142*8c35d5eeSXin Li if line.find('build/header_guard') != -1: 4143*8c35d5eeSXin Li self.fail('Unexpected error: %s' % line) 4144*8c35d5eeSXin Li 4145*8c35d5eeSXin Li # No header guard errors for old-style guard 4146*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4147*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'h', 4148*8c35d5eeSXin Li ['#ifndef %s_' % expected_guard, 4149*8c35d5eeSXin Li '#define %s_' % expected_guard, 4150*8c35d5eeSXin Li '#endif // %s_' % expected_guard], 4151*8c35d5eeSXin Li error_collector) 4152*8c35d5eeSXin Li for line in error_collector.ResultList(): 4153*8c35d5eeSXin Li if line.find('build/header_guard') != -1: 4154*8c35d5eeSXin Li self.fail('Unexpected error: %s' % line) 4155*8c35d5eeSXin Li 4156*8c35d5eeSXin Li old_verbose_level = cpplint._cpplint_state.verbose_level 4157*8c35d5eeSXin Li try: 4158*8c35d5eeSXin Li cpplint._cpplint_state.verbose_level = 0 4159*8c35d5eeSXin Li # Warn on old-style guard if verbosity is 0. 4160*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4161*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'h', 4162*8c35d5eeSXin Li ['#ifndef %s_' % expected_guard, 4163*8c35d5eeSXin Li '#define %s_' % expected_guard, 4164*8c35d5eeSXin Li '#endif // %s_' % expected_guard], 4165*8c35d5eeSXin Li error_collector) 4166*8c35d5eeSXin Li self.assertEquals( 4167*8c35d5eeSXin Li 1, 4168*8c35d5eeSXin Li error_collector.ResultList().count( 4169*8c35d5eeSXin Li '#ifndef header guard has wrong style, please use: %s' 4170*8c35d5eeSXin Li ' [build/header_guard] [0]' % expected_guard), 4171*8c35d5eeSXin Li error_collector.ResultList()) 4172*8c35d5eeSXin Li finally: 4173*8c35d5eeSXin Li cpplint._cpplint_state.verbose_level = old_verbose_level 4174*8c35d5eeSXin Li 4175*8c35d5eeSXin Li # Completely incorrect header guard 4176*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4177*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'h', 4178*8c35d5eeSXin Li ['#ifndef FOO', 4179*8c35d5eeSXin Li '#define FOO', 4180*8c35d5eeSXin Li '#endif // FOO'], 4181*8c35d5eeSXin Li error_collector) 4182*8c35d5eeSXin Li self.assertEquals( 4183*8c35d5eeSXin Li 1, 4184*8c35d5eeSXin Li error_collector.ResultList().count( 4185*8c35d5eeSXin Li '#ifndef header guard has wrong style, please use: %s' 4186*8c35d5eeSXin Li ' [build/header_guard] [5]' % expected_guard), 4187*8c35d5eeSXin Li error_collector.ResultList()) 4188*8c35d5eeSXin Li self.assertEquals( 4189*8c35d5eeSXin Li 1, 4190*8c35d5eeSXin Li error_collector.ResultList().count( 4191*8c35d5eeSXin Li '#endif line should be "#endif // %s"' 4192*8c35d5eeSXin Li ' [build/header_guard] [5]' % expected_guard), 4193*8c35d5eeSXin Li error_collector.ResultList()) 4194*8c35d5eeSXin Li 4195*8c35d5eeSXin Li # incorrect header guard with nolint 4196*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4197*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'h', 4198*8c35d5eeSXin Li ['#ifndef FOO // NOLINT', 4199*8c35d5eeSXin Li '#define FOO', 4200*8c35d5eeSXin Li '#endif // FOO NOLINT'], 4201*8c35d5eeSXin Li error_collector) 4202*8c35d5eeSXin Li self.assertEquals( 4203*8c35d5eeSXin Li 0, 4204*8c35d5eeSXin Li error_collector.ResultList().count( 4205*8c35d5eeSXin Li '#ifndef header guard has wrong style, please use: %s' 4206*8c35d5eeSXin Li ' [build/header_guard] [5]' % expected_guard), 4207*8c35d5eeSXin Li error_collector.ResultList()) 4208*8c35d5eeSXin Li self.assertEquals( 4209*8c35d5eeSXin Li 0, 4210*8c35d5eeSXin Li error_collector.ResultList().count( 4211*8c35d5eeSXin Li '#endif line should be "#endif // %s"' 4212*8c35d5eeSXin Li ' [build/header_guard] [5]' % expected_guard), 4213*8c35d5eeSXin Li error_collector.ResultList()) 4214*8c35d5eeSXin Li 4215*8c35d5eeSXin Li # Special case for flymake 4216*8c35d5eeSXin Li for test_file in ['mydir/foo_flymake.h', 'mydir/.flymake/foo.h']: 4217*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4218*8c35d5eeSXin Li cpplint.ProcessFileData(test_file, 'h', 4219*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', ''], 4220*8c35d5eeSXin Li error_collector) 4221*8c35d5eeSXin Li self.assertEquals( 4222*8c35d5eeSXin Li 1, 4223*8c35d5eeSXin Li error_collector.ResultList().count( 4224*8c35d5eeSXin Li 'No #ifndef header guard found, suggested CPP variable is: %s' 4225*8c35d5eeSXin Li ' [build/header_guard] [5]' % expected_guard), 4226*8c35d5eeSXin Li error_collector.ResultList()) 4227*8c35d5eeSXin Li 4228*8c35d5eeSXin Li def testBuildHeaderGuardWithRoot(self): 4229*8c35d5eeSXin Li # note: Tested file paths must be real, otherwise 4230*8c35d5eeSXin Li # the repository name lookup will fail. 4231*8c35d5eeSXin Li file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 4232*8c35d5eeSXin Li 'cpplint_test_header.h') 4233*8c35d5eeSXin Li file_info = cpplint.FileInfo(file_path) 4234*8c35d5eeSXin Li if file_info.FullName() == file_info.RepositoryName(): 4235*8c35d5eeSXin Li # When FileInfo cannot deduce the root directory of the repository, 4236*8c35d5eeSXin Li # FileInfo.RepositoryName returns the same value as FileInfo.FullName. 4237*8c35d5eeSXin Li # This can happen when this source file was obtained without .svn or 4238*8c35d5eeSXin Li # .git directory. (e.g. using 'svn export' or 'git archive'). 4239*8c35d5eeSXin Li # Skip this test in such a case because --root flag makes sense only 4240*8c35d5eeSXin Li # when the root directory of the repository is properly deduced. 4241*8c35d5eeSXin Li return 4242*8c35d5eeSXin Li 4243*8c35d5eeSXin Li self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_', 4244*8c35d5eeSXin Li cpplint.GetHeaderGuardCPPVariable(file_path)) 4245*8c35d5eeSXin Li # 4246*8c35d5eeSXin Li # test --root flags: 4247*8c35d5eeSXin Li # this changes the cpp header guard prefix 4248*8c35d5eeSXin Li # 4249*8c35d5eeSXin Li 4250*8c35d5eeSXin Li # left-strip the header guard by using a root dir inside of the repo dir. 4251*8c35d5eeSXin Li # relative directory 4252*8c35d5eeSXin Li cpplint._root = 'cpplint' 4253*8c35d5eeSXin Li self.assertEquals('CPPLINT_TEST_HEADER_H_', 4254*8c35d5eeSXin Li cpplint.GetHeaderGuardCPPVariable(file_path)) 4255*8c35d5eeSXin Li 4256*8c35d5eeSXin Li nested_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 4257*8c35d5eeSXin Li os.path.join('nested', 4258*8c35d5eeSXin Li 'cpplint_test_header.h')) 4259*8c35d5eeSXin Li cpplint._root = os.path.join('cpplint', 'nested') 4260*8c35d5eeSXin Li actual = cpplint.GetHeaderGuardCPPVariable(nested_file_path) 4261*8c35d5eeSXin Li self.assertEquals('CPPLINT_TEST_HEADER_H_', 4262*8c35d5eeSXin Li actual) 4263*8c35d5eeSXin Li 4264*8c35d5eeSXin Li # absolute directory 4265*8c35d5eeSXin Li # (note that CPPLINT.cfg root=setting is always made absolute) 4266*8c35d5eeSXin Li cpplint._root = os.path.join(os.path.dirname(os.path.abspath(__file__))) 4267*8c35d5eeSXin Li self.assertEquals('CPPLINT_TEST_HEADER_H_', 4268*8c35d5eeSXin Li cpplint.GetHeaderGuardCPPVariable(file_path)) 4269*8c35d5eeSXin Li 4270*8c35d5eeSXin Li nested_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 4271*8c35d5eeSXin Li os.path.join('nested', 4272*8c35d5eeSXin Li 'cpplint_test_header.h')) 4273*8c35d5eeSXin Li cpplint._root = os.path.join(os.path.dirname(os.path.abspath(__file__)), 4274*8c35d5eeSXin Li 'nested') 4275*8c35d5eeSXin Li self.assertEquals('CPPLINT_TEST_HEADER_H_', 4276*8c35d5eeSXin Li cpplint.GetHeaderGuardCPPVariable(nested_file_path)) 4277*8c35d5eeSXin Li 4278*8c35d5eeSXin Li # --root flag is ignored if an non-existent directory is specified. 4279*8c35d5eeSXin Li cpplint._root = 'NON_EXISTENT_DIR' 4280*8c35d5eeSXin Li self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_', 4281*8c35d5eeSXin Li cpplint.GetHeaderGuardCPPVariable(file_path)) 4282*8c35d5eeSXin Li 4283*8c35d5eeSXin Li # prepend to the header guard by using a root dir that is more outer 4284*8c35d5eeSXin Li # than the repo dir 4285*8c35d5eeSXin Li 4286*8c35d5eeSXin Li # (using absolute paths) 4287*8c35d5eeSXin Li # (note that CPPLINT.cfg root=setting is always made absolute) 4288*8c35d5eeSXin Li this_files_path = os.path.dirname(os.path.abspath(__file__)) 4289*8c35d5eeSXin Li (styleguide_path, this_files_dir) = os.path.split(this_files_path) 4290*8c35d5eeSXin Li (styleguide_parent_path, styleguide_dir_name) = os.path.split(styleguide_path) 4291*8c35d5eeSXin Li # parent dir of styleguide 4292*8c35d5eeSXin Li cpplint._root = styleguide_parent_path 4293*8c35d5eeSXin Li self.assertIsNotNone(styleguide_parent_path) 4294*8c35d5eeSXin Li # do not hardcode the 'styleguide' repository name, it could be anything. 4295*8c35d5eeSXin Li expected_prefix = re.sub(r'[^a-zA-Z0-9]', '_', styleguide_dir_name).upper() + '_' 4296*8c35d5eeSXin Li # do not have 'styleguide' repo in '/' 4297*8c35d5eeSXin Li self.assertEquals('%sCPPLINT_CPPLINT_TEST_HEADER_H_' %(expected_prefix), 4298*8c35d5eeSXin Li cpplint.GetHeaderGuardCPPVariable(file_path)) 4299*8c35d5eeSXin Li 4300*8c35d5eeSXin Li # To run the 'relative path' tests, we must be in the directory of this test file. 4301*8c35d5eeSXin Li cur_dir = os.getcwd() 4302*8c35d5eeSXin Li os.chdir(this_files_path) 4303*8c35d5eeSXin Li 4304*8c35d5eeSXin Li # (using relative paths) 4305*8c35d5eeSXin Li styleguide_rel_path = os.path.relpath(styleguide_path, this_files_path) 4306*8c35d5eeSXin Li # '..' 4307*8c35d5eeSXin Li cpplint._root = styleguide_rel_path 4308*8c35d5eeSXin Li self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_', 4309*8c35d5eeSXin Li cpplint.GetHeaderGuardCPPVariable(file_path)) 4310*8c35d5eeSXin Li 4311*8c35d5eeSXin Li styleguide_rel_path = os.path.relpath(styleguide_parent_path, 4312*8c35d5eeSXin Li this_files_path) # '../..' 4313*8c35d5eeSXin Li cpplint._root = styleguide_rel_path 4314*8c35d5eeSXin Li self.assertEquals('%sCPPLINT_CPPLINT_TEST_HEADER_H_' %(expected_prefix), 4315*8c35d5eeSXin Li cpplint.GetHeaderGuardCPPVariable(file_path)) 4316*8c35d5eeSXin Li 4317*8c35d5eeSXin Li cpplint._root = None 4318*8c35d5eeSXin Li 4319*8c35d5eeSXin Li # Restore previous CWD. 4320*8c35d5eeSXin Li os.chdir(cur_dir) 4321*8c35d5eeSXin Li 4322*8c35d5eeSXin Li def testPathSplitToList(self): 4323*8c35d5eeSXin Li self.assertEquals([''], 4324*8c35d5eeSXin Li cpplint.PathSplitToList(os.path.join(''))) 4325*8c35d5eeSXin Li 4326*8c35d5eeSXin Li self.assertEquals(['.'], 4327*8c35d5eeSXin Li cpplint.PathSplitToList(os.path.join('.'))) 4328*8c35d5eeSXin Li 4329*8c35d5eeSXin Li self.assertEquals(['..'], 4330*8c35d5eeSXin Li cpplint.PathSplitToList(os.path.join('..'))) 4331*8c35d5eeSXin Li 4332*8c35d5eeSXin Li self.assertEquals(['..', 'a', 'b'], 4333*8c35d5eeSXin Li cpplint.PathSplitToList(os.path.join('..', 'a', 'b'))) 4334*8c35d5eeSXin Li 4335*8c35d5eeSXin Li self.assertEquals(['a', 'b', 'c', 'd'], 4336*8c35d5eeSXin Li cpplint.PathSplitToList(os.path.join('a', 'b', 'c', 'd'))) 4337*8c35d5eeSXin Li 4338*8c35d5eeSXin Li def testBuildInclude(self): 4339*8c35d5eeSXin Li # Test that include statements have slashes in them. 4340*8c35d5eeSXin Li self.TestLint('#include "foo.h"', 4341*8c35d5eeSXin Li 'Include the directory when naming .h files' 4342*8c35d5eeSXin Li ' [build/include] [4]') 4343*8c35d5eeSXin Li self.TestLint('#include "Python.h"', '') 4344*8c35d5eeSXin Li self.TestLint('#include "lua.h"', '') 4345*8c35d5eeSXin Li 4346*8c35d5eeSXin Li def testBuildPrintfFormat(self): 4347*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4348*8c35d5eeSXin Li cpplint.ProcessFileData( 4349*8c35d5eeSXin Li 'foo.cc', 'cc', 4350*8c35d5eeSXin Li [r'printf("\%%d", value);', 4351*8c35d5eeSXin Li r'snprintf(buffer, sizeof(buffer), "\[%d", value);', 4352*8c35d5eeSXin Li r'fprintf(file, "\(%d", value);', 4353*8c35d5eeSXin Li r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);'], 4354*8c35d5eeSXin Li error_collector) 4355*8c35d5eeSXin Li self.assertEquals( 4356*8c35d5eeSXin Li 4, 4357*8c35d5eeSXin Li error_collector.Results().count( 4358*8c35d5eeSXin Li '%, [, (, and { are undefined character escapes. Unescape them.' 4359*8c35d5eeSXin Li ' [build/printf_format] [3]')) 4360*8c35d5eeSXin Li 4361*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4362*8c35d5eeSXin Li cpplint.ProcessFileData( 4363*8c35d5eeSXin Li 'foo.cc', 'cc', 4364*8c35d5eeSXin Li ['// Copyright 2014 Your Company.', 4365*8c35d5eeSXin Li r'printf("\\%%%d", value);', 4366*8c35d5eeSXin Li r'printf(R"(\[)");', 4367*8c35d5eeSXin Li r'printf(R"(\[%s)", R"(\])");', 4368*8c35d5eeSXin Li ''], 4369*8c35d5eeSXin Li error_collector) 4370*8c35d5eeSXin Li self.assertEquals('', error_collector.Results()) 4371*8c35d5eeSXin Li 4372*8c35d5eeSXin Li def testRuntimePrintfFormat(self): 4373*8c35d5eeSXin Li self.TestLint( 4374*8c35d5eeSXin Li r'fprintf(file, "%q", value);', 4375*8c35d5eeSXin Li '%q in format strings is deprecated. Use %ll instead.' 4376*8c35d5eeSXin Li ' [runtime/printf_format] [3]') 4377*8c35d5eeSXin Li 4378*8c35d5eeSXin Li self.TestLint( 4379*8c35d5eeSXin Li r'aprintf(file, "The number is %12q", value);', 4380*8c35d5eeSXin Li '%q in format strings is deprecated. Use %ll instead.' 4381*8c35d5eeSXin Li ' [runtime/printf_format] [3]') 4382*8c35d5eeSXin Li 4383*8c35d5eeSXin Li self.TestLint( 4384*8c35d5eeSXin Li r'printf(file, "The number is" "%-12q", value);', 4385*8c35d5eeSXin Li '%q in format strings is deprecated. Use %ll instead.' 4386*8c35d5eeSXin Li ' [runtime/printf_format] [3]') 4387*8c35d5eeSXin Li 4388*8c35d5eeSXin Li self.TestLint( 4389*8c35d5eeSXin Li r'printf(file, "The number is" "%+12q", value);', 4390*8c35d5eeSXin Li '%q in format strings is deprecated. Use %ll instead.' 4391*8c35d5eeSXin Li ' [runtime/printf_format] [3]') 4392*8c35d5eeSXin Li 4393*8c35d5eeSXin Li self.TestLint( 4394*8c35d5eeSXin Li r'printf(file, "The number is" "% 12q", value);', 4395*8c35d5eeSXin Li '%q in format strings is deprecated. Use %ll instead.' 4396*8c35d5eeSXin Li ' [runtime/printf_format] [3]') 4397*8c35d5eeSXin Li 4398*8c35d5eeSXin Li self.TestLint( 4399*8c35d5eeSXin Li r'snprintf(file, "Never mix %d and %1$d parameters!", value);', 4400*8c35d5eeSXin Li '%N$ formats are unconventional. Try rewriting to avoid them.' 4401*8c35d5eeSXin Li ' [runtime/printf_format] [2]') 4402*8c35d5eeSXin Li 4403*8c35d5eeSXin Li def TestLintLogCodeOnError(self, code, expected_message): 4404*8c35d5eeSXin Li # Special TestLint which logs the input code on error. 4405*8c35d5eeSXin Li result = self.PerformSingleLineLint(code) 4406*8c35d5eeSXin Li if result != expected_message: 4407*8c35d5eeSXin Li self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"' 4408*8c35d5eeSXin Li % (code, result, expected_message)) 4409*8c35d5eeSXin Li 4410*8c35d5eeSXin Li def testBuildStorageClass(self): 4411*8c35d5eeSXin Li qualifiers = [None, 'const', 'volatile'] 4412*8c35d5eeSXin Li signs = [None, 'signed', 'unsigned'] 4413*8c35d5eeSXin Li types = ['void', 'char', 'int', 'float', 'double', 4414*8c35d5eeSXin Li 'schar', 'int8', 'uint8', 'int16', 'uint16', 4415*8c35d5eeSXin Li 'int32', 'uint32', 'int64', 'uint64'] 4416*8c35d5eeSXin Li storage_classes = ['extern', 'register', 'static', 'typedef'] 4417*8c35d5eeSXin Li 4418*8c35d5eeSXin Li build_storage_class_error_message = ( 4419*8c35d5eeSXin Li 'Storage-class specifier (static, extern, typedef, etc) should be ' 4420*8c35d5eeSXin Li 'at the beginning of the declaration. [build/storage_class] [5]') 4421*8c35d5eeSXin Li 4422*8c35d5eeSXin Li # Some explicit cases. Legal in C++, deprecated in C99. 4423*8c35d5eeSXin Li self.TestLint('const int static foo = 5;', 4424*8c35d5eeSXin Li build_storage_class_error_message) 4425*8c35d5eeSXin Li 4426*8c35d5eeSXin Li self.TestLint('char static foo;', 4427*8c35d5eeSXin Li build_storage_class_error_message) 4428*8c35d5eeSXin Li 4429*8c35d5eeSXin Li self.TestLint('double const static foo = 2.0;', 4430*8c35d5eeSXin Li build_storage_class_error_message) 4431*8c35d5eeSXin Li 4432*8c35d5eeSXin Li self.TestLint('uint64 typedef unsigned_long_long;', 4433*8c35d5eeSXin Li build_storage_class_error_message) 4434*8c35d5eeSXin Li 4435*8c35d5eeSXin Li self.TestLint('int register foo = 0;', 4436*8c35d5eeSXin Li build_storage_class_error_message) 4437*8c35d5eeSXin Li 4438*8c35d5eeSXin Li # Since there are a very large number of possibilities, randomly 4439*8c35d5eeSXin Li # construct declarations. 4440*8c35d5eeSXin Li # Make sure that the declaration is logged if there's an error. 4441*8c35d5eeSXin Li # Seed generator with an integer for absolute reproducibility. 4442*8c35d5eeSXin Li random.seed(25) 4443*8c35d5eeSXin Li for unused_i in range(10): 4444*8c35d5eeSXin Li # Build up random list of non-storage-class declaration specs. 4445*8c35d5eeSXin Li other_decl_specs = [random.choice(qualifiers), random.choice(signs), 4446*8c35d5eeSXin Li random.choice(types)] 4447*8c35d5eeSXin Li # remove None 4448*8c35d5eeSXin Li other_decl_specs = [x for x in other_decl_specs if x is not None] 4449*8c35d5eeSXin Li 4450*8c35d5eeSXin Li # shuffle 4451*8c35d5eeSXin Li random.shuffle(other_decl_specs) 4452*8c35d5eeSXin Li 4453*8c35d5eeSXin Li # insert storage class after the first 4454*8c35d5eeSXin Li storage_class = random.choice(storage_classes) 4455*8c35d5eeSXin Li insertion_point = random.randint(1, len(other_decl_specs)) 4456*8c35d5eeSXin Li decl_specs = (other_decl_specs[0:insertion_point] 4457*8c35d5eeSXin Li + [storage_class] 4458*8c35d5eeSXin Li + other_decl_specs[insertion_point:]) 4459*8c35d5eeSXin Li 4460*8c35d5eeSXin Li self.TestLintLogCodeOnError( 4461*8c35d5eeSXin Li ' '.join(decl_specs) + ';', 4462*8c35d5eeSXin Li build_storage_class_error_message) 4463*8c35d5eeSXin Li 4464*8c35d5eeSXin Li # but no error if storage class is first 4465*8c35d5eeSXin Li self.TestLintLogCodeOnError( 4466*8c35d5eeSXin Li storage_class + ' ' + ' '.join(other_decl_specs), 4467*8c35d5eeSXin Li '') 4468*8c35d5eeSXin Li 4469*8c35d5eeSXin Li def testLegalCopyright(self): 4470*8c35d5eeSXin Li legal_copyright_message = ( 4471*8c35d5eeSXin Li 'No copyright message found. ' 4472*8c35d5eeSXin Li 'You should have a line: "Copyright [year] <Copyright Owner>"' 4473*8c35d5eeSXin Li ' [legal/copyright] [5]') 4474*8c35d5eeSXin Li 4475*8c35d5eeSXin Li copyright_line = '// Copyright 2014 Google Inc. All Rights Reserved.' 4476*8c35d5eeSXin Li 4477*8c35d5eeSXin Li file_path = 'mydir/googleclient/foo.cc' 4478*8c35d5eeSXin Li 4479*8c35d5eeSXin Li # There should be a copyright message in the first 10 lines 4480*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4481*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'cc', [], error_collector) 4482*8c35d5eeSXin Li self.assertEquals( 4483*8c35d5eeSXin Li 1, 4484*8c35d5eeSXin Li error_collector.ResultList().count(legal_copyright_message)) 4485*8c35d5eeSXin Li 4486*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4487*8c35d5eeSXin Li cpplint.ProcessFileData( 4488*8c35d5eeSXin Li file_path, 'cc', 4489*8c35d5eeSXin Li ['' for unused_i in range(10)] + [copyright_line], 4490*8c35d5eeSXin Li error_collector) 4491*8c35d5eeSXin Li self.assertEquals( 4492*8c35d5eeSXin Li 1, 4493*8c35d5eeSXin Li error_collector.ResultList().count(legal_copyright_message)) 4494*8c35d5eeSXin Li 4495*8c35d5eeSXin Li # Test that warning isn't issued if Copyright line appears early enough. 4496*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4497*8c35d5eeSXin Li cpplint.ProcessFileData(file_path, 'cc', [copyright_line], error_collector) 4498*8c35d5eeSXin Li for message in error_collector.ResultList(): 4499*8c35d5eeSXin Li if message.find('legal/copyright') != -1: 4500*8c35d5eeSXin Li self.fail('Unexpected error: %s' % message) 4501*8c35d5eeSXin Li 4502*8c35d5eeSXin Li error_collector = ErrorCollector(self.assert_) 4503*8c35d5eeSXin Li cpplint.ProcessFileData( 4504*8c35d5eeSXin Li file_path, 'cc', 4505*8c35d5eeSXin Li ['' for unused_i in range(9)] + [copyright_line], 4506*8c35d5eeSXin Li error_collector) 4507*8c35d5eeSXin Li for message in error_collector.ResultList(): 4508*8c35d5eeSXin Li if message.find('legal/copyright') != -1: 4509*8c35d5eeSXin Li self.fail('Unexpected error: %s' % message) 4510*8c35d5eeSXin Li 4511*8c35d5eeSXin Li def testInvalidIncrement(self): 4512*8c35d5eeSXin Li self.TestLint('*count++;', 4513*8c35d5eeSXin Li 'Changing pointer instead of value (or unused value of ' 4514*8c35d5eeSXin Li 'operator*). [runtime/invalid_increment] [5]') 4515*8c35d5eeSXin Li 4516*8c35d5eeSXin Li def testSnprintfSize(self): 4517*8c35d5eeSXin Li self.TestLint('vsnprintf(NULL, 0, format)', '') 4518*8c35d5eeSXin Li self.TestLint('snprintf(fisk, 1, format)', 4519*8c35d5eeSXin Li 'If you can, use sizeof(fisk) instead of 1 as the 2nd arg ' 4520*8c35d5eeSXin Li 'to snprintf. [runtime/printf] [3]') 4521*8c35d5eeSXin Liclass Cxx11Test(CpplintTestBase): 4522*8c35d5eeSXin Li 4523*8c35d5eeSXin Li def Helper(self, package, extension, lines, count): 4524*8c35d5eeSXin Li filename = package + '/foo.' + extension 4525*8c35d5eeSXin Li lines = lines[:] 4526*8c35d5eeSXin Li 4527*8c35d5eeSXin Li # Header files need to have an ifdef guard wrapped around their code. 4528*8c35d5eeSXin Li if extension == 'h': 4529*8c35d5eeSXin Li guard = filename.upper().replace('/', '_').replace('.', '_') + '_' 4530*8c35d5eeSXin Li lines.insert(0, '#ifndef ' + guard) 4531*8c35d5eeSXin Li lines.insert(1, '#define ' + guard) 4532*8c35d5eeSXin Li lines.append('#endif // ' + guard) 4533*8c35d5eeSXin Li 4534*8c35d5eeSXin Li # All files need a final blank line. 4535*8c35d5eeSXin Li lines.append('') 4536*8c35d5eeSXin Li 4537*8c35d5eeSXin Li # Process the file and check resulting error count. 4538*8c35d5eeSXin Li collector = ErrorCollector(self.assert_) 4539*8c35d5eeSXin Li cpplint.ProcessFileData(filename, extension, lines, collector) 4540*8c35d5eeSXin Li error_list = collector.ResultList() 4541*8c35d5eeSXin Li self.assertEquals(count, len(error_list), error_list) 4542*8c35d5eeSXin Li 4543*8c35d5eeSXin Li def TestCxx11Feature(self, code, expected_error): 4544*8c35d5eeSXin Li lines = code.split('\n') 4545*8c35d5eeSXin Li collector = ErrorCollector(self.assert_) 4546*8c35d5eeSXin Li cpplint.RemoveMultiLineComments('foo.h', lines, collector) 4547*8c35d5eeSXin Li clean_lines = cpplint.CleansedLines(lines) 4548*8c35d5eeSXin Li cpplint.FlagCxx11Features('foo.cc', clean_lines, 0, collector) 4549*8c35d5eeSXin Li self.assertEquals(expected_error, collector.Results()) 4550*8c35d5eeSXin Li 4551*8c35d5eeSXin Li def testBlockedHeaders(self): 4552*8c35d5eeSXin Li self.TestCxx11Feature('#include <tr1/regex>', 4553*8c35d5eeSXin Li 'C++ TR1 headers such as <tr1/regex> are ' 4554*8c35d5eeSXin Li 'unapproved. [build/c++tr1] [5]') 4555*8c35d5eeSXin Li self.TestCxx11Feature('#include <mutex>', 4556*8c35d5eeSXin Li '<mutex> is an unapproved C++11 header.' 4557*8c35d5eeSXin Li ' [build/c++11] [5]') 4558*8c35d5eeSXin Li 4559*8c35d5eeSXin Li def testBlockedClasses(self): 4560*8c35d5eeSXin Li self.TestCxx11Feature('std::alignment_of<T>', 4561*8c35d5eeSXin Li 'std::alignment_of is an unapproved ' 4562*8c35d5eeSXin Li 'C++11 class or function. Send c-style an example ' 4563*8c35d5eeSXin Li 'of where it would make your code more readable, ' 4564*8c35d5eeSXin Li 'and they may let you use it.' 4565*8c35d5eeSXin Li ' [build/c++11] [5]') 4566*8c35d5eeSXin Li self.TestCxx11Feature('std::alignment_offer', '') 4567*8c35d5eeSXin Li self.TestCxx11Feature('mystd::alignment_of', '') 4568*8c35d5eeSXin Li self.TestCxx11Feature('std::binomial_distribution', '') 4569*8c35d5eeSXin Li 4570*8c35d5eeSXin Li def testBlockedFunctions(self): 4571*8c35d5eeSXin Li self.TestCxx11Feature('std::alignment_of<int>', 4572*8c35d5eeSXin Li 'std::alignment_of is an unapproved ' 4573*8c35d5eeSXin Li 'C++11 class or function. Send c-style an example ' 4574*8c35d5eeSXin Li 'of where it would make your code more readable, ' 4575*8c35d5eeSXin Li 'and they may let you use it.' 4576*8c35d5eeSXin Li ' [build/c++11] [5]') 4577*8c35d5eeSXin Li # Missed because of the lack of "std::". Compiles because ADL 4578*8c35d5eeSXin Li # looks in the namespace of my_shared_ptr, which (presumably) is 4579*8c35d5eeSXin Li # std::. But there will be a lint error somewhere in this file 4580*8c35d5eeSXin Li # since my_shared_ptr had to be defined. 4581*8c35d5eeSXin Li self.TestCxx11Feature('static_pointer_cast<Base>(my_shared_ptr)', '') 4582*8c35d5eeSXin Li self.TestCxx11Feature('std::declval<T>()', '') 4583*8c35d5eeSXin Li 4584*8c35d5eeSXin Li def testExplicitMakePair(self): 4585*8c35d5eeSXin Li self.TestLint('make_pair', '') 4586*8c35d5eeSXin Li self.TestLint('make_pair(42, 42)', '') 4587*8c35d5eeSXin Li self.TestLint('make_pair<', 4588*8c35d5eeSXin Li 'For C++11-compatibility, omit template arguments from' 4589*8c35d5eeSXin Li ' make_pair OR use pair directly OR if appropriate,' 4590*8c35d5eeSXin Li ' construct a pair directly' 4591*8c35d5eeSXin Li ' [build/explicit_make_pair] [4]') 4592*8c35d5eeSXin Li self.TestLint('make_pair <', 4593*8c35d5eeSXin Li 'For C++11-compatibility, omit template arguments from' 4594*8c35d5eeSXin Li ' make_pair OR use pair directly OR if appropriate,' 4595*8c35d5eeSXin Li ' construct a pair directly' 4596*8c35d5eeSXin Li ' [build/explicit_make_pair] [4]') 4597*8c35d5eeSXin Li self.TestLint('my_make_pair<int, int>', '') 4598*8c35d5eeSXin Li 4599*8c35d5eeSXin Liclass Cxx14Test(CpplintTestBase): 4600*8c35d5eeSXin Li 4601*8c35d5eeSXin Li def TestCxx14Feature(self, code, expected_error): 4602*8c35d5eeSXin Li lines = code.split('\n') 4603*8c35d5eeSXin Li collector = ErrorCollector(self.assert_) 4604*8c35d5eeSXin Li cpplint.RemoveMultiLineComments('foo.h', lines, collector) 4605*8c35d5eeSXin Li clean_lines = cpplint.CleansedLines(lines) 4606*8c35d5eeSXin Li cpplint.FlagCxx14Features('foo.cc', clean_lines, 0, collector) 4607*8c35d5eeSXin Li self.assertEquals(expected_error, collector.Results()) 4608*8c35d5eeSXin Li 4609*8c35d5eeSXin Li def testBlockedHeaders(self): 4610*8c35d5eeSXin Li self.TestCxx14Feature('#include <scoped_allocator>', 4611*8c35d5eeSXin Li '<scoped_allocator> is an unapproved C++14 header.' 4612*8c35d5eeSXin Li ' [build/c++14] [5]') 4613*8c35d5eeSXin Li self.TestCxx14Feature('#include <shared_mutex>', 4614*8c35d5eeSXin Li '<shared_mutex> is an unapproved C++14 header.' 4615*8c35d5eeSXin Li ' [build/c++14] [5]') 4616*8c35d5eeSXin Li 4617*8c35d5eeSXin Li 4618*8c35d5eeSXin Liclass CleansedLinesTest(unittest.TestCase): 4619*8c35d5eeSXin Li 4620*8c35d5eeSXin Li def testInit(self): 4621*8c35d5eeSXin Li lines = ['Line 1', 4622*8c35d5eeSXin Li 'Line 2', 4623*8c35d5eeSXin Li 'Line 3 // Comment test', 4624*8c35d5eeSXin Li 'Line 4 /* Comment test */', 4625*8c35d5eeSXin Li 'Line 5 "foo"'] 4626*8c35d5eeSXin Li 4627*8c35d5eeSXin Li clean_lines = cpplint.CleansedLines(lines) 4628*8c35d5eeSXin Li self.assertEquals(lines, clean_lines.raw_lines) 4629*8c35d5eeSXin Li self.assertEquals(5, clean_lines.NumLines()) 4630*8c35d5eeSXin Li 4631*8c35d5eeSXin Li self.assertEquals(['Line 1', 4632*8c35d5eeSXin Li 'Line 2', 4633*8c35d5eeSXin Li 'Line 3', 4634*8c35d5eeSXin Li 'Line 4', 4635*8c35d5eeSXin Li 'Line 5 "foo"'], 4636*8c35d5eeSXin Li clean_lines.lines) 4637*8c35d5eeSXin Li 4638*8c35d5eeSXin Li self.assertEquals(['Line 1', 4639*8c35d5eeSXin Li 'Line 2', 4640*8c35d5eeSXin Li 'Line 3', 4641*8c35d5eeSXin Li 'Line 4', 4642*8c35d5eeSXin Li 'Line 5 ""'], 4643*8c35d5eeSXin Li clean_lines.elided) 4644*8c35d5eeSXin Li 4645*8c35d5eeSXin Li def testInitEmpty(self): 4646*8c35d5eeSXin Li clean_lines = cpplint.CleansedLines([]) 4647*8c35d5eeSXin Li self.assertEquals([], clean_lines.raw_lines) 4648*8c35d5eeSXin Li self.assertEquals(0, clean_lines.NumLines()) 4649*8c35d5eeSXin Li 4650*8c35d5eeSXin Li def testCollapseStrings(self): 4651*8c35d5eeSXin Li collapse = cpplint.CleansedLines._CollapseStrings 4652*8c35d5eeSXin Li self.assertEquals('""', collapse('""')) # "" (empty) 4653*8c35d5eeSXin Li self.assertEquals('"""', collapse('"""')) # """ (bad) 4654*8c35d5eeSXin Li self.assertEquals('""', collapse('"xyz"')) # "xyz" (string) 4655*8c35d5eeSXin Li self.assertEquals('""', collapse('"\\\""')) # "\"" (string) 4656*8c35d5eeSXin Li self.assertEquals('""', collapse('"\'"')) # "'" (string) 4657*8c35d5eeSXin Li self.assertEquals('"\"', collapse('"\"')) # "\" (bad) 4658*8c35d5eeSXin Li self.assertEquals('""', collapse('"\\\\"')) # "\\" (string) 4659*8c35d5eeSXin Li self.assertEquals('"', collapse('"\\\\\\"')) # "\\\" (bad) 4660*8c35d5eeSXin Li self.assertEquals('""', collapse('"\\\\\\\\"')) # "\\\\" (string) 4661*8c35d5eeSXin Li 4662*8c35d5eeSXin Li self.assertEquals('\'\'', collapse('\'\'')) # '' (empty) 4663*8c35d5eeSXin Li self.assertEquals('\'\'', collapse('\'a\'')) # 'a' (char) 4664*8c35d5eeSXin Li self.assertEquals('\'\'', collapse('\'\\\'\'')) # '\'' (char) 4665*8c35d5eeSXin Li self.assertEquals('\'', collapse('\'\\\'')) # '\' (bad) 4666*8c35d5eeSXin Li self.assertEquals('', collapse('\\012')) # '\012' (char) 4667*8c35d5eeSXin Li self.assertEquals('', collapse('\\xfF0')) # '\xfF0' (char) 4668*8c35d5eeSXin Li self.assertEquals('', collapse('\\n')) # '\n' (char) 4669*8c35d5eeSXin Li self.assertEquals(r'\#', collapse('\\#')) # '\#' (bad) 4670*8c35d5eeSXin Li 4671*8c35d5eeSXin Li self.assertEquals('"" + ""', collapse('"\'" + "\'"')) 4672*8c35d5eeSXin Li self.assertEquals("'', ''", collapse("'\"', '\"'")) 4673*8c35d5eeSXin Li self.assertEquals('""[0b10]', collapse('"a\'b"[0b1\'0]')) 4674*8c35d5eeSXin Li 4675*8c35d5eeSXin Li self.assertEquals('42', collapse("4'2")) 4676*8c35d5eeSXin Li self.assertEquals('0b0101', collapse("0b0'1'0'1")) 4677*8c35d5eeSXin Li self.assertEquals('1048576', collapse("1'048'576")) 4678*8c35d5eeSXin Li self.assertEquals('0X100000', collapse("0X10'0000")) 4679*8c35d5eeSXin Li self.assertEquals('0004000000', collapse("0'004'000'000")) 4680*8c35d5eeSXin Li self.assertEquals('1.602176565e-19', collapse("1.602'176'565e-19")) 4681*8c35d5eeSXin Li self.assertEquals('\'\' + 0xffff', collapse("'i' + 0xf'f'f'f")) 4682*8c35d5eeSXin Li self.assertEquals('sizeof\'\' == 1', collapse("sizeof'x' == 1")) 4683*8c35d5eeSXin Li self.assertEquals('0x.03p100', collapse('0x.0\'3p1\'0\'0')) 4684*8c35d5eeSXin Li self.assertEquals('123.45', collapse('1\'23.4\'5')) 4685*8c35d5eeSXin Li 4686*8c35d5eeSXin Li self.assertEquals('StringReplace(body, "", "");', 4687*8c35d5eeSXin Li collapse('StringReplace(body, "\\\\", "\\\\\\\\");')) 4688*8c35d5eeSXin Li self.assertEquals('\'\' ""', 4689*8c35d5eeSXin Li collapse('\'"\' "foo"')) 4690*8c35d5eeSXin Li 4691*8c35d5eeSXin Li 4692*8c35d5eeSXin Liclass OrderOfIncludesTest(CpplintTestBase): 4693*8c35d5eeSXin Li 4694*8c35d5eeSXin Li def setUp(self): 4695*8c35d5eeSXin Li CpplintTestBase.setUp(self) 4696*8c35d5eeSXin Li self.include_state = cpplint._IncludeState() 4697*8c35d5eeSXin Li os.path.abspath = lambda value: value 4698*8c35d5eeSXin Li 4699*8c35d5eeSXin Li def testCheckNextIncludeOrder_OtherThenCpp(self): 4700*8c35d5eeSXin Li self.assertEqual('', self.include_state.CheckNextIncludeOrder( 4701*8c35d5eeSXin Li cpplint._OTHER_HEADER)) 4702*8c35d5eeSXin Li self.assertEqual('Found C++ system header after other header', 4703*8c35d5eeSXin Li self.include_state.CheckNextIncludeOrder( 4704*8c35d5eeSXin Li cpplint._CPP_SYS_HEADER)) 4705*8c35d5eeSXin Li 4706*8c35d5eeSXin Li def testCheckNextIncludeOrder_CppThenC(self): 4707*8c35d5eeSXin Li self.assertEqual('', self.include_state.CheckNextIncludeOrder( 4708*8c35d5eeSXin Li cpplint._CPP_SYS_HEADER)) 4709*8c35d5eeSXin Li self.assertEqual('Found C system header after C++ system header', 4710*8c35d5eeSXin Li self.include_state.CheckNextIncludeOrder( 4711*8c35d5eeSXin Li cpplint._C_SYS_HEADER)) 4712*8c35d5eeSXin Li 4713*8c35d5eeSXin Li def testCheckNextIncludeOrder_LikelyThenCpp(self): 4714*8c35d5eeSXin Li self.assertEqual('', self.include_state.CheckNextIncludeOrder( 4715*8c35d5eeSXin Li cpplint._LIKELY_MY_HEADER)) 4716*8c35d5eeSXin Li self.assertEqual('', self.include_state.CheckNextIncludeOrder( 4717*8c35d5eeSXin Li cpplint._CPP_SYS_HEADER)) 4718*8c35d5eeSXin Li 4719*8c35d5eeSXin Li def testCheckNextIncludeOrder_PossibleThenCpp(self): 4720*8c35d5eeSXin Li self.assertEqual('', self.include_state.CheckNextIncludeOrder( 4721*8c35d5eeSXin Li cpplint._POSSIBLE_MY_HEADER)) 4722*8c35d5eeSXin Li self.assertEqual('', self.include_state.CheckNextIncludeOrder( 4723*8c35d5eeSXin Li cpplint._CPP_SYS_HEADER)) 4724*8c35d5eeSXin Li 4725*8c35d5eeSXin Li def testCheckNextIncludeOrder_CppThenLikely(self): 4726*8c35d5eeSXin Li self.assertEqual('', self.include_state.CheckNextIncludeOrder( 4727*8c35d5eeSXin Li cpplint._CPP_SYS_HEADER)) 4728*8c35d5eeSXin Li # This will eventually fail. 4729*8c35d5eeSXin Li self.assertEqual('', self.include_state.CheckNextIncludeOrder( 4730*8c35d5eeSXin Li cpplint._LIKELY_MY_HEADER)) 4731*8c35d5eeSXin Li 4732*8c35d5eeSXin Li def testCheckNextIncludeOrder_CppThenPossible(self): 4733*8c35d5eeSXin Li self.assertEqual('', self.include_state.CheckNextIncludeOrder( 4734*8c35d5eeSXin Li cpplint._CPP_SYS_HEADER)) 4735*8c35d5eeSXin Li self.assertEqual('', self.include_state.CheckNextIncludeOrder( 4736*8c35d5eeSXin Li cpplint._POSSIBLE_MY_HEADER)) 4737*8c35d5eeSXin Li 4738*8c35d5eeSXin Li def testClassifyInclude(self): 4739*8c35d5eeSXin Li file_info = cpplint.FileInfo 4740*8c35d5eeSXin Li classify_include = cpplint._ClassifyInclude 4741*8c35d5eeSXin Li self.assertEqual(cpplint._C_SYS_HEADER, 4742*8c35d5eeSXin Li classify_include(file_info('foo/foo.cc'), 4743*8c35d5eeSXin Li 'stdio.h', 4744*8c35d5eeSXin Li True)) 4745*8c35d5eeSXin Li self.assertEqual(cpplint._CPP_SYS_HEADER, 4746*8c35d5eeSXin Li classify_include(file_info('foo/foo.cc'), 4747*8c35d5eeSXin Li 'string', 4748*8c35d5eeSXin Li True)) 4749*8c35d5eeSXin Li self.assertEqual(cpplint._CPP_SYS_HEADER, 4750*8c35d5eeSXin Li classify_include(file_info('foo/foo.cc'), 4751*8c35d5eeSXin Li 'typeinfo', 4752*8c35d5eeSXin Li True)) 4753*8c35d5eeSXin Li self.assertEqual(cpplint._OTHER_HEADER, 4754*8c35d5eeSXin Li classify_include(file_info('foo/foo.cc'), 4755*8c35d5eeSXin Li 'string', 4756*8c35d5eeSXin Li False)) 4757*8c35d5eeSXin Li 4758*8c35d5eeSXin Li self.assertEqual(cpplint._LIKELY_MY_HEADER, 4759*8c35d5eeSXin Li classify_include(file_info('foo/foo.cc'), 4760*8c35d5eeSXin Li 'foo/foo-inl.h', 4761*8c35d5eeSXin Li False)) 4762*8c35d5eeSXin Li self.assertEqual(cpplint._LIKELY_MY_HEADER, 4763*8c35d5eeSXin Li classify_include(file_info('foo/internal/foo.cc'), 4764*8c35d5eeSXin Li 'foo/public/foo.h', 4765*8c35d5eeSXin Li False)) 4766*8c35d5eeSXin Li self.assertEqual(cpplint._POSSIBLE_MY_HEADER, 4767*8c35d5eeSXin Li classify_include(file_info('foo/internal/foo.cc'), 4768*8c35d5eeSXin Li 'foo/other/public/foo.h', 4769*8c35d5eeSXin Li False)) 4770*8c35d5eeSXin Li self.assertEqual(cpplint._OTHER_HEADER, 4771*8c35d5eeSXin Li classify_include(file_info('foo/internal/foo.cc'), 4772*8c35d5eeSXin Li 'foo/other/public/foop.h', 4773*8c35d5eeSXin Li False)) 4774*8c35d5eeSXin Li 4775*8c35d5eeSXin Li def testTryDropCommonSuffixes(self): 4776*8c35d5eeSXin Li self.assertEqual('foo/foo', cpplint._DropCommonSuffixes('foo/foo-inl.h')) 4777*8c35d5eeSXin Li self.assertEqual('foo/bar/foo', 4778*8c35d5eeSXin Li cpplint._DropCommonSuffixes('foo/bar/foo_inl.h')) 4779*8c35d5eeSXin Li self.assertEqual('foo/foo', cpplint._DropCommonSuffixes('foo/foo.cc')) 4780*8c35d5eeSXin Li self.assertEqual('foo/foo_unusualinternal', 4781*8c35d5eeSXin Li cpplint._DropCommonSuffixes('foo/foo_unusualinternal.h')) 4782*8c35d5eeSXin Li self.assertEqual('', 4783*8c35d5eeSXin Li cpplint._DropCommonSuffixes('_test.cc')) 4784*8c35d5eeSXin Li self.assertEqual('test', 4785*8c35d5eeSXin Li cpplint._DropCommonSuffixes('test.cc')) 4786*8c35d5eeSXin Li 4787*8c35d5eeSXin Li def testRegression(self): 4788*8c35d5eeSXin Li def Format(includes): 4789*8c35d5eeSXin Li include_list = [] 4790*8c35d5eeSXin Li for item in includes: 4791*8c35d5eeSXin Li if item.startswith('"') or item.startswith('<'): 4792*8c35d5eeSXin Li include_list.append('#include %s\n' % item) 4793*8c35d5eeSXin Li else: 4794*8c35d5eeSXin Li include_list.append(item + '\n') 4795*8c35d5eeSXin Li return ''.join(include_list) 4796*8c35d5eeSXin Li 4797*8c35d5eeSXin Li # Test singleton cases first. 4798*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo/foo.cc', Format(['"foo/foo.h"']), '') 4799*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo/foo.cc', Format(['<stdio.h>']), '') 4800*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo/foo.cc', Format(['<string>']), '') 4801*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo/foo.cc', Format(['"foo/foo-inl.h"']), '') 4802*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo/foo.cc', Format(['"bar/bar-inl.h"']), '') 4803*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo/foo.cc', Format(['"bar/bar.h"']), '') 4804*8c35d5eeSXin Li 4805*8c35d5eeSXin Li # Test everything in a good and new order. 4806*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo/foo.cc', 4807*8c35d5eeSXin Li Format(['"foo/foo.h"', 4808*8c35d5eeSXin Li '"foo/foo-inl.h"', 4809*8c35d5eeSXin Li '<stdio.h>', 4810*8c35d5eeSXin Li '<string>', 4811*8c35d5eeSXin Li '<unordered_map>', 4812*8c35d5eeSXin Li '"bar/bar-inl.h"', 4813*8c35d5eeSXin Li '"bar/bar.h"']), 4814*8c35d5eeSXin Li '') 4815*8c35d5eeSXin Li 4816*8c35d5eeSXin Li # Test bad orders. 4817*8c35d5eeSXin Li self.TestLanguageRulesCheck( 4818*8c35d5eeSXin Li 'foo/foo.cc', 4819*8c35d5eeSXin Li Format(['<string>', '<stdio.h>']), 4820*8c35d5eeSXin Li 'Found C system header after C++ system header.' 4821*8c35d5eeSXin Li ' Should be: foo.h, c system, c++ system, other.' 4822*8c35d5eeSXin Li ' [build/include_order] [4]') 4823*8c35d5eeSXin Li self.TestLanguageRulesCheck( 4824*8c35d5eeSXin Li 'foo/foo.cc', 4825*8c35d5eeSXin Li Format(['"foo/bar-inl.h"', 4826*8c35d5eeSXin Li '"foo/foo-inl.h"']), 4827*8c35d5eeSXin Li '') 4828*8c35d5eeSXin Li self.TestLanguageRulesCheck( 4829*8c35d5eeSXin Li 'foo/foo.cc', 4830*8c35d5eeSXin Li Format(['"foo/e.h"', 4831*8c35d5eeSXin Li '"foo/b.h"', # warning here (e>b) 4832*8c35d5eeSXin Li '"foo/c.h"', 4833*8c35d5eeSXin Li '"foo/d.h"', 4834*8c35d5eeSXin Li '"foo/a.h"']), # warning here (d>a) 4835*8c35d5eeSXin Li ['Include "foo/b.h" not in alphabetical order' 4836*8c35d5eeSXin Li ' [build/include_alpha] [4]', 4837*8c35d5eeSXin Li 'Include "foo/a.h" not in alphabetical order' 4838*8c35d5eeSXin Li ' [build/include_alpha] [4]']) 4839*8c35d5eeSXin Li # -inl.h headers are no longer special. 4840*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo/foo.cc', 4841*8c35d5eeSXin Li Format(['"foo/foo-inl.h"', '<string>']), 4842*8c35d5eeSXin Li '') 4843*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo/foo.cc', 4844*8c35d5eeSXin Li Format(['"foo/bar.h"', '"foo/bar-inl.h"']), 4845*8c35d5eeSXin Li '') 4846*8c35d5eeSXin Li # Test componentized header. OK to have my header in ../public dir. 4847*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo/internal/foo.cc', 4848*8c35d5eeSXin Li Format(['"foo/public/foo.h"', '<string>']), 4849*8c35d5eeSXin Li '') 4850*8c35d5eeSXin Li # OK to have my header in other dir (not stylistically, but 4851*8c35d5eeSXin Li # cpplint isn't as good as a human). 4852*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo/internal/foo.cc', 4853*8c35d5eeSXin Li Format(['"foo/other/public/foo.h"', 4854*8c35d5eeSXin Li '<string>']), 4855*8c35d5eeSXin Li '') 4856*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo/foo.cc', 4857*8c35d5eeSXin Li Format(['"foo/foo.h"', 4858*8c35d5eeSXin Li '<string>', 4859*8c35d5eeSXin Li '"base/google.h"', 4860*8c35d5eeSXin Li '"base/flags.h"']), 4861*8c35d5eeSXin Li 'Include "base/flags.h" not in alphabetical ' 4862*8c35d5eeSXin Li 'order [build/include_alpha] [4]') 4863*8c35d5eeSXin Li # According to the style, -inl.h should come before .h, but we don't 4864*8c35d5eeSXin Li # complain about that. 4865*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo/foo.cc', 4866*8c35d5eeSXin Li Format(['"foo/foo-inl.h"', 4867*8c35d5eeSXin Li '"foo/foo.h"', 4868*8c35d5eeSXin Li '"base/google.h"', 4869*8c35d5eeSXin Li '"base/google-inl.h"']), 4870*8c35d5eeSXin Li '') 4871*8c35d5eeSXin Li # Allow project includes to be separated by blank lines 4872*8c35d5eeSXin Li self.TestLanguageRulesCheck('a/a.cc', 4873*8c35d5eeSXin Li Format(['"a/a.h"', 4874*8c35d5eeSXin Li '<string>', 4875*8c35d5eeSXin Li '"base/google.h"', 4876*8c35d5eeSXin Li '', 4877*8c35d5eeSXin Li '"b/c.h"', 4878*8c35d5eeSXin Li '', 4879*8c35d5eeSXin Li 'MACRO', 4880*8c35d5eeSXin Li '"a/b.h"']), 4881*8c35d5eeSXin Li '') 4882*8c35d5eeSXin Li self.TestLanguageRulesCheck('a/a.cc', 4883*8c35d5eeSXin Li Format(['"a/a.h"', 4884*8c35d5eeSXin Li '<string>', 4885*8c35d5eeSXin Li '"base/google.h"', 4886*8c35d5eeSXin Li '"a/b.h"']), 4887*8c35d5eeSXin Li 'Include "a/b.h" not in alphabetical ' 4888*8c35d5eeSXin Li 'order [build/include_alpha] [4]') 4889*8c35d5eeSXin Li 4890*8c35d5eeSXin Li # Test conditional includes 4891*8c35d5eeSXin Li self.TestLanguageRulesCheck( 4892*8c35d5eeSXin Li 'a/a.cc', 4893*8c35d5eeSXin Li ''.join(['#include <string.h>\n', 4894*8c35d5eeSXin Li '#include "base/port.h"\n', 4895*8c35d5eeSXin Li '#include <initializer_list>\n']), 4896*8c35d5eeSXin Li ('Found C++ system header after other header. ' 4897*8c35d5eeSXin Li 'Should be: a.h, c system, c++ system, other. ' 4898*8c35d5eeSXin Li '[build/include_order] [4]')) 4899*8c35d5eeSXin Li self.TestLanguageRulesCheck( 4900*8c35d5eeSXin Li 'a/a.cc', 4901*8c35d5eeSXin Li ''.join(['#include <string.h>\n', 4902*8c35d5eeSXin Li '#include "base/port.h"\n', 4903*8c35d5eeSXin Li '#ifdef LANG_CXX11\n', 4904*8c35d5eeSXin Li '#include <initializer_list>\n', 4905*8c35d5eeSXin Li '#endif // LANG_CXX11\n']), 4906*8c35d5eeSXin Li '') 4907*8c35d5eeSXin Li self.TestLanguageRulesCheck( 4908*8c35d5eeSXin Li 'a/a.cc', 4909*8c35d5eeSXin Li ''.join(['#include <string.h>\n', 4910*8c35d5eeSXin Li '#ifdef LANG_CXX11\n', 4911*8c35d5eeSXin Li '#include "base/port.h"\n', 4912*8c35d5eeSXin Li '#include <initializer_list>\n', 4913*8c35d5eeSXin Li '#endif // LANG_CXX11\n']), 4914*8c35d5eeSXin Li ('Found C++ system header after other header. ' 4915*8c35d5eeSXin Li 'Should be: a.h, c system, c++ system, other. ' 4916*8c35d5eeSXin Li '[build/include_order] [4]')) 4917*8c35d5eeSXin Li 4918*8c35d5eeSXin Li # Third party headers are exempt from order checks 4919*8c35d5eeSXin Li self.TestLanguageRulesCheck('foo/foo.cc', 4920*8c35d5eeSXin Li Format(['<string>', '"Python.h"', '<vector>']), 4921*8c35d5eeSXin Li '') 4922*8c35d5eeSXin Li 4923*8c35d5eeSXin Li 4924*8c35d5eeSXin Liclass CheckForFunctionLengthsTest(CpplintTestBase): 4925*8c35d5eeSXin Li 4926*8c35d5eeSXin Li def setUp(self): 4927*8c35d5eeSXin Li # Reducing these thresholds for the tests speeds up tests significantly. 4928*8c35d5eeSXin Li self.old_normal_trigger = cpplint._FunctionState._NORMAL_TRIGGER 4929*8c35d5eeSXin Li self.old_test_trigger = cpplint._FunctionState._TEST_TRIGGER 4930*8c35d5eeSXin Li 4931*8c35d5eeSXin Li cpplint._FunctionState._NORMAL_TRIGGER = 10 4932*8c35d5eeSXin Li cpplint._FunctionState._TEST_TRIGGER = 25 4933*8c35d5eeSXin Li 4934*8c35d5eeSXin Li def tearDown(self): 4935*8c35d5eeSXin Li cpplint._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger 4936*8c35d5eeSXin Li cpplint._FunctionState._TEST_TRIGGER = self.old_test_trigger 4937*8c35d5eeSXin Li 4938*8c35d5eeSXin Li def TestFunctionLengthsCheck(self, code, expected_message): 4939*8c35d5eeSXin Li """Check warnings for long function bodies are as expected. 4940*8c35d5eeSXin Li 4941*8c35d5eeSXin Li Args: 4942*8c35d5eeSXin Li code: C++ source code expected to generate a warning message. 4943*8c35d5eeSXin Li expected_message: Message expected to be generated by the C++ code. 4944*8c35d5eeSXin Li """ 4945*8c35d5eeSXin Li self.assertEquals(expected_message, 4946*8c35d5eeSXin Li self.PerformFunctionLengthsCheck(code)) 4947*8c35d5eeSXin Li 4948*8c35d5eeSXin Li def TriggerLines(self, error_level): 4949*8c35d5eeSXin Li """Return number of lines needed to trigger a function length warning. 4950*8c35d5eeSXin Li 4951*8c35d5eeSXin Li Args: 4952*8c35d5eeSXin Li error_level: --v setting for cpplint. 4953*8c35d5eeSXin Li 4954*8c35d5eeSXin Li Returns: 4955*8c35d5eeSXin Li Number of lines needed to trigger a function length warning. 4956*8c35d5eeSXin Li """ 4957*8c35d5eeSXin Li return cpplint._FunctionState._NORMAL_TRIGGER * 2**error_level 4958*8c35d5eeSXin Li 4959*8c35d5eeSXin Li def TestLines(self, error_level): 4960*8c35d5eeSXin Li """Return number of lines needed to trigger a test function length warning. 4961*8c35d5eeSXin Li 4962*8c35d5eeSXin Li Args: 4963*8c35d5eeSXin Li error_level: --v setting for cpplint. 4964*8c35d5eeSXin Li 4965*8c35d5eeSXin Li Returns: 4966*8c35d5eeSXin Li Number of lines needed to trigger a test function length warning. 4967*8c35d5eeSXin Li """ 4968*8c35d5eeSXin Li return cpplint._FunctionState._TEST_TRIGGER * 2**error_level 4969*8c35d5eeSXin Li 4970*8c35d5eeSXin Li def TestFunctionLengthCheckDefinition(self, lines, error_level): 4971*8c35d5eeSXin Li """Generate long function definition and check warnings are as expected. 4972*8c35d5eeSXin Li 4973*8c35d5eeSXin Li Args: 4974*8c35d5eeSXin Li lines: Number of lines to generate. 4975*8c35d5eeSXin Li error_level: --v setting for cpplint. 4976*8c35d5eeSXin Li """ 4977*8c35d5eeSXin Li trigger_level = self.TriggerLines(cpplint._VerboseLevel()) 4978*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 4979*8c35d5eeSXin Li 'void test(int x)' + self.FunctionBody(lines), 4980*8c35d5eeSXin Li ('Small and focused functions are preferred: ' 4981*8c35d5eeSXin Li 'test() has %d non-comment lines ' 4982*8c35d5eeSXin Li '(error triggered by exceeding %d lines).' 4983*8c35d5eeSXin Li ' [readability/fn_size] [%d]' 4984*8c35d5eeSXin Li % (lines, trigger_level, error_level))) 4985*8c35d5eeSXin Li 4986*8c35d5eeSXin Li def TestFunctionLengthCheckDefinitionOK(self, lines): 4987*8c35d5eeSXin Li """Generate shorter function definition and check no warning is produced. 4988*8c35d5eeSXin Li 4989*8c35d5eeSXin Li Args: 4990*8c35d5eeSXin Li lines: Number of lines to generate. 4991*8c35d5eeSXin Li """ 4992*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 4993*8c35d5eeSXin Li 'void test(int x)' + self.FunctionBody(lines), 4994*8c35d5eeSXin Li '') 4995*8c35d5eeSXin Li 4996*8c35d5eeSXin Li def TestFunctionLengthCheckAtErrorLevel(self, error_level): 4997*8c35d5eeSXin Li """Generate and check function at the trigger level for --v setting. 4998*8c35d5eeSXin Li 4999*8c35d5eeSXin Li Args: 5000*8c35d5eeSXin Li error_level: --v setting for cpplint. 5001*8c35d5eeSXin Li """ 5002*8c35d5eeSXin Li self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level), 5003*8c35d5eeSXin Li error_level) 5004*8c35d5eeSXin Li 5005*8c35d5eeSXin Li def TestFunctionLengthCheckBelowErrorLevel(self, error_level): 5006*8c35d5eeSXin Li """Generate and check function just below the trigger level for --v setting. 5007*8c35d5eeSXin Li 5008*8c35d5eeSXin Li Args: 5009*8c35d5eeSXin Li error_level: --v setting for cpplint. 5010*8c35d5eeSXin Li """ 5011*8c35d5eeSXin Li self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level)-1, 5012*8c35d5eeSXin Li error_level-1) 5013*8c35d5eeSXin Li 5014*8c35d5eeSXin Li def TestFunctionLengthCheckAboveErrorLevel(self, error_level): 5015*8c35d5eeSXin Li """Generate and check function just above the trigger level for --v setting. 5016*8c35d5eeSXin Li 5017*8c35d5eeSXin Li Args: 5018*8c35d5eeSXin Li error_level: --v setting for cpplint. 5019*8c35d5eeSXin Li """ 5020*8c35d5eeSXin Li self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level)+1, 5021*8c35d5eeSXin Li error_level) 5022*8c35d5eeSXin Li 5023*8c35d5eeSXin Li def FunctionBody(self, number_of_lines): 5024*8c35d5eeSXin Li return ' {\n' + ' this_is_just_a_test();\n'*number_of_lines + '}' 5025*8c35d5eeSXin Li 5026*8c35d5eeSXin Li def FunctionBodyWithBlankLines(self, number_of_lines): 5027*8c35d5eeSXin Li return ' {\n' + ' this_is_just_a_test();\n\n'*number_of_lines + '}' 5028*8c35d5eeSXin Li 5029*8c35d5eeSXin Li def FunctionBodyWithNoLints(self, number_of_lines): 5030*8c35d5eeSXin Li return (' {\n' + 5031*8c35d5eeSXin Li ' this_is_just_a_test(); // NOLINT\n'*number_of_lines + '}') 5032*8c35d5eeSXin Li 5033*8c35d5eeSXin Li # Test line length checks. 5034*8c35d5eeSXin Li def testFunctionLengthCheckDeclaration(self): 5035*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 5036*8c35d5eeSXin Li 'void test();', # Not a function definition 5037*8c35d5eeSXin Li '') 5038*8c35d5eeSXin Li 5039*8c35d5eeSXin Li def testFunctionLengthCheckDeclarationWithBlockFollowing(self): 5040*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 5041*8c35d5eeSXin Li ('void test();\n' 5042*8c35d5eeSXin Li + self.FunctionBody(66)), # Not a function definition 5043*8c35d5eeSXin Li '') 5044*8c35d5eeSXin Li 5045*8c35d5eeSXin Li def testFunctionLengthCheckClassDefinition(self): 5046*8c35d5eeSXin Li self.TestFunctionLengthsCheck( # Not a function definition 5047*8c35d5eeSXin Li 'class Test' + self.FunctionBody(66) + ';', 5048*8c35d5eeSXin Li '') 5049*8c35d5eeSXin Li 5050*8c35d5eeSXin Li def testFunctionLengthCheckTrivial(self): 5051*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 5052*8c35d5eeSXin Li 'void test() {}', # Not counted 5053*8c35d5eeSXin Li '') 5054*8c35d5eeSXin Li 5055*8c35d5eeSXin Li def testFunctionLengthCheckEmpty(self): 5056*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 5057*8c35d5eeSXin Li 'void test() {\n}', 5058*8c35d5eeSXin Li '') 5059*8c35d5eeSXin Li 5060*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionBelowSeverity0(self): 5061*8c35d5eeSXin Li old_verbosity = cpplint._SetVerboseLevel(0) 5062*8c35d5eeSXin Li self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(0)-1) 5063*8c35d5eeSXin Li cpplint._SetVerboseLevel(old_verbosity) 5064*8c35d5eeSXin Li 5065*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionAtSeverity0(self): 5066*8c35d5eeSXin Li old_verbosity = cpplint._SetVerboseLevel(0) 5067*8c35d5eeSXin Li self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(0)) 5068*8c35d5eeSXin Li cpplint._SetVerboseLevel(old_verbosity) 5069*8c35d5eeSXin Li 5070*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionAboveSeverity0(self): 5071*8c35d5eeSXin Li old_verbosity = cpplint._SetVerboseLevel(0) 5072*8c35d5eeSXin Li self.TestFunctionLengthCheckAboveErrorLevel(0) 5073*8c35d5eeSXin Li cpplint._SetVerboseLevel(old_verbosity) 5074*8c35d5eeSXin Li 5075*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionBelowSeverity1v0(self): 5076*8c35d5eeSXin Li old_verbosity = cpplint._SetVerboseLevel(0) 5077*8c35d5eeSXin Li self.TestFunctionLengthCheckBelowErrorLevel(1) 5078*8c35d5eeSXin Li cpplint._SetVerboseLevel(old_verbosity) 5079*8c35d5eeSXin Li 5080*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionAtSeverity1v0(self): 5081*8c35d5eeSXin Li old_verbosity = cpplint._SetVerboseLevel(0) 5082*8c35d5eeSXin Li self.TestFunctionLengthCheckAtErrorLevel(1) 5083*8c35d5eeSXin Li cpplint._SetVerboseLevel(old_verbosity) 5084*8c35d5eeSXin Li 5085*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionBelowSeverity1(self): 5086*8c35d5eeSXin Li self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(1)-1) 5087*8c35d5eeSXin Li 5088*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionAtSeverity1(self): 5089*8c35d5eeSXin Li self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(1)) 5090*8c35d5eeSXin Li 5091*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionAboveSeverity1(self): 5092*8c35d5eeSXin Li self.TestFunctionLengthCheckAboveErrorLevel(1) 5093*8c35d5eeSXin Li 5094*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionSeverity1PlusBlanks(self): 5095*8c35d5eeSXin Li error_level = 1 5096*8c35d5eeSXin Li error_lines = self.TriggerLines(error_level) + 1 5097*8c35d5eeSXin Li trigger_level = self.TriggerLines(cpplint._VerboseLevel()) 5098*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 5099*8c35d5eeSXin Li 'void test_blanks(int x)' + self.FunctionBody(error_lines), 5100*8c35d5eeSXin Li ('Small and focused functions are preferred: ' 5101*8c35d5eeSXin Li 'test_blanks() has %d non-comment lines ' 5102*8c35d5eeSXin Li '(error triggered by exceeding %d lines).' 5103*8c35d5eeSXin Li ' [readability/fn_size] [%d]') 5104*8c35d5eeSXin Li % (error_lines, trigger_level, error_level)) 5105*8c35d5eeSXin Li 5106*8c35d5eeSXin Li def testFunctionLengthCheckComplexDefinitionSeverity1(self): 5107*8c35d5eeSXin Li error_level = 1 5108*8c35d5eeSXin Li error_lines = self.TriggerLines(error_level) + 1 5109*8c35d5eeSXin Li trigger_level = self.TriggerLines(cpplint._VerboseLevel()) 5110*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 5111*8c35d5eeSXin Li ('my_namespace::my_other_namespace::MyVeryLongTypeName*\n' 5112*8c35d5eeSXin Li 'my_namespace::my_other_namespace::MyFunction(int arg1, char* arg2)' 5113*8c35d5eeSXin Li + self.FunctionBody(error_lines)), 5114*8c35d5eeSXin Li ('Small and focused functions are preferred: ' 5115*8c35d5eeSXin Li 'my_namespace::my_other_namespace::MyFunction()' 5116*8c35d5eeSXin Li ' has %d non-comment lines ' 5117*8c35d5eeSXin Li '(error triggered by exceeding %d lines).' 5118*8c35d5eeSXin Li ' [readability/fn_size] [%d]') 5119*8c35d5eeSXin Li % (error_lines, trigger_level, error_level)) 5120*8c35d5eeSXin Li 5121*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionSeverity1ForTest(self): 5122*8c35d5eeSXin Li error_level = 1 5123*8c35d5eeSXin Li error_lines = self.TestLines(error_level) + 1 5124*8c35d5eeSXin Li trigger_level = self.TestLines(cpplint._VerboseLevel()) 5125*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 5126*8c35d5eeSXin Li 'TEST_F(Test, Mutator)' + self.FunctionBody(error_lines), 5127*8c35d5eeSXin Li ('Small and focused functions are preferred: ' 5128*8c35d5eeSXin Li 'TEST_F(Test, Mutator) has %d non-comment lines ' 5129*8c35d5eeSXin Li '(error triggered by exceeding %d lines).' 5130*8c35d5eeSXin Li ' [readability/fn_size] [%d]') 5131*8c35d5eeSXin Li % (error_lines, trigger_level, error_level)) 5132*8c35d5eeSXin Li 5133*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionSeverity1ForSplitLineTest(self): 5134*8c35d5eeSXin Li error_level = 1 5135*8c35d5eeSXin Li error_lines = self.TestLines(error_level) + 1 5136*8c35d5eeSXin Li trigger_level = self.TestLines(cpplint._VerboseLevel()) 5137*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 5138*8c35d5eeSXin Li ('TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,\n' 5139*8c35d5eeSXin Li ' FixGoogleUpdate_AllValues_MachineApp)' # note: 4 spaces 5140*8c35d5eeSXin Li + self.FunctionBody(error_lines)), 5141*8c35d5eeSXin Li ('Small and focused functions are preferred: ' 5142*8c35d5eeSXin Li 'TEST_F(GoogleUpdateRecoveryRegistryProtectedTest, ' # 1 space 5143*8c35d5eeSXin Li 'FixGoogleUpdate_AllValues_MachineApp) has %d non-comment lines ' 5144*8c35d5eeSXin Li '(error triggered by exceeding %d lines).' 5145*8c35d5eeSXin Li ' [readability/fn_size] [%d]') 5146*8c35d5eeSXin Li % (error_lines+1, trigger_level, error_level)) 5147*8c35d5eeSXin Li 5148*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionSeverity1ForBadTestDoesntBreak(self): 5149*8c35d5eeSXin Li error_level = 1 5150*8c35d5eeSXin Li error_lines = self.TestLines(error_level) + 1 5151*8c35d5eeSXin Li trigger_level = self.TestLines(cpplint._VerboseLevel()) 5152*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 5153*8c35d5eeSXin Li ('TEST_F(' 5154*8c35d5eeSXin Li + self.FunctionBody(error_lines)), 5155*8c35d5eeSXin Li ('Small and focused functions are preferred: ' 5156*8c35d5eeSXin Li 'TEST_F has %d non-comment lines ' 5157*8c35d5eeSXin Li '(error triggered by exceeding %d lines).' 5158*8c35d5eeSXin Li ' [readability/fn_size] [%d]') 5159*8c35d5eeSXin Li % (error_lines, trigger_level, error_level)) 5160*8c35d5eeSXin Li 5161*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionSeverity1WithEmbeddedNoLints(self): 5162*8c35d5eeSXin Li error_level = 1 5163*8c35d5eeSXin Li error_lines = self.TriggerLines(error_level)+1 5164*8c35d5eeSXin Li trigger_level = self.TriggerLines(cpplint._VerboseLevel()) 5165*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 5166*8c35d5eeSXin Li 'void test(int x)' + self.FunctionBodyWithNoLints(error_lines), 5167*8c35d5eeSXin Li ('Small and focused functions are preferred: ' 5168*8c35d5eeSXin Li 'test() has %d non-comment lines ' 5169*8c35d5eeSXin Li '(error triggered by exceeding %d lines).' 5170*8c35d5eeSXin Li ' [readability/fn_size] [%d]') 5171*8c35d5eeSXin Li % (error_lines, trigger_level, error_level)) 5172*8c35d5eeSXin Li 5173*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionSeverity1WithNoLint(self): 5174*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 5175*8c35d5eeSXin Li ('void test(int x)' + self.FunctionBody(self.TriggerLines(1)) 5176*8c35d5eeSXin Li + ' // NOLINT -- long function'), 5177*8c35d5eeSXin Li '') 5178*8c35d5eeSXin Li 5179*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionBelowSeverity2(self): 5180*8c35d5eeSXin Li self.TestFunctionLengthCheckBelowErrorLevel(2) 5181*8c35d5eeSXin Li 5182*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionSeverity2(self): 5183*8c35d5eeSXin Li self.TestFunctionLengthCheckAtErrorLevel(2) 5184*8c35d5eeSXin Li 5185*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionAboveSeverity2(self): 5186*8c35d5eeSXin Li self.TestFunctionLengthCheckAboveErrorLevel(2) 5187*8c35d5eeSXin Li 5188*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionBelowSeverity3(self): 5189*8c35d5eeSXin Li self.TestFunctionLengthCheckBelowErrorLevel(3) 5190*8c35d5eeSXin Li 5191*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionSeverity3(self): 5192*8c35d5eeSXin Li self.TestFunctionLengthCheckAtErrorLevel(3) 5193*8c35d5eeSXin Li 5194*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionAboveSeverity3(self): 5195*8c35d5eeSXin Li self.TestFunctionLengthCheckAboveErrorLevel(3) 5196*8c35d5eeSXin Li 5197*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionBelowSeverity4(self): 5198*8c35d5eeSXin Li self.TestFunctionLengthCheckBelowErrorLevel(4) 5199*8c35d5eeSXin Li 5200*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionSeverity4(self): 5201*8c35d5eeSXin Li self.TestFunctionLengthCheckAtErrorLevel(4) 5202*8c35d5eeSXin Li 5203*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionAboveSeverity4(self): 5204*8c35d5eeSXin Li self.TestFunctionLengthCheckAboveErrorLevel(4) 5205*8c35d5eeSXin Li 5206*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionBelowSeverity5(self): 5207*8c35d5eeSXin Li self.TestFunctionLengthCheckBelowErrorLevel(5) 5208*8c35d5eeSXin Li 5209*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionAtSeverity5(self): 5210*8c35d5eeSXin Li self.TestFunctionLengthCheckAtErrorLevel(5) 5211*8c35d5eeSXin Li 5212*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionAboveSeverity5(self): 5213*8c35d5eeSXin Li self.TestFunctionLengthCheckAboveErrorLevel(5) 5214*8c35d5eeSXin Li 5215*8c35d5eeSXin Li def testFunctionLengthCheckDefinitionHugeLines(self): 5216*8c35d5eeSXin Li # 5 is the limit 5217*8c35d5eeSXin Li self.TestFunctionLengthCheckDefinition(self.TriggerLines(10), 5) 5218*8c35d5eeSXin Li 5219*8c35d5eeSXin Li def testFunctionLengthNotDeterminable(self): 5220*8c35d5eeSXin Li # Macro invocation without terminating semicolon. 5221*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 5222*8c35d5eeSXin Li 'MACRO(arg)', 5223*8c35d5eeSXin Li '') 5224*8c35d5eeSXin Li 5225*8c35d5eeSXin Li # Macro with underscores 5226*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 5227*8c35d5eeSXin Li 'MACRO_WITH_UNDERSCORES(arg1, arg2, arg3)', 5228*8c35d5eeSXin Li '') 5229*8c35d5eeSXin Li 5230*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 5231*8c35d5eeSXin Li 'NonMacro(arg)', 5232*8c35d5eeSXin Li 'Lint failed to find start of function body.' 5233*8c35d5eeSXin Li ' [readability/fn_size] [5]') 5234*8c35d5eeSXin Li 5235*8c35d5eeSXin Li def testFunctionLengthCheckWithNamespace(self): 5236*8c35d5eeSXin Li old_verbosity = cpplint._SetVerboseLevel(1) 5237*8c35d5eeSXin Li self.TestFunctionLengthsCheck( 5238*8c35d5eeSXin Li ('namespace {\n' 5239*8c35d5eeSXin Li 'void CodeCoverageCL35256059() {\n' + 5240*8c35d5eeSXin Li (' X++;\n' * 3000) + 5241*8c35d5eeSXin Li '}\n' 5242*8c35d5eeSXin Li '} // namespace\n'), 5243*8c35d5eeSXin Li ('Small and focused functions are preferred: ' 5244*8c35d5eeSXin Li 'CodeCoverageCL35256059() has 3000 non-comment lines ' 5245*8c35d5eeSXin Li '(error triggered by exceeding 20 lines).' 5246*8c35d5eeSXin Li ' [readability/fn_size] [5]')) 5247*8c35d5eeSXin Li cpplint._SetVerboseLevel(old_verbosity) 5248*8c35d5eeSXin Li 5249*8c35d5eeSXin Li 5250*8c35d5eeSXin Lidef TrimExtraIndent(text_block): 5251*8c35d5eeSXin Li """Trim a uniform amount of whitespace off of each line in a string. 5252*8c35d5eeSXin Li 5253*8c35d5eeSXin Li Compute the minimum indent on all non blank lines and trim that from each, so 5254*8c35d5eeSXin Li that the block of text has no extra indentation. 5255*8c35d5eeSXin Li 5256*8c35d5eeSXin Li Args: 5257*8c35d5eeSXin Li text_block: a multiline string 5258*8c35d5eeSXin Li 5259*8c35d5eeSXin Li Returns: 5260*8c35d5eeSXin Li text_block with the common whitespace indent of each line removed. 5261*8c35d5eeSXin Li """ 5262*8c35d5eeSXin Li 5263*8c35d5eeSXin Li def CountLeadingWhitespace(s): 5264*8c35d5eeSXin Li count = 0 5265*8c35d5eeSXin Li for c in s: 5266*8c35d5eeSXin Li if not c.isspace(): 5267*8c35d5eeSXin Li break 5268*8c35d5eeSXin Li count += 1 5269*8c35d5eeSXin Li return count 5270*8c35d5eeSXin Li # find the minimum indent (except for blank lines) 5271*8c35d5eeSXin Li min_indent = min([CountLeadingWhitespace(line) 5272*8c35d5eeSXin Li for line in text_block.split('\n') if line]) 5273*8c35d5eeSXin Li return '\n'.join([line[min_indent:] for line in text_block.split('\n')]) 5274*8c35d5eeSXin Li 5275*8c35d5eeSXin Li 5276*8c35d5eeSXin Liclass CloseExpressionTest(unittest.TestCase): 5277*8c35d5eeSXin Li 5278*8c35d5eeSXin Li def setUp(self): 5279*8c35d5eeSXin Li self.lines = cpplint.CleansedLines( 5280*8c35d5eeSXin Li # 1 2 3 4 5 5281*8c35d5eeSXin Li # 0123456789012345678901234567890123456789012345678901234567890 5282*8c35d5eeSXin Li ['// Line 0', 5283*8c35d5eeSXin Li 'inline RCULocked<X>::ReadPtr::ReadPtr(const RCULocked* rcu) {', 5284*8c35d5eeSXin Li ' DCHECK(!(data & kFlagMask)) << "Error";', 5285*8c35d5eeSXin Li '}', 5286*8c35d5eeSXin Li '// Line 4', 5287*8c35d5eeSXin Li 'RCULocked<X>::WritePtr::WritePtr(RCULocked* rcu)', 5288*8c35d5eeSXin Li ' : lock_(&rcu_->mutex_) {', 5289*8c35d5eeSXin Li '}', 5290*8c35d5eeSXin Li '// Line 8', 5291*8c35d5eeSXin Li 'template <typename T, typename... A>', 5292*8c35d5eeSXin Li 'typename std::enable_if<', 5293*8c35d5eeSXin Li ' std::is_array<T>::value && (std::extent<T>::value > 0)>::type', 5294*8c35d5eeSXin Li 'MakeUnique(A&&... a) = delete;', 5295*8c35d5eeSXin Li '// Line 13', 5296*8c35d5eeSXin Li 'auto x = []() {};', 5297*8c35d5eeSXin Li '// Line 15', 5298*8c35d5eeSXin Li 'template <typename U>', 5299*8c35d5eeSXin Li 'friend bool operator==(const reffed_ptr& a,', 5300*8c35d5eeSXin Li ' const reffed_ptr<U>& b) {', 5301*8c35d5eeSXin Li ' return a.get() == b.get();', 5302*8c35d5eeSXin Li '}', 5303*8c35d5eeSXin Li '// Line 21']) 5304*8c35d5eeSXin Li 5305*8c35d5eeSXin Li def testCloseExpression(self): 5306*8c35d5eeSXin Li # List of positions to test: 5307*8c35d5eeSXin Li # (start line, start position, end line, end position + 1) 5308*8c35d5eeSXin Li positions = [(1, 16, 1, 19), 5309*8c35d5eeSXin Li (1, 37, 1, 59), 5310*8c35d5eeSXin Li (1, 60, 3, 1), 5311*8c35d5eeSXin Li (2, 8, 2, 29), 5312*8c35d5eeSXin Li (2, 30, 22, -1), # Left shift operator 5313*8c35d5eeSXin Li (9, 9, 9, 36), 5314*8c35d5eeSXin Li (10, 23, 11, 59), 5315*8c35d5eeSXin Li (11, 54, 22, -1), # Greater than operator 5316*8c35d5eeSXin Li (14, 9, 14, 11), 5317*8c35d5eeSXin Li (14, 11, 14, 13), 5318*8c35d5eeSXin Li (14, 14, 14, 16), 5319*8c35d5eeSXin Li (17, 22, 18, 46), 5320*8c35d5eeSXin Li (18, 47, 20, 1)] 5321*8c35d5eeSXin Li for p in positions: 5322*8c35d5eeSXin Li (_, line, column) = cpplint.CloseExpression(self.lines, p[0], p[1]) 5323*8c35d5eeSXin Li self.assertEquals((p[2], p[3]), (line, column)) 5324*8c35d5eeSXin Li 5325*8c35d5eeSXin Li def testReverseCloseExpression(self): 5326*8c35d5eeSXin Li # List of positions to test: 5327*8c35d5eeSXin Li # (end line, end position, start line, start position) 5328*8c35d5eeSXin Li positions = [(1, 18, 1, 16), 5329*8c35d5eeSXin Li (1, 58, 1, 37), 5330*8c35d5eeSXin Li (2, 27, 2, 10), 5331*8c35d5eeSXin Li (2, 28, 2, 8), 5332*8c35d5eeSXin Li (6, 18, 0, -1), # -> operator 5333*8c35d5eeSXin Li (9, 35, 9, 9), 5334*8c35d5eeSXin Li (11, 54, 0, -1), # Greater than operator 5335*8c35d5eeSXin Li (11, 57, 11, 31), 5336*8c35d5eeSXin Li (14, 10, 14, 9), 5337*8c35d5eeSXin Li (14, 12, 14, 11), 5338*8c35d5eeSXin Li (14, 15, 14, 14), 5339*8c35d5eeSXin Li (18, 45, 17, 22), 5340*8c35d5eeSXin Li (20, 0, 18, 47)] 5341*8c35d5eeSXin Li for p in positions: 5342*8c35d5eeSXin Li (_, line, column) = cpplint.ReverseCloseExpression(self.lines, p[0], p[1]) 5343*8c35d5eeSXin Li self.assertEquals((p[2], p[3]), (line, column)) 5344*8c35d5eeSXin Li 5345*8c35d5eeSXin Li 5346*8c35d5eeSXin Liclass NestingStateTest(unittest.TestCase): 5347*8c35d5eeSXin Li 5348*8c35d5eeSXin Li def setUp(self): 5349*8c35d5eeSXin Li self.nesting_state = cpplint.NestingState() 5350*8c35d5eeSXin Li self.error_collector = ErrorCollector(self.assert_) 5351*8c35d5eeSXin Li 5352*8c35d5eeSXin Li def UpdateWithLines(self, lines): 5353*8c35d5eeSXin Li clean_lines = cpplint.CleansedLines(lines) 5354*8c35d5eeSXin Li for line in xrange(clean_lines.NumLines()): 5355*8c35d5eeSXin Li self.nesting_state.Update('test.cc', 5356*8c35d5eeSXin Li clean_lines, line, self.error_collector) 5357*8c35d5eeSXin Li 5358*8c35d5eeSXin Li def testEmpty(self): 5359*8c35d5eeSXin Li self.UpdateWithLines([]) 5360*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack, []) 5361*8c35d5eeSXin Li 5362*8c35d5eeSXin Li def testNamespace(self): 5363*8c35d5eeSXin Li self.UpdateWithLines(['namespace {']) 5364*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5365*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], 5366*8c35d5eeSXin Li cpplint._NamespaceInfo)) 5367*8c35d5eeSXin Li self.assertTrue(self.nesting_state.stack[0].seen_open_brace) 5368*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, '') 5369*8c35d5eeSXin Li 5370*8c35d5eeSXin Li self.UpdateWithLines(['namespace outer { namespace inner']) 5371*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 3) 5372*8c35d5eeSXin Li self.assertTrue(self.nesting_state.stack[0].seen_open_brace) 5373*8c35d5eeSXin Li self.assertTrue(self.nesting_state.stack[1].seen_open_brace) 5374*8c35d5eeSXin Li self.assertFalse(self.nesting_state.stack[2].seen_open_brace) 5375*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, '') 5376*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[1].name, 'outer') 5377*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[2].name, 'inner') 5378*8c35d5eeSXin Li 5379*8c35d5eeSXin Li self.UpdateWithLines(['{']) 5380*8c35d5eeSXin Li self.assertTrue(self.nesting_state.stack[2].seen_open_brace) 5381*8c35d5eeSXin Li 5382*8c35d5eeSXin Li self.UpdateWithLines(['}', '}}']) 5383*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 0) 5384*8c35d5eeSXin Li 5385*8c35d5eeSXin Li def testClass(self): 5386*8c35d5eeSXin Li self.UpdateWithLines(['class A {']) 5387*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5388*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo)) 5389*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'A') 5390*8c35d5eeSXin Li self.assertFalse(self.nesting_state.stack[0].is_derived) 5391*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].class_indent, 0) 5392*8c35d5eeSXin Li 5393*8c35d5eeSXin Li self.UpdateWithLines(['};', 5394*8c35d5eeSXin Li 'struct B : public A {']) 5395*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5396*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo)) 5397*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'B') 5398*8c35d5eeSXin Li self.assertTrue(self.nesting_state.stack[0].is_derived) 5399*8c35d5eeSXin Li 5400*8c35d5eeSXin Li self.UpdateWithLines(['};', 5401*8c35d5eeSXin Li 'class C', 5402*8c35d5eeSXin Li ': public A {']) 5403*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5404*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo)) 5405*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'C') 5406*8c35d5eeSXin Li self.assertTrue(self.nesting_state.stack[0].is_derived) 5407*8c35d5eeSXin Li 5408*8c35d5eeSXin Li self.UpdateWithLines(['};', 5409*8c35d5eeSXin Li 'template<T>']) 5410*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 0) 5411*8c35d5eeSXin Li 5412*8c35d5eeSXin Li self.UpdateWithLines(['class D {', ' class E {']) 5413*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 2) 5414*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo)) 5415*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'D') 5416*8c35d5eeSXin Li self.assertFalse(self.nesting_state.stack[0].is_derived) 5417*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo)) 5418*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[1].name, 'E') 5419*8c35d5eeSXin Li self.assertFalse(self.nesting_state.stack[1].is_derived) 5420*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[1].class_indent, 2) 5421*8c35d5eeSXin Li self.assertEquals(self.nesting_state.InnermostClass().name, 'E') 5422*8c35d5eeSXin Li 5423*8c35d5eeSXin Li self.UpdateWithLines(['}', '}']) 5424*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 0) 5425*8c35d5eeSXin Li 5426*8c35d5eeSXin Li def testClassAccess(self): 5427*8c35d5eeSXin Li self.UpdateWithLines(['class A {']) 5428*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5429*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo)) 5430*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].access, 'private') 5431*8c35d5eeSXin Li 5432*8c35d5eeSXin Li self.UpdateWithLines([' public:']) 5433*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].access, 'public') 5434*8c35d5eeSXin Li self.UpdateWithLines([' protracted:']) 5435*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].access, 'public') 5436*8c35d5eeSXin Li self.UpdateWithLines([' protected:']) 5437*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].access, 'protected') 5438*8c35d5eeSXin Li self.UpdateWithLines([' private:']) 5439*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].access, 'private') 5440*8c35d5eeSXin Li 5441*8c35d5eeSXin Li self.UpdateWithLines([' struct B {']) 5442*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 2) 5443*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo)) 5444*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[1].access, 'public') 5445*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].access, 'private') 5446*8c35d5eeSXin Li 5447*8c35d5eeSXin Li self.UpdateWithLines([' protected :']) 5448*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[1].access, 'protected') 5449*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].access, 'private') 5450*8c35d5eeSXin Li 5451*8c35d5eeSXin Li self.UpdateWithLines([' }', '}']) 5452*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 0) 5453*8c35d5eeSXin Li 5454*8c35d5eeSXin Li def testStruct(self): 5455*8c35d5eeSXin Li self.UpdateWithLines(['struct A {']) 5456*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5457*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo)) 5458*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'A') 5459*8c35d5eeSXin Li self.assertFalse(self.nesting_state.stack[0].is_derived) 5460*8c35d5eeSXin Li 5461*8c35d5eeSXin Li self.UpdateWithLines(['}', 5462*8c35d5eeSXin Li 'void Func(struct B arg) {']) 5463*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5464*8c35d5eeSXin Li self.assertFalse(isinstance(self.nesting_state.stack[0], 5465*8c35d5eeSXin Li cpplint._ClassInfo)) 5466*8c35d5eeSXin Li 5467*8c35d5eeSXin Li self.UpdateWithLines(['}']) 5468*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 0) 5469*8c35d5eeSXin Li 5470*8c35d5eeSXin Li def testPreprocessor(self): 5471*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.pp_stack), 0) 5472*8c35d5eeSXin Li self.UpdateWithLines(['#if MACRO1']) 5473*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.pp_stack), 1) 5474*8c35d5eeSXin Li self.UpdateWithLines(['#endif']) 5475*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.pp_stack), 0) 5476*8c35d5eeSXin Li 5477*8c35d5eeSXin Li self.UpdateWithLines(['#ifdef MACRO2']) 5478*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.pp_stack), 1) 5479*8c35d5eeSXin Li self.UpdateWithLines(['#else']) 5480*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.pp_stack), 1) 5481*8c35d5eeSXin Li self.UpdateWithLines(['#ifdef MACRO3']) 5482*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.pp_stack), 2) 5483*8c35d5eeSXin Li self.UpdateWithLines(['#elif MACRO4']) 5484*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.pp_stack), 2) 5485*8c35d5eeSXin Li self.UpdateWithLines(['#endif']) 5486*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.pp_stack), 1) 5487*8c35d5eeSXin Li self.UpdateWithLines(['#endif']) 5488*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.pp_stack), 0) 5489*8c35d5eeSXin Li 5490*8c35d5eeSXin Li self.UpdateWithLines(['#ifdef MACRO5', 5491*8c35d5eeSXin Li 'class A {', 5492*8c35d5eeSXin Li '#elif MACRO6', 5493*8c35d5eeSXin Li 'class B {', 5494*8c35d5eeSXin Li '#else', 5495*8c35d5eeSXin Li 'class C {', 5496*8c35d5eeSXin Li '#endif']) 5497*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.pp_stack), 0) 5498*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5499*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo)) 5500*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'A') 5501*8c35d5eeSXin Li self.UpdateWithLines(['};']) 5502*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 0) 5503*8c35d5eeSXin Li 5504*8c35d5eeSXin Li self.UpdateWithLines(['class D', 5505*8c35d5eeSXin Li '#ifdef MACRO7']) 5506*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.pp_stack), 1) 5507*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5508*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo)) 5509*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'D') 5510*8c35d5eeSXin Li self.assertFalse(self.nesting_state.stack[0].is_derived) 5511*8c35d5eeSXin Li 5512*8c35d5eeSXin Li self.UpdateWithLines(['#elif MACRO8', 5513*8c35d5eeSXin Li ': public E']) 5514*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5515*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'D') 5516*8c35d5eeSXin Li self.assertTrue(self.nesting_state.stack[0].is_derived) 5517*8c35d5eeSXin Li self.assertFalse(self.nesting_state.stack[0].seen_open_brace) 5518*8c35d5eeSXin Li 5519*8c35d5eeSXin Li self.UpdateWithLines(['#else', 5520*8c35d5eeSXin Li '{']) 5521*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5522*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'D') 5523*8c35d5eeSXin Li self.assertFalse(self.nesting_state.stack[0].is_derived) 5524*8c35d5eeSXin Li self.assertTrue(self.nesting_state.stack[0].seen_open_brace) 5525*8c35d5eeSXin Li 5526*8c35d5eeSXin Li self.UpdateWithLines(['#endif']) 5527*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.pp_stack), 0) 5528*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5529*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'D') 5530*8c35d5eeSXin Li self.assertFalse(self.nesting_state.stack[0].is_derived) 5531*8c35d5eeSXin Li self.assertFalse(self.nesting_state.stack[0].seen_open_brace) 5532*8c35d5eeSXin Li 5533*8c35d5eeSXin Li self.UpdateWithLines([';']) 5534*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 0) 5535*8c35d5eeSXin Li 5536*8c35d5eeSXin Li def testTemplate(self): 5537*8c35d5eeSXin Li self.UpdateWithLines(['template <T,', 5538*8c35d5eeSXin Li ' class Arg1 = tmpl<T> >']) 5539*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 0) 5540*8c35d5eeSXin Li self.UpdateWithLines(['class A {']) 5541*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5542*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo)) 5543*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'A') 5544*8c35d5eeSXin Li 5545*8c35d5eeSXin Li self.UpdateWithLines(['};', 5546*8c35d5eeSXin Li 'template <T,', 5547*8c35d5eeSXin Li ' template <typename, typename> class B>', 5548*8c35d5eeSXin Li 'class C']) 5549*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5550*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo)) 5551*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'C') 5552*8c35d5eeSXin Li self.UpdateWithLines([';']) 5553*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 0) 5554*8c35d5eeSXin Li 5555*8c35d5eeSXin Li self.UpdateWithLines(['class D : public Tmpl<E>']) 5556*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5557*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo)) 5558*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'D') 5559*8c35d5eeSXin Li 5560*8c35d5eeSXin Li self.UpdateWithLines(['{', '};']) 5561*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 0) 5562*8c35d5eeSXin Li 5563*8c35d5eeSXin Li self.UpdateWithLines(['template <class F,', 5564*8c35d5eeSXin Li ' class G,', 5565*8c35d5eeSXin Li ' class H,', 5566*8c35d5eeSXin Li ' typename I>', 5567*8c35d5eeSXin Li 'static void Func() {']) 5568*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5569*8c35d5eeSXin Li self.assertFalse(isinstance(self.nesting_state.stack[0], 5570*8c35d5eeSXin Li cpplint._ClassInfo)) 5571*8c35d5eeSXin Li self.UpdateWithLines(['}', 5572*8c35d5eeSXin Li 'template <class J> class K {']) 5573*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5574*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo)) 5575*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'K') 5576*8c35d5eeSXin Li 5577*8c35d5eeSXin Li def testTemplateInnerClass(self): 5578*8c35d5eeSXin Li self.UpdateWithLines(['class A {', 5579*8c35d5eeSXin Li ' public:']) 5580*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5581*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo)) 5582*8c35d5eeSXin Li 5583*8c35d5eeSXin Li self.UpdateWithLines([' template <class B>', 5584*8c35d5eeSXin Li ' class C<alloc<B> >', 5585*8c35d5eeSXin Li ' : public A {']) 5586*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 2) 5587*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo)) 5588*8c35d5eeSXin Li 5589*8c35d5eeSXin Li def testArguments(self): 5590*8c35d5eeSXin Li self.UpdateWithLines(['class A {']) 5591*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5592*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo)) 5593*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'A') 5594*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0) 5595*8c35d5eeSXin Li 5596*8c35d5eeSXin Li self.UpdateWithLines([' void Func(', 5597*8c35d5eeSXin Li ' struct X arg1,']) 5598*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5599*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1) 5600*8c35d5eeSXin Li self.UpdateWithLines([' struct X *arg2);']) 5601*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5602*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0) 5603*8c35d5eeSXin Li 5604*8c35d5eeSXin Li self.UpdateWithLines(['};']) 5605*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 0) 5606*8c35d5eeSXin Li 5607*8c35d5eeSXin Li self.UpdateWithLines(['struct B {']) 5608*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5609*8c35d5eeSXin Li self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo)) 5610*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[0].name, 'B') 5611*8c35d5eeSXin Li 5612*8c35d5eeSXin Li self.UpdateWithLines(['#ifdef MACRO', 5613*8c35d5eeSXin Li ' void Func(', 5614*8c35d5eeSXin Li ' struct X arg1']) 5615*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5616*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1) 5617*8c35d5eeSXin Li self.UpdateWithLines(['#else']) 5618*8c35d5eeSXin Li 5619*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5620*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0) 5621*8c35d5eeSXin Li self.UpdateWithLines([' void Func(', 5622*8c35d5eeSXin Li ' struct X arg1']) 5623*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5624*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1) 5625*8c35d5eeSXin Li 5626*8c35d5eeSXin Li self.UpdateWithLines(['#endif']) 5627*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5628*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1) 5629*8c35d5eeSXin Li self.UpdateWithLines([' struct X *arg2);']) 5630*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5631*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0) 5632*8c35d5eeSXin Li 5633*8c35d5eeSXin Li self.UpdateWithLines(['};']) 5634*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 0) 5635*8c35d5eeSXin Li 5636*8c35d5eeSXin Li def testInlineAssembly(self): 5637*8c35d5eeSXin Li self.UpdateWithLines(['void CopyRow_SSE2(const uint8* src, uint8* dst,', 5638*8c35d5eeSXin Li ' int count) {']) 5639*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5640*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0) 5641*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].inline_asm, cpplint._NO_ASM) 5642*8c35d5eeSXin Li 5643*8c35d5eeSXin Li self.UpdateWithLines([' asm volatile (']) 5644*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5645*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1) 5646*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].inline_asm, 5647*8c35d5eeSXin Li cpplint._INSIDE_ASM) 5648*8c35d5eeSXin Li 5649*8c35d5eeSXin Li self.UpdateWithLines([' "sub %0,%1 \\n"', 5650*8c35d5eeSXin Li ' "1: \\n"', 5651*8c35d5eeSXin Li ' "movdqa (%0),%%xmm0 \\n"', 5652*8c35d5eeSXin Li ' "movdqa 0x10(%0),%%xmm1 \\n"', 5653*8c35d5eeSXin Li ' "movdqa %%xmm0,(%0,%1) \\n"', 5654*8c35d5eeSXin Li ' "movdqa %%xmm1,0x10(%0,%1) \\n"', 5655*8c35d5eeSXin Li ' "lea 0x20(%0),%0 \\n"', 5656*8c35d5eeSXin Li ' "sub $0x20,%2 \\n"', 5657*8c35d5eeSXin Li ' "jg 1b \\n"', 5658*8c35d5eeSXin Li ' : "+r"(src), // %0', 5659*8c35d5eeSXin Li ' "+r"(dst), // %1', 5660*8c35d5eeSXin Li ' "+r"(count) // %2', 5661*8c35d5eeSXin Li ' :', 5662*8c35d5eeSXin Li ' : "memory", "cc"']) 5663*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5664*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1) 5665*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].inline_asm, 5666*8c35d5eeSXin Li cpplint._INSIDE_ASM) 5667*8c35d5eeSXin Li 5668*8c35d5eeSXin Li self.UpdateWithLines(['#if defined(__SSE2__)', 5669*8c35d5eeSXin Li ' , "xmm0", "xmm1"']) 5670*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5671*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1) 5672*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].inline_asm, 5673*8c35d5eeSXin Li cpplint._INSIDE_ASM) 5674*8c35d5eeSXin Li 5675*8c35d5eeSXin Li self.UpdateWithLines(['#endif']) 5676*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5677*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1) 5678*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].inline_asm, 5679*8c35d5eeSXin Li cpplint._INSIDE_ASM) 5680*8c35d5eeSXin Li 5681*8c35d5eeSXin Li self.UpdateWithLines([' );']) 5682*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5683*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0) 5684*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].inline_asm, cpplint._END_ASM) 5685*8c35d5eeSXin Li 5686*8c35d5eeSXin Li self.UpdateWithLines(['__asm {']) 5687*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 2) 5688*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0) 5689*8c35d5eeSXin Li self.assertEquals(self.nesting_state.stack[-1].inline_asm, 5690*8c35d5eeSXin Li cpplint._BLOCK_ASM) 5691*8c35d5eeSXin Li 5692*8c35d5eeSXin Li self.UpdateWithLines(['}']) 5693*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 1) 5694*8c35d5eeSXin Li 5695*8c35d5eeSXin Li self.UpdateWithLines(['}']) 5696*8c35d5eeSXin Li self.assertEquals(len(self.nesting_state.stack), 0) 5697*8c35d5eeSXin Li 5698*8c35d5eeSXin Li 5699*8c35d5eeSXin Liclass QuietTest(unittest.TestCase): 5700*8c35d5eeSXin Li 5701*8c35d5eeSXin Li def setUp(self): 5702*8c35d5eeSXin Li self.this_dir_path = os.path.dirname(os.path.abspath(__file__)) 5703*8c35d5eeSXin Li self.python_executable = sys.executable or 'python' 5704*8c35d5eeSXin Li self.cpplint_test_h = os.path.join(self.this_dir_path, 5705*8c35d5eeSXin Li 'cpplint_test_header.h') 5706*8c35d5eeSXin Li 5707*8c35d5eeSXin Li def _runCppLint(self, *args): 5708*8c35d5eeSXin Li cpplint_abspath = os.path.join(self.this_dir_path, 'cpplint.py') 5709*8c35d5eeSXin Li 5710*8c35d5eeSXin Li cmd_line = [self.python_executable, cpplint_abspath] + \ 5711*8c35d5eeSXin Li list(args) + \ 5712*8c35d5eeSXin Li [ self.cpplint_test_h ] 5713*8c35d5eeSXin Li 5714*8c35d5eeSXin Li return_code = 0 5715*8c35d5eeSXin Li try: 5716*8c35d5eeSXin Li output = subprocess.check_output(cmd_line, 5717*8c35d5eeSXin Li stderr=subprocess.STDOUT) 5718*8c35d5eeSXin Li except subprocess.CalledProcessError as err: 5719*8c35d5eeSXin Li return_code = err.returncode 5720*8c35d5eeSXin Li output = err.output 5721*8c35d5eeSXin Li 5722*8c35d5eeSXin Li return (return_code, output) 5723*8c35d5eeSXin Li 5724*8c35d5eeSXin Li def testNonQuietWithErrors(self): 5725*8c35d5eeSXin Li # This will fail: the test header is missing a copyright and header guard. 5726*8c35d5eeSXin Li (return_code, output) = self._runCppLint() 5727*8c35d5eeSXin Li self.assertEquals(1, return_code) 5728*8c35d5eeSXin Li # Always-on behavior: Print error messages as they come up. 5729*8c35d5eeSXin Li self.assertIn("[legal/copyright]", output) 5730*8c35d5eeSXin Li self.assertIn("[build/header_guard]", output) 5731*8c35d5eeSXin Li # If --quiet was unspecified: Print 'Done processing' and 'Total errors..' 5732*8c35d5eeSXin Li self.assertIn("Done processing", output) 5733*8c35d5eeSXin Li self.assertIn("Total errors found:", output) 5734*8c35d5eeSXin Li 5735*8c35d5eeSXin Li def testQuietWithErrors(self): 5736*8c35d5eeSXin Li # When there are errors, behavior is identical to not passing --quiet. 5737*8c35d5eeSXin Li (return_code, output) = self._runCppLint('--quiet') 5738*8c35d5eeSXin Li self.assertEquals(1, return_code) 5739*8c35d5eeSXin Li self.assertIn("[legal/copyright]", output) 5740*8c35d5eeSXin Li self.assertIn("[build/header_guard]", output) 5741*8c35d5eeSXin Li # Even though --quiet was used, print these since there were errors. 5742*8c35d5eeSXin Li self.assertIn("Done processing", output) 5743*8c35d5eeSXin Li self.assertIn("Total errors found:", output) 5744*8c35d5eeSXin Li 5745*8c35d5eeSXin Li def testNonQuietWithoutErrors(self): 5746*8c35d5eeSXin Li # This will succeed. We filtered out all the known errors for that file. 5747*8c35d5eeSXin Li (return_code, output) = self._runCppLint('--filter=' + 5748*8c35d5eeSXin Li '-legal/copyright,' + 5749*8c35d5eeSXin Li '-build/header_guard') 5750*8c35d5eeSXin Li self.assertEquals(0, return_code, output) 5751*8c35d5eeSXin Li # No cpplint errors are printed since there were no errors. 5752*8c35d5eeSXin Li self.assertNotIn("[legal/copyright]", output) 5753*8c35d5eeSXin Li self.assertNotIn("[build/header_guard]", output) 5754*8c35d5eeSXin Li # Print 'Done processing' and 'Total errors found' since 5755*8c35d5eeSXin Li # --quiet was not specified. 5756*8c35d5eeSXin Li self.assertIn("Done processing", output) 5757*8c35d5eeSXin Li self.assertIn("Total errors found:", output) 5758*8c35d5eeSXin Li 5759*8c35d5eeSXin Li def testQuietWithoutErrors(self): 5760*8c35d5eeSXin Li # This will succeed. We filtered out all the known errors for that file. 5761*8c35d5eeSXin Li (return_code, output) = self._runCppLint('--quiet', 5762*8c35d5eeSXin Li '--filter=' + 5763*8c35d5eeSXin Li '-legal/copyright,' + 5764*8c35d5eeSXin Li '-build/header_guard') 5765*8c35d5eeSXin Li self.assertEquals(0, return_code, output) 5766*8c35d5eeSXin Li # No cpplint errors are printed since there were no errors. 5767*8c35d5eeSXin Li self.assertNotIn("[legal/copyright]", output) 5768*8c35d5eeSXin Li self.assertNotIn("[build/header_guard]", output) 5769*8c35d5eeSXin Li # --quiet was specified and there were no errors: 5770*8c35d5eeSXin Li # skip the printing of 'Done processing' and 'Total errors..' 5771*8c35d5eeSXin Li self.assertNotIn("Done processing", output) 5772*8c35d5eeSXin Li self.assertNotIn("Total errors found:", output) 5773*8c35d5eeSXin Li # Output with no errors must be completely blank! 5774*8c35d5eeSXin Li self.assertEquals("", output) 5775*8c35d5eeSXin Li 5776*8c35d5eeSXin Li# pylint: disable-msg=C6409 5777*8c35d5eeSXin Lidef setUp(): 5778*8c35d5eeSXin Li """Runs before all tests are executed. 5779*8c35d5eeSXin Li """ 5780*8c35d5eeSXin Li # Enable all filters, so we don't miss anything that is off by default. 5781*8c35d5eeSXin Li cpplint._DEFAULT_FILTERS = [] 5782*8c35d5eeSXin Li cpplint._cpplint_state.SetFilters('') 5783*8c35d5eeSXin Li 5784*8c35d5eeSXin Li 5785*8c35d5eeSXin Li# pylint: disable-msg=C6409 5786*8c35d5eeSXin Lidef tearDown(): 5787*8c35d5eeSXin Li """A global check to make sure all error-categories have been tested. 5788*8c35d5eeSXin Li 5789*8c35d5eeSXin Li The main tearDown() routine is the only code we can guarantee will be 5790*8c35d5eeSXin Li run after all other tests have been executed. 5791*8c35d5eeSXin Li """ 5792*8c35d5eeSXin Li try: 5793*8c35d5eeSXin Li if _run_verifyallcategoriesseen: 5794*8c35d5eeSXin Li ErrorCollector(None).VerifyAllCategoriesAreSeen() 5795*8c35d5eeSXin Li except NameError: 5796*8c35d5eeSXin Li # If nobody set the global _run_verifyallcategoriesseen, then 5797*8c35d5eeSXin Li # we assume we should silently not run the test 5798*8c35d5eeSXin Li pass 5799*8c35d5eeSXin Li 5800*8c35d5eeSXin Li 5801*8c35d5eeSXin Liif __name__ == '__main__': 5802*8c35d5eeSXin Li # We don't want to run the VerifyAllCategoriesAreSeen() test unless 5803*8c35d5eeSXin Li # we're running the full test suite: if we only run one test, 5804*8c35d5eeSXin Li # obviously we're not going to see all the error categories. So we 5805*8c35d5eeSXin Li # only run VerifyAllCategoriesAreSeen() when no commandline flags 5806*8c35d5eeSXin Li # are passed in. 5807*8c35d5eeSXin Li global _run_verifyallcategoriesseen 5808*8c35d5eeSXin Li _run_verifyallcategoriesseen = (len(sys.argv) == 1) 5809*8c35d5eeSXin Li 5810*8c35d5eeSXin Li setUp() 5811*8c35d5eeSXin Li unittest.main() 5812*8c35d5eeSXin Li tearDown() 5813