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