blob: fd059fb01b75754b8055a7b3fc33afd53412497d [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
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +000040import sys
erg@google.com4e00b9a2009-01-12 23:05:11 +000041import unittest
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +000042
erg@google.com4e00b9a2009-01-12 23:05:11 +000043import cpplint
44
45
46# This class works as an error collector and replaces cpplint.Error
47# function for the unit tests. We also verify each category we see
48# is in cpplint._ERROR_CATEGORIES, to help keep that list up to date.
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +000049class ErrorCollector(object):
erg@google.com4e00b9a2009-01-12 23:05:11 +000050 # These are a global list, covering all categories seen ever.
erg+personal@google.com05189642010-04-30 20:43:03 +000051 _ERROR_CATEGORIES = cpplint._ERROR_CATEGORIES
erg@google.com4e00b9a2009-01-12 23:05:11 +000052 _SEEN_ERROR_CATEGORIES = {}
53
54 def __init__(self, assert_fn):
55 """assert_fn: a function to call when we notice a problem."""
56 self._assert_fn = assert_fn
57 self._errors = []
erg+personal@google.com05189642010-04-30 20:43:03 +000058 cpplint.ResetNolintSuppressions()
erg@google.com4e00b9a2009-01-12 23:05:11 +000059
erg+personal@google.com05189642010-04-30 20:43:03 +000060 def __call__(self, unused_filename, linenum,
erg@google.com4e00b9a2009-01-12 23:05:11 +000061 category, confidence, message):
62 self._assert_fn(category in self._ERROR_CATEGORIES,
63 'Message "%s" has category "%s",'
64 ' which is not in _ERROR_CATEGORIES' % (message, category))
65 self._SEEN_ERROR_CATEGORIES[category] = 1
erg+personal@google.com05189642010-04-30 20:43:03 +000066 if cpplint._ShouldPrintError(category, confidence, linenum):
erg@google.com4e00b9a2009-01-12 23:05:11 +000067 self._errors.append('%s [%s] [%d]' % (message, category, confidence))
68
69 def Results(self):
70 if len(self._errors) < 2:
71 return ''.join(self._errors) # Most tests expect to have a string.
72 else:
73 return self._errors # Let's give a list if there is more than one.
74
75 def ResultList(self):
76 return self._errors
77
78 def VerifyAllCategoriesAreSeen(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +000079 """Fails if there's a category in _ERROR_CATEGORIES~_SEEN_ERROR_CATEGORIES.
erg@google.com4e00b9a2009-01-12 23:05:11 +000080
81 This should only be called after all tests are run, so
82 _SEEN_ERROR_CATEGORIES has had a chance to fully populate. Since
83 this isn't called from within the normal unittest framework, we
84 can't use the normal unittest assert macros. Instead we just exit
85 when we see an error. Good thing this test is always run last!
86 """
87 for category in self._ERROR_CATEGORIES:
88 if category not in self._SEEN_ERROR_CATEGORIES:
erg@google.com4e00b9a2009-01-12 23:05:11 +000089 sys.exit('FATAL ERROR: There are no tests for category "%s"' % category)
90
91 def RemoveIfPresent(self, substr):
92 for (index, error) in enumerate(self._errors):
93 if error.find(substr) != -1:
94 self._errors = self._errors[0:index] + self._errors[(index + 1):]
95 break
96
erg@google.come35f7652009-06-19 20:52:09 +000097
98# This class is a lame mock of codecs. We do not verify filename, mode, or
99# encoding, but for the current use case it is not needed.
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000100class MockIo(object):
avakulenko@google.com02af6282014-06-04 18:53:25 +0000101
erg@google.come35f7652009-06-19 20:52:09 +0000102 def __init__(self, mock_file):
103 self.mock_file = mock_file
104
erg@google.comd350fe52013-01-14 17:51:48 +0000105 def open(self, # pylint: disable-msg=C6409
106 unused_filename, unused_mode, unused_encoding, _):
erg@google.come35f7652009-06-19 20:52:09 +0000107 return self.mock_file
108
109
erg@google.com4e00b9a2009-01-12 23:05:11 +0000110class CpplintTestBase(unittest.TestCase):
111 """Provides some useful helper functions for cpplint tests."""
112
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000113 def setUp(self):
114 # Allow subclasses to cheat os.path.abspath called in FileInfo class.
115 self.os_path_abspath_orig = os.path.abspath
116
117 def tearDown(self):
118 os.path.abspath = self.os_path_abspath_orig
119
erg@google.com4e00b9a2009-01-12 23:05:11 +0000120 # Perform lint on single line of input and return the error message.
121 def PerformSingleLineLint(self, code):
122 error_collector = ErrorCollector(self.assert_)
123 lines = code.split('\n')
124 cpplint.RemoveMultiLineComments('foo.h', lines, error_collector)
125 clean_lines = cpplint.CleansedLines(lines)
126 include_state = cpplint._IncludeState()
127 function_state = cpplint._FunctionState()
avakulenko@google.com02af6282014-06-04 18:53:25 +0000128 nesting_state = cpplint.NestingState()
erg@google.com4e00b9a2009-01-12 23:05:11 +0000129 cpplint.ProcessLine('foo.cc', 'cc', clean_lines, 0,
130 include_state, function_state,
erg@google.comd350fe52013-01-14 17:51:48 +0000131 nesting_state, error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000132 # Single-line lint tests are allowed to fail the 'unlintable function'
133 # check.
134 error_collector.RemoveIfPresent(
135 'Lint failed to find start of function body.')
136 return error_collector.Results()
137
138 # Perform lint over multiple lines and return the error message.
139 def PerformMultiLineLint(self, code):
140 error_collector = ErrorCollector(self.assert_)
141 lines = code.split('\n')
142 cpplint.RemoveMultiLineComments('foo.h', lines, error_collector)
143 lines = cpplint.CleansedLines(lines)
avakulenko@google.com02af6282014-06-04 18:53:25 +0000144 nesting_state = cpplint.NestingState()
erg@google.com4e00b9a2009-01-12 23:05:11 +0000145 for i in xrange(lines.NumLines()):
erg@google.comd350fe52013-01-14 17:51:48 +0000146 nesting_state.Update('foo.h', lines, i, error_collector)
147 cpplint.CheckStyle('foo.h', lines, i, 'h', nesting_state,
erg@google.com8a95ecc2011-09-08 00:45:54 +0000148 error_collector)
erg@google.comd350fe52013-01-14 17:51:48 +0000149 cpplint.CheckForNonStandardConstructs('foo.h', lines, i,
150 nesting_state, error_collector)
erg@google.com2aa59982013-10-28 19:09:25 +0000151 nesting_state.CheckCompletedBlocks('foo.h', error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000152 return error_collector.Results()
153
154 # Similar to PerformMultiLineLint, but calls CheckLanguage instead of
155 # CheckForNonStandardConstructs
156 def PerformLanguageRulesCheck(self, file_name, code):
157 error_collector = ErrorCollector(self.assert_)
158 include_state = cpplint._IncludeState()
avakulenko@google.com02af6282014-06-04 18:53:25 +0000159 nesting_state = cpplint.NestingState()
erg@google.com4e00b9a2009-01-12 23:05:11 +0000160 lines = code.split('\n')
161 cpplint.RemoveMultiLineComments(file_name, lines, error_collector)
162 lines = cpplint.CleansedLines(lines)
163 ext = file_name[file_name.rfind('.') + 1:]
164 for i in xrange(lines.NumLines()):
165 cpplint.CheckLanguage(file_name, lines, i, ext, include_state,
erg@google.comfd5da632013-10-25 17:39:45 +0000166 nesting_state, error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000167 return error_collector.Results()
168
169 def PerformFunctionLengthsCheck(self, code):
170 """Perform Lint function length check on block of code and return warnings.
171
172 Builds up an array of lines corresponding to the code and strips comments
173 using cpplint functions.
174
175 Establishes an error collector and invokes the function length checking
176 function following cpplint's pattern.
177
178 Args:
179 code: C++ source code expected to generate a warning message.
180
181 Returns:
182 The accumulated errors.
183 """
184 file_name = 'foo.cc'
185 error_collector = ErrorCollector(self.assert_)
186 function_state = cpplint._FunctionState()
187 lines = code.split('\n')
188 cpplint.RemoveMultiLineComments(file_name, lines, error_collector)
189 lines = cpplint.CleansedLines(lines)
190 for i in xrange(lines.NumLines()):
191 cpplint.CheckForFunctionLengths(file_name, lines, i,
192 function_state, error_collector)
193 return error_collector.Results()
194
erg@google.come35f7652009-06-19 20:52:09 +0000195 def PerformIncludeWhatYouUse(self, code, filename='foo.h', io=codecs):
erg@google.com4e00b9a2009-01-12 23:05:11 +0000196 # First, build up the include state.
197 error_collector = ErrorCollector(self.assert_)
198 include_state = cpplint._IncludeState()
avakulenko@google.com02af6282014-06-04 18:53:25 +0000199 nesting_state = cpplint.NestingState()
erg@google.com4e00b9a2009-01-12 23:05:11 +0000200 lines = code.split('\n')
201 cpplint.RemoveMultiLineComments(filename, lines, error_collector)
202 lines = cpplint.CleansedLines(lines)
203 for i in xrange(lines.NumLines()):
204 cpplint.CheckLanguage(filename, lines, i, '.h', include_state,
erg@google.comfd5da632013-10-25 17:39:45 +0000205 nesting_state, error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000206 # We could clear the error_collector here, but this should
207 # also be fine, since our IncludeWhatYouUse unittests do not
208 # have language problems.
209
210 # Second, look for missing includes.
211 cpplint.CheckForIncludeWhatYouUse(filename, lines, include_state,
erg@google.come35f7652009-06-19 20:52:09 +0000212 error_collector, io)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000213 return error_collector.Results()
214
215 # Perform lint and compare the error message with "expected_message".
216 def TestLint(self, code, expected_message):
217 self.assertEquals(expected_message, self.PerformSingleLineLint(code))
218
219 def TestMultiLineLint(self, code, expected_message):
220 self.assertEquals(expected_message, self.PerformMultiLineLint(code))
221
222 def TestMultiLineLintRE(self, code, expected_message_re):
223 message = self.PerformMultiLineLint(code)
224 if not re.search(expected_message_re, message):
225 self.fail('Message was:\n' + message + 'Expected match to "' +
226 expected_message_re + '"')
227
228 def TestLanguageRulesCheck(self, file_name, code, expected_message):
229 self.assertEquals(expected_message,
230 self.PerformLanguageRulesCheck(file_name, code))
231
232 def TestIncludeWhatYouUse(self, code, expected_message):
233 self.assertEquals(expected_message,
234 self.PerformIncludeWhatYouUse(code))
235
236 def TestBlankLinesCheck(self, lines, start_errors, end_errors):
237 error_collector = ErrorCollector(self.assert_)
238 cpplint.ProcessFileData('foo.cc', 'cc', lines, error_collector)
239 self.assertEquals(
240 start_errors,
241 error_collector.Results().count(
erg@google.com2aa59982013-10-28 19:09:25 +0000242 'Redundant blank line at the start of a code block '
243 'should be deleted. [whitespace/blank_line] [2]'))
erg@google.com4e00b9a2009-01-12 23:05:11 +0000244 self.assertEquals(
245 end_errors,
246 error_collector.Results().count(
erg@google.com2aa59982013-10-28 19:09:25 +0000247 'Redundant blank line at the end of a code block '
248 'should be deleted. [whitespace/blank_line] [3]'))
erg@google.com4e00b9a2009-01-12 23:05:11 +0000249
250
251class CpplintTest(CpplintTestBase):
252
avakulenko@google.com554223d2014-12-04 22:00:20 +0000253 def GetNamespaceResults(self, lines):
254 error_collector = ErrorCollector(self.assert_)
255 cpplint.RemoveMultiLineComments('foo.h', lines, error_collector)
256 lines = cpplint.CleansedLines(lines)
257 nesting_state = cpplint.NestingState()
258 for i in xrange(lines.NumLines()):
259 nesting_state.Update('foo.h', lines, i, error_collector)
260 cpplint.CheckForNamespaceIndentation('foo.h', nesting_state,
261 lines, i, error_collector)
262
263 return error_collector.Results()
264
265 def testForwardDeclarationNameSpaceIndentation(self):
266 lines = ['namespace Test {',
267 ' class ForwardDeclaration;',
268 '} // namespace Test']
269
270 results = self.GetNamespaceResults(lines)
271 self.assertEquals(results, 'Do not indent within a namespace '
272 ' [runtime/indentation_namespace] [4]')
273
274 def testNameSpaceIndentationForClass(self):
275 lines = ['namespace Test {',
276 'void foo() { }',
277 ' class Test {',
278 ' };',
279 '} // namespace Test']
280
281 results = self.GetNamespaceResults(lines)
282 self.assertEquals(results, 'Do not indent within a namespace '
283 ' [runtime/indentation_namespace] [4]')
284
285 def testNameSpaceIndentationNoError(self):
286 lines = ['namespace Test {',
287 'void foo() { }',
288 '} // namespace Test']
289
290 results = self.GetNamespaceResults(lines)
291 self.assertEquals(results, '')
292
Alex Vakulenko01e47232016-05-06 13:54:15 -0700293 def testWhitespaceBeforeNamespace(self):
294 lines = [' namespace Test {',
295 ' void foo() { }',
296 ' } // namespace Test']
297
298 results = self.GetNamespaceResults(lines)
299 self.assertEquals(results, '')
300
avakulenko@google.com554223d2014-12-04 22:00:20 +0000301 def testFalsePositivesNoError(self):
302 lines = ['namespace Test {',
303 'struct OuterClass {',
304 ' struct NoFalsePositivesHere;',
305 ' struct NoFalsePositivesHere member_variable;',
306 '};',
307 '} // namespace Test']
308
309 results = self.GetNamespaceResults(lines)
310 self.assertEquals(results, '')
311
312
erg@google.com4e00b9a2009-01-12 23:05:11 +0000313 # Test get line width.
314 def testGetLineWidth(self):
315 self.assertEquals(0, cpplint.GetLineWidth(''))
316 self.assertEquals(10, cpplint.GetLineWidth(u'x' * 10))
317 self.assertEquals(16, cpplint.GetLineWidth(u'都|道|府|県|支庁'))
318
erg@google.com8a95ecc2011-09-08 00:45:54 +0000319 def testGetTextInside(self):
320 self.assertEquals('', cpplint._GetTextInside('fun()', r'fun\('))
321 self.assertEquals('x, y', cpplint._GetTextInside('f(x, y)', r'f\('))
322 self.assertEquals('a(), b(c())', cpplint._GetTextInside(
323 'printf(a(), b(c()))', r'printf\('))
324 self.assertEquals('x, y{}', cpplint._GetTextInside('f[x, y{}]', r'f\['))
325 self.assertEquals(None, cpplint._GetTextInside('f[a, b(}]', r'f\['))
326 self.assertEquals(None, cpplint._GetTextInside('f[x, y]', r'f\('))
327 self.assertEquals('y, h(z, (a + b))', cpplint._GetTextInside(
328 'f(x, g(y, h(z, (a + b))))', r'g\('))
329 self.assertEquals('f(f(x))', cpplint._GetTextInside('f(f(f(x)))', r'f\('))
330 # Supports multiple lines.
331 self.assertEquals('\n return loop(x);\n',
332 cpplint._GetTextInside(
333 'int loop(int x) {\n return loop(x);\n}\n', r'\{'))
avakulenko@google.com02af6282014-06-04 18:53:25 +0000334 # '^' matches the beginning of each line.
erg@google.com8a95ecc2011-09-08 00:45:54 +0000335 self.assertEquals('x, y',
336 cpplint._GetTextInside(
337 '#include "inl.h" // skip #define\n'
338 '#define A2(x, y) a_inl_(x, y, __LINE__)\n'
339 '#define A(x) a_inl_(x, "", __LINE__)\n',
340 r'^\s*#define\s*\w+\('))
341
erg@google.com4e00b9a2009-01-12 23:05:11 +0000342 def testFindNextMultiLineCommentStart(self):
343 self.assertEquals(1, cpplint.FindNextMultiLineCommentStart([''], 0))
344
345 lines = ['a', 'b', '/* c']
346 self.assertEquals(2, cpplint.FindNextMultiLineCommentStart(lines, 0))
347
348 lines = ['char a[] = "/*";'] # not recognized as comment.
349 self.assertEquals(1, cpplint.FindNextMultiLineCommentStart(lines, 0))
350
351 def testFindNextMultiLineCommentEnd(self):
352 self.assertEquals(1, cpplint.FindNextMultiLineCommentEnd([''], 0))
353 lines = ['a', 'b', ' c */']
354 self.assertEquals(2, cpplint.FindNextMultiLineCommentEnd(lines, 0))
355
356 def testRemoveMultiLineCommentsFromRange(self):
357 lines = ['a', ' /* comment ', ' * still comment', ' comment */ ', 'b']
358 cpplint.RemoveMultiLineCommentsFromRange(lines, 1, 4)
avakulenko@google.com554223d2014-12-04 22:00:20 +0000359 self.assertEquals(['a', '/**/', '/**/', '/**/', 'b'], lines)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000360
361 def testSpacesAtEndOfLine(self):
362 self.TestLint(
363 '// Hello there ',
364 'Line ends in whitespace. Consider deleting these extra spaces.'
365 ' [whitespace/end_of_line] [4]')
366
367 # Test line length check.
368 def testLineLengthCheck(self):
369 self.TestLint(
370 '// Hello',
371 '')
372 self.TestLint(
Alex Vakulenko01e47232016-05-06 13:54:15 -0700373 '// x' + ' x' * 40,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000374 'Lines should be <= 80 characters long'
375 ' [whitespace/line_length] [2]')
376 self.TestLint(
Alex Vakulenko01e47232016-05-06 13:54:15 -0700377 '// x' + ' x' * 50,
378 'Lines should be <= 80 characters long'
379 ' [whitespace/line_length] [2]')
380 self.TestLint(
381 '// //some/path/to/f' + ('i' * 100) + 'le',
382 '')
383 self.TestLint(
384 '// //some/path/to/f' + ('i' * 100) + 'le',
385 '')
386 self.TestLint(
387 '// //some/path/to/f' + ('i' * 50) + 'le and some comments',
388 'Lines should be <= 80 characters long'
389 ' [whitespace/line_length] [2]')
erg@google.coma87abb82009-02-24 01:41:01 +0000390 self.TestLint(
391 '// http://g' + ('o' * 100) + 'gle.com/',
392 '')
393 self.TestLint(
394 '// https://g' + ('o' * 100) + 'gle.com/',
395 '')
396 self.TestLint(
397 '// https://g' + ('o' * 60) + 'gle.com/ and some comments',
398 'Lines should be <= 80 characters long'
399 ' [whitespace/line_length] [2]')
erg@google.com36649102009-03-25 21:18:36 +0000400 self.TestLint(
avakulenko@google.com554223d2014-12-04 22:00:20 +0000401 '// Read https://g' + ('o' * 60) + 'gle.com/',
erg@google.com36649102009-03-25 21:18:36 +0000402 '')
erg@google.comd7d27472011-09-07 17:36:35 +0000403 self.TestLint(
404 '// $Id: g' + ('o' * 80) + 'gle.cc#1 $',
405 '')
406 self.TestLint(
407 '// $Id: g' + ('o' * 80) + 'gle.cc#1',
408 'Lines should be <= 80 characters long'
409 ' [whitespace/line_length] [2]')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000410 self.TestMultiLineLint(
411 'static const char kCStr[] = "g' + ('o' * 50) + 'gle";\n',
412 'Lines should be <= 80 characters long'
413 ' [whitespace/line_length] [2]')
414 self.TestMultiLineLint(
415 'static const char kRawStr[] = R"(g' + ('o' * 50) + 'gle)";\n',
416 '') # no warning because raw string content is elided
417 self.TestMultiLineLint(
418 'static const char kMultiLineRawStr[] = R"(\n'
419 'g' + ('o' * 80) + 'gle\n'
420 ')";',
421 '')
422 self.TestMultiLineLint(
423 'static const char kL' + ('o' * 50) + 'ngIdentifier[] = R"()";\n',
424 'Lines should be <= 80 characters long'
425 ' [whitespace/line_length] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000426
erg+personal@google.com05189642010-04-30 20:43:03 +0000427 # Test error suppression annotations.
428 def testErrorSuppression(self):
429 # Two errors on same line:
430 self.TestLint(
431 'long a = (int64) 65;',
432 ['Using C-style cast. Use static_cast<int64>(...) instead'
433 ' [readability/casting] [4]',
434 'Use int16/int64/etc, rather than the C type long'
435 ' [runtime/int] [4]',
erg@google.com8a95ecc2011-09-08 00:45:54 +0000436 ])
erg+personal@google.com05189642010-04-30 20:43:03 +0000437 # One category of error suppressed:
438 self.TestLint(
439 'long a = (int64) 65; // NOLINT(runtime/int)',
440 'Using C-style cast. Use static_cast<int64>(...) instead'
441 ' [readability/casting] [4]')
442 # All categories suppressed: (two aliases)
443 self.TestLint('long a = (int64) 65; // NOLINT', '')
444 self.TestLint('long a = (int64) 65; // NOLINT(*)', '')
445 # Malformed NOLINT directive:
446 self.TestLint(
447 'long a = 65; // NOLINT(foo)',
erg@google.com8a95ecc2011-09-08 00:45:54 +0000448 ['Unknown NOLINT error category: foo'
449 ' [readability/nolint] [5]',
450 'Use int16/int64/etc, rather than the C type long [runtime/int] [4]',
451 ])
erg+personal@google.com05189642010-04-30 20:43:03 +0000452 # Irrelevant NOLINT directive has no effect:
453 self.TestLint(
454 'long a = 65; // NOLINT(readability/casting)',
erg@google.com8a95ecc2011-09-08 00:45:54 +0000455 'Use int16/int64/etc, rather than the C type long'
avakulenko@google.com02af6282014-06-04 18:53:25 +0000456 ' [runtime/int] [4]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000457 # NOLINTNEXTLINE silences warning for the next line instead of current line
458 error_collector = ErrorCollector(self.assert_)
459 cpplint.ProcessFileData('test.cc', 'cc',
460 ['// Copyright 2014 Your Company.',
461 '// NOLINTNEXTLINE(whitespace/line_length)',
462 '// ./command' + (' -verbose' * 80),
463 ''],
464 error_collector)
465 self.assertEquals('', error_collector.Results())
Alex Vakulenko01e47232016-05-06 13:54:15 -0700466 # LINT_C_FILE silences cast warnings for entire file.
467 error_collector = ErrorCollector(self.assert_)
468 cpplint.ProcessFileData('test.h', 'h',
469 ['// Copyright 2014 Your Company.',
470 '// NOLINT(build/header_guard)',
471 'int64 a = (uint64) 65;',
472 '// LINT_C_FILE',
473 ''],
474 error_collector)
475 self.assertEquals('', error_collector.Results())
476 # Vim modes silence cast warnings for entire file.
477 for modeline in ['vi:filetype=c',
478 'vi:sw=8 filetype=c',
479 'vi:sw=8 filetype=c ts=8',
480 'vi: filetype=c',
481 'vi: sw=8 filetype=c',
482 'vi: sw=8 filetype=c ts=8',
483 'vim:filetype=c',
484 'vim:sw=8 filetype=c',
485 'vim:sw=8 filetype=c ts=8',
486 'vim: filetype=c',
487 'vim: sw=8 filetype=c',
488 'vim: sw=8 filetype=c ts=8',
489 'vim: set filetype=c:',
490 'vim: set sw=8 filetype=c:',
491 'vim: set sw=8 filetype=c ts=8:',
492 'vim: set filetype=c :',
493 'vim: set sw=8 filetype=c :',
494 'vim: set sw=8 filetype=c ts=8 :',
495 'vim: se filetype=c:',
496 'vim: se sw=8 filetype=c:',
497 'vim: se sw=8 filetype=c ts=8:',
498 'vim: se filetype=c :',
499 'vim: se sw=8 filetype=c :',
500 'vim: se sw=8 filetype=c ts=8 :']:
501 error_collector = ErrorCollector(self.assert_)
502 cpplint.ProcessFileData('test.h', 'h',
503 ['// Copyright 2014 Your Company.',
504 '// NOLINT(build/header_guard)',
505 'int64 a = (uint64) 65;',
506 '/* Prevent warnings about the modeline',
507 modeline,
508 '*/',
509 ''],
510 error_collector)
511 self.assertEquals('', error_collector.Results())
512 # LINT_KERNEL_FILE silences whitespace/tab warnings for entire file.
513 error_collector = ErrorCollector(self.assert_)
514 cpplint.ProcessFileData('test.h', 'h',
515 ['// Copyright 2014 Your Company.',
516 '// NOLINT(build/header_guard)',
517 'struct test {',
518 '\tint member;',
519 '};',
520 '// LINT_KERNEL_FILE',
521 ''],
522 error_collector)
523 self.assertEquals('', error_collector.Results())
erg+personal@google.com05189642010-04-30 20:43:03 +0000524
erg@google.com4e00b9a2009-01-12 23:05:11 +0000525 # Test Variable Declarations.
526 def testVariableDeclarations(self):
527 self.TestLint(
528 'long a = 65;',
529 'Use int16/int64/etc, rather than the C type long'
530 ' [runtime/int] [4]')
531 self.TestLint(
532 'long double b = 65.0;',
533 '')
534 self.TestLint(
535 'long long aa = 6565;',
536 'Use int16/int64/etc, rather than the C type long'
537 ' [runtime/int] [4]')
538
539 # Test C-style cast cases.
540 def testCStyleCast(self):
541 self.TestLint(
542 'int a = (int)1.0;',
543 'Using C-style cast. Use static_cast<int>(...) instead'
544 ' [readability/casting] [4]')
545 self.TestLint(
avakulenko@google.com554223d2014-12-04 22:00:20 +0000546 'int a = (int)-1.0;',
547 'Using C-style cast. Use static_cast<int>(...) instead'
548 ' [readability/casting] [4]')
549 self.TestLint(
erg@google.com8f91ab22011-09-06 21:04:45 +0000550 'int *a = (int *)NULL;',
erg@google.com4e00b9a2009-01-12 23:05:11 +0000551 'Using C-style cast. Use reinterpret_cast<int *>(...) instead'
552 ' [readability/casting] [4]')
553
554 self.TestLint(
555 'uint16 a = (uint16)1.0;',
556 'Using C-style cast. Use static_cast<uint16>(...) instead'
557 ' [readability/casting] [4]')
558 self.TestLint(
559 'int32 a = (int32)1.0;',
560 'Using C-style cast. Use static_cast<int32>(...) instead'
561 ' [readability/casting] [4]')
562 self.TestLint(
563 'uint64 a = (uint64)1.0;',
564 'Using C-style cast. Use static_cast<uint64>(...) instead'
565 ' [readability/casting] [4]')
566
567 # These shouldn't be recognized casts.
568 self.TestLint('u a = (u)NULL;', '')
569 self.TestLint('uint a = (uint)NULL;', '')
erg@google.comc6671232013-10-25 21:44:03 +0000570 self.TestLint('typedef MockCallback<int(int)> CallbackType;', '')
571 self.TestLint('scoped_ptr< MockCallback<int(int)> > callback_value;', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000572 self.TestLint('std::function<int(bool)>', '')
573 self.TestLint('x = sizeof(int)', '')
574 self.TestLint('x = alignof(int)', '')
575 self.TestLint('alignas(int) char x[42]', '')
576 self.TestLint('alignas(alignof(x)) char y[42]', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +0000577 self.TestLint('void F(int (func)(int));', '')
578 self.TestLint('void F(int (func)(int*));', '')
579 self.TestLint('void F(int (Class::member)(int));', '')
580 self.TestLint('void F(int (Class::member)(int*));', '')
581 self.TestLint('void F(int (Class::member)(int), int param);', '')
582 self.TestLint('void F(int (Class::member)(int*), int param);', '')
583
584 # These should not be recognized (lambda functions without arg names).
585 self.TestLint('[](int/*unused*/) -> bool {', '')
586 self.TestLint('[](int /*unused*/) -> bool {', '')
587 self.TestLint('auto f = [](MyStruct* /*unused*/)->int {', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -0700588 self.TestLint('[](int) -> bool {', '')
589 self.TestLint('auto f = [](MyStruct*)->int {', '')
590
591 # Cast with brace initializers
592 self.TestLint('int64_t{4096} * 1000 * 1000', '')
593 self.TestLint('size_t{4096} * 1000 * 1000', '')
594 self.TestLint('uint_fast16_t{4096} * 1000 * 1000', '')
595
596 # Brace initializer with templated type
597 self.TestMultiLineLint(
598 """
599 template <typename Type1,
600 typename Type2>
601 void Function(int arg1,
602 int arg2) {
603 variable &= ~Type1{0} - 1;
604 }""",
605 '')
606 self.TestMultiLineLint(
607 """
608 template <typename Type>
609 class Class {
610 void Function() {
611 variable &= ~Type{0} - 1;
612 }
613 };""",
614 '')
615 self.TestMultiLineLint(
616 """
617 template <typename Type>
618 class Class {
619 void Function() {
620 variable &= ~Type{0} - 1;
621 }
622 };""",
623 '')
624 self.TestMultiLineLint(
625 """
626 namespace {
627 template <typename Type>
628 class Class {
629 void Function() {
630 if (block) {
631 variable &= ~Type{0} - 1;
632 }
633 }
634 };
635 }""",
636 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000637
638 # Test taking address of casts (runtime/casting)
639 def testRuntimeCasting(self):
erg@google.comc6671232013-10-25 21:44:03 +0000640 error_msg = ('Are you taking an address of a cast? '
641 'This is dangerous: could be a temp var. '
642 'Take the address before doing the cast, rather than after'
643 ' [runtime/casting] [4]')
644 self.TestLint('int* x = &static_cast<int*>(foo);', error_msg)
645 self.TestLint('int* x = &reinterpret_cast<int *>(foo);', error_msg)
646 self.TestLint('int* x = &(int*)foo;',
647 ['Using C-style cast. Use reinterpret_cast<int*>(...) '
648 'instead [readability/casting] [4]',
649 error_msg])
avakulenko@google.com554223d2014-12-04 22:00:20 +0000650 self.TestLint('BudgetBuckets&(BudgetWinHistory::*BucketFn)(void) const;',
651 '')
652 self.TestLint('&(*func_ptr)(arg)', '')
653 self.TestLint('Compute(arg, &(*func_ptr)(i, j));', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000654
avakulenko@google.com02af6282014-06-04 18:53:25 +0000655 # Alternative error message
656 alt_error_msg = ('Are you taking an address of something dereferenced '
657 'from a cast? Wrapping the dereferenced expression in '
658 'parentheses will make the binding more obvious'
659 ' [readability/casting] [4]')
660 self.TestLint('int* x = &down_cast<Obj*>(obj)->member_;', alt_error_msg)
661 self.TestLint('int* x = &down_cast<Obj*>(obj)[index];', alt_error_msg)
662 self.TestLint('int* x = &(down_cast<Obj*>(obj)->member_);', '')
663 self.TestLint('int* x = &(down_cast<Obj*>(obj)[index]);', '')
664 self.TestLint('int* x = &down_cast<Obj*>(obj)\n->member_;', alt_error_msg)
665 self.TestLint('int* x = &(down_cast<Obj*>(obj)\n->member_);', '')
666
erg@google.com4e00b9a2009-01-12 23:05:11 +0000667 # It's OK to cast an address.
erg@google.comc6671232013-10-25 21:44:03 +0000668 self.TestLint('int* x = reinterpret_cast<int *>(&foo);', '')
669
670 # Function pointers returning references should not be confused
671 # with taking address of old-style casts.
672 self.TestLint('auto x = implicit_cast<string &(*)(int)>(&foo);', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000673
674 def testRuntimeSelfinit(self):
675 self.TestLint(
676 'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }',
677 'You seem to be initializing a member variable with itself.'
678 ' [runtime/init] [4]')
679 self.TestLint(
Alex Vakulenko01e47232016-05-06 13:54:15 -0700680 'Foo::Foo(Bar r, Bel l) : r_(CHECK_NOTNULL(r_)) { }',
681 'You seem to be initializing a member variable with itself.'
682 ' [runtime/init] [4]')
683 self.TestLint(
erg@google.com4e00b9a2009-01-12 23:05:11 +0000684 'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }',
685 '')
686 self.TestLint(
687 'Foo::Foo(Bar r) : r_(r), l_(r_), ll_(l_) { }',
688 '')
689
erg@google.com4e00b9a2009-01-12 23:05:11 +0000690 # Test for unnamed arguments in a method.
691 def testCheckForUnnamedParams(self):
Alex Vakulenko01e47232016-05-06 13:54:15 -0700692 self.TestLint('virtual void Func(int*) const;', '')
693 self.TestLint('virtual void Func(int*);', '')
694 self.TestLint('void Method(char*) {', '')
695 self.TestLint('void Method(char*);', '')
696 self.TestLint('static void operator delete[](void*) throw();', '')
697 self.TestLint('int Method(int);', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000698
avakulenko@google.com02af6282014-06-04 18:53:25 +0000699 self.TestLint('virtual void Func(int* p);', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000700 self.TestLint('void operator delete(void* x) throw();', '')
701 self.TestLint('void Method(char* x) {', '')
702 self.TestLint('void Method(char* /*x*/) {', '')
703 self.TestLint('void Method(char* x);', '')
704 self.TestLint('typedef void (*Method)(int32 x);', '')
705 self.TestLint('static void operator delete[](void* x) throw();', '')
706 self.TestLint('static void operator delete[](void* /*x*/) throw();', '')
707
erg@google.comd350fe52013-01-14 17:51:48 +0000708 self.TestLint('X operator++(int);', '')
709 self.TestLint('X operator++(int) {', '')
710 self.TestLint('X operator--(int);', '')
711 self.TestLint('X operator--(int /*unused*/) {', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000712 self.TestLint('MACRO(int);', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +0000713 self.TestLint('MACRO(func(int));', '')
714 self.TestLint('MACRO(arg, func(int));', '')
erg@google.comd350fe52013-01-14 17:51:48 +0000715
erg@google.comc6671232013-10-25 21:44:03 +0000716 self.TestLint('void (*func)(void*);', '')
717 self.TestLint('void Func((*func)(void*)) {}', '')
718 self.TestLint('template <void Func(void*)> void func();', '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000719 self.TestLint('virtual void f(int /*unused*/) {', '')
720 self.TestLint('void f(int /*unused*/) override {', '')
721 self.TestLint('void f(int /*unused*/) final {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000722
723 # Test deprecated casts such as int(d)
724 def testDeprecatedCast(self):
725 self.TestLint(
726 'int a = int(2.2);',
727 'Using deprecated casting style. '
728 'Use static_cast<int>(...) instead'
729 ' [readability/casting] [4]')
erg@google.com8a95ecc2011-09-08 00:45:54 +0000730
731 self.TestLint(
732 '(char *) "foo"',
733 'Using C-style cast. '
734 'Use const_cast<char *>(...) instead'
735 ' [readability/casting] [4]')
736
737 self.TestLint(
738 '(int*)foo',
739 'Using C-style cast. '
740 'Use reinterpret_cast<int*>(...) instead'
741 ' [readability/casting] [4]')
742
erg@google.com4e00b9a2009-01-12 23:05:11 +0000743 # Checks for false positives...
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000744 self.TestLint('int a = int();', '') # constructor
745 self.TestLint('X::X() : a(int()) {}', '') # default constructor
746 self.TestLint('operator bool();', '') # Conversion operator
747 self.TestLint('new int64(123);', '') # "new" operator on basic type
748 self.TestLint('new int64(123);', '') # "new" operator on basic type
Alex Vakulenko01e47232016-05-06 13:54:15 -0700749 self.TestLint('new const int(42);', '') # "new" on const-qualified type
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000750 self.TestLint('using a = bool(int arg);', '') # C++11 alias-declaration
751 self.TestLint('x = bit_cast<double(*)[3]>(y);', '') # array of array
752 self.TestLint('void F(const char(&src)[N]);', '') # array of references
753
754 # Placement new
avakulenko@google.com02af6282014-06-04 18:53:25 +0000755 self.TestLint(
756 'new(field_ptr) int(field->default_value_enum()->number());',
757 '')
758
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000759 # C++11 function wrappers
760 self.TestLint('std::function<int(bool)>', '')
761 self.TestLint('std::function<const int(bool)>', '')
762 self.TestLint('std::function< int(bool) >', '')
763 self.TestLint('mfunction<int(bool)>', '')
764
avakulenko@google.com02af6282014-06-04 18:53:25 +0000765 error_collector = ErrorCollector(self.assert_)
766 cpplint.ProcessFileData(
767 'test.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000768 ['// Copyright 2014 Your Company. All Rights Reserved.',
avakulenko@google.com02af6282014-06-04 18:53:25 +0000769 'typedef std::function<',
770 ' bool(int)> F;',
771 ''],
772 error_collector)
773 self.assertEquals('', error_collector.Results())
erg@google.comc6671232013-10-25 21:44:03 +0000774
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000775 # Return types for function pointers
776 self.TestLint('typedef bool(FunctionPointer)();', '')
777 self.TestLint('typedef bool(FunctionPointer)(int param);', '')
778 self.TestLint('typedef bool(MyClass::*MemberFunctionPointer)();', '')
779 self.TestLint('typedef bool(MyClass::* MemberFunctionPointer)();', '')
780 self.TestLint('typedef bool(MyClass::*MemberFunctionPointer)() const;', '')
781 self.TestLint('void Function(bool(FunctionPointerArg)());', '')
782 self.TestLint('void Function(bool(FunctionPointerArg)()) {}', '')
783 self.TestLint('typedef set<int64, bool(*)(int64, int64)> SortedIdSet', '')
erg@google.comc6671232013-10-25 21:44:03 +0000784 self.TestLint(
785 'bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *t)) {}',
786 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000787
788 # The second parameter to a gMock method definition is a function signature
789 # that often looks like a bad cast but should not picked up by lint.
790 def testMockMethod(self):
791 self.TestLint(
792 'MOCK_METHOD0(method, int());',
793 '')
794 self.TestLint(
795 'MOCK_CONST_METHOD1(method, float(string));',
796 '')
797 self.TestLint(
798 'MOCK_CONST_METHOD2_T(method, double(float, float));',
799 '')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000800 self.TestLint(
801 'MOCK_CONST_METHOD1(method, SomeType(int));',
802 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000803
erg@google.comd350fe52013-01-14 17:51:48 +0000804 error_collector = ErrorCollector(self.assert_)
805 cpplint.ProcessFileData('mock.cc', 'cc',
806 ['MOCK_METHOD1(method1,',
erg@google.comc6671232013-10-25 21:44:03 +0000807 ' bool(int));',
808 'MOCK_METHOD1(',
809 ' method2,',
810 ' bool(int));',
811 'MOCK_CONST_METHOD2(',
812 ' method3, bool(int,',
813 ' int));',
814 'MOCK_METHOD1(method4, int(bool));',
erg@google.comd350fe52013-01-14 17:51:48 +0000815 'const int kConstant = int(42);'], # true positive
816 error_collector)
817 self.assertEquals(
818 0,
819 error_collector.Results().count(
820 ('Using deprecated casting style. '
821 'Use static_cast<bool>(...) instead '
822 '[readability/casting] [4]')))
823 self.assertEquals(
824 1,
825 error_collector.Results().count(
826 ('Using deprecated casting style. '
827 'Use static_cast<int>(...) instead '
828 '[readability/casting] [4]')))
829
erg@google.comd7d27472011-09-07 17:36:35 +0000830 # Like gMock method definitions, MockCallback instantiations look very similar
831 # to bad casts.
832 def testMockCallback(self):
833 self.TestLint(
834 'MockCallback<bool(int)>',
835 '')
836 self.TestLint(
837 'MockCallback<int(float, char)>',
838 '')
839
erg@google.come35f7652009-06-19 20:52:09 +0000840 # Test false errors that happened with some include file names
841 def testIncludeFilenameFalseError(self):
842 self.TestLint(
843 '#include "foo/long-foo.h"',
844 '')
845 self.TestLint(
846 '#include "foo/sprintf.h"',
847 '')
848
erg@google.com4e00b9a2009-01-12 23:05:11 +0000849 # Test typedef cases. There was a bug that cpplint misidentified
850 # typedef for pointer to function as C-style cast and produced
851 # false-positive error messages.
852 def testTypedefForPointerToFunction(self):
853 self.TestLint(
854 'typedef void (*Func)(int x);',
855 '')
856 self.TestLint(
857 'typedef void (*Func)(int *x);',
858 '')
859 self.TestLint(
860 'typedef void Func(int x);',
861 '')
862 self.TestLint(
863 'typedef void Func(int *x);',
864 '')
865
866 def testIncludeWhatYouUseNoImplementationFiles(self):
867 code = 'std::vector<int> foo;'
868 self.assertEquals('Add #include <vector> for vector<>'
869 ' [build/include_what_you_use] [4]',
870 self.PerformIncludeWhatYouUse(code, 'foo.h'))
871 self.assertEquals('',
872 self.PerformIncludeWhatYouUse(code, 'foo.cc'))
873
874 def testIncludeWhatYouUse(self):
875 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000876 """#include <vector>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000877 std::vector<int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000878 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000879 '')
880 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000881 """#include <map>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000882 std::pair<int,int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000883 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000884 'Add #include <utility> for pair<>'
885 ' [build/include_what_you_use] [4]')
886 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000887 """#include <multimap>
888 std::pair<int,int> foo;
889 """,
890 'Add #include <utility> for pair<>'
891 ' [build/include_what_you_use] [4]')
892 self.TestIncludeWhatYouUse(
893 """#include <hash_map>
894 std::pair<int,int> foo;
895 """,
896 'Add #include <utility> for pair<>'
897 ' [build/include_what_you_use] [4]')
898 self.TestIncludeWhatYouUse(
899 """#include <utility>
900 std::pair<int,int> foo;
901 """,
902 '')
903 self.TestIncludeWhatYouUse(
904 """#include <vector>
905 DECLARE_string(foobar);
906 """,
907 '')
908 self.TestIncludeWhatYouUse(
909 """#include <vector>
910 DEFINE_string(foobar, "", "");
911 """,
912 '')
913 self.TestIncludeWhatYouUse(
914 """#include <vector>
915 std::pair<int,int> foo;
916 """,
917 'Add #include <utility> for pair<>'
918 ' [build/include_what_you_use] [4]')
919 self.TestIncludeWhatYouUse(
920 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000921 std::vector<int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000922 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000923 'Add #include <vector> for vector<>'
924 ' [build/include_what_you_use] [4]')
925 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000926 """#include <vector>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000927 std::set<int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000928 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000929 'Add #include <set> for set<>'
930 ' [build/include_what_you_use] [4]')
931 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000932 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000933 hash_map<int, int> foobar;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000934 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000935 'Add #include <hash_map> for hash_map<>'
936 ' [build/include_what_you_use] [4]')
937 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000938 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000939 bool foobar = std::less<int>(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000940 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000941 'Add #include <functional> for less<>'
942 ' [build/include_what_you_use] [4]')
943 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000944 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000945 bool foobar = min<int>(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000946 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000947 'Add #include <algorithm> for min [build/include_what_you_use] [4]')
948 self.TestIncludeWhatYouUse(
949 'void a(const string &foobar);',
950 'Add #include <string> for string [build/include_what_you_use] [4]')
951 self.TestIncludeWhatYouUse(
erg+personal@google.com05189642010-04-30 20:43:03 +0000952 'void a(const std::string &foobar);',
953 'Add #include <string> for string [build/include_what_you_use] [4]')
954 self.TestIncludeWhatYouUse(
955 'void a(const my::string &foobar);',
956 '') # Avoid false positives on strings in other namespaces.
957 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000958 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000959 bool foobar = swap(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000960 """,
Alex Vakulenko01e47232016-05-06 13:54:15 -0700961 'Add #include <utility> for swap [build/include_what_you_use] [4]')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000962 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000963 """#include "base/foobar.h"
erg@google.coma87abb82009-02-24 01:41:01 +0000964 bool foobar = transform(a.begin(), a.end(), b.start(), Foo);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000965 """,
erg@google.coma87abb82009-02-24 01:41:01 +0000966 'Add #include <algorithm> for transform '
967 '[build/include_what_you_use] [4]')
968 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000969 """#include "base/foobar.h"
erg@google.coma87abb82009-02-24 01:41:01 +0000970 bool foobar = min_element(a.begin(), a.end());
erg@google.com8a95ecc2011-09-08 00:45:54 +0000971 """,
erg@google.coma87abb82009-02-24 01:41:01 +0000972 'Add #include <algorithm> for min_element '
973 '[build/include_what_you_use] [4]')
974 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000975 """foo->swap(0,1);
erg@google.com4e00b9a2009-01-12 23:05:11 +0000976 foo.swap(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000977 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000978 '')
979 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000980 """#include <string>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000981 void a(const std::multimap<int,string> &foobar);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000982 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000983 'Add #include <map> for multimap<>'
984 ' [build/include_what_you_use] [4]')
985 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000986 """#include <queue>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000987 void a(const std::priority_queue<int> &foobar);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000988 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000989 '')
990 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000991 """#include <assert.h>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000992 #include <string>
993 #include <vector>
994 #include "base/basictypes.h"
995 #include "base/port.h"
erg@google.com8a95ecc2011-09-08 00:45:54 +0000996 vector<string> hajoa;""", '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000997 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000998 """#include <string>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000999 int i = numeric_limits<int>::max()
erg@google.com8a95ecc2011-09-08 00:45:54 +00001000 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +00001001 'Add #include <limits> for numeric_limits<>'
1002 ' [build/include_what_you_use] [4]')
1003 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001004 """#include <limits>
erg@google.com4e00b9a2009-01-12 23:05:11 +00001005 int i = numeric_limits<int>::max()
erg@google.com8a95ecc2011-09-08 00:45:54 +00001006 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +00001007 '')
1008
erg@google.come35f7652009-06-19 20:52:09 +00001009 # Test the UpdateIncludeState code path.
1010 mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"']
1011 message = self.PerformIncludeWhatYouUse(
1012 '#include "blah/a.h"',
1013 filename='blah/a.cc',
1014 io=MockIo(mock_header_contents))
1015 self.assertEquals(message, '')
1016
1017 mock_header_contents = ['#include <set>']
1018 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001019 """#include "blah/a.h"
1020 std::set<int> foo;""",
erg@google.come35f7652009-06-19 20:52:09 +00001021 filename='blah/a.cc',
1022 io=MockIo(mock_header_contents))
1023 self.assertEquals(message, '')
1024
1025 # Make sure we can find the correct header file if the cc file seems to be
1026 # a temporary file generated by Emacs's flymake.
1027 mock_header_contents = ['']
1028 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001029 """#include "blah/a.h"
1030 std::set<int> foo;""",
erg@google.come35f7652009-06-19 20:52:09 +00001031 filename='blah/a_flymake.cc',
1032 io=MockIo(mock_header_contents))
1033 self.assertEquals(message, 'Add #include <set> for set<> '
erg@google.com8a95ecc2011-09-08 00:45:54 +00001034 '[build/include_what_you_use] [4]')
erg@google.come35f7652009-06-19 20:52:09 +00001035
1036 # If there's just a cc and the header can't be found then it's ok.
1037 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001038 """#include "blah/a.h"
1039 std::set<int> foo;""",
erg@google.come35f7652009-06-19 20:52:09 +00001040 filename='blah/a.cc')
1041 self.assertEquals(message, '')
1042
1043 # Make sure we find the headers with relative paths.
1044 mock_header_contents = ['']
1045 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001046 """#include "%s/a.h"
1047 std::set<int> foo;""" % os.path.basename(os.getcwd()),
erg@google.come35f7652009-06-19 20:52:09 +00001048 filename='a.cc',
1049 io=MockIo(mock_header_contents))
1050 self.assertEquals(message, 'Add #include <set> for set<> '
erg@google.com8a95ecc2011-09-08 00:45:54 +00001051 '[build/include_what_you_use] [4]')
erg@google.come35f7652009-06-19 20:52:09 +00001052
1053 def testFilesBelongToSameModule(self):
1054 f = cpplint.FilesBelongToSameModule
1055 self.assertEquals((True, ''), f('a.cc', 'a.h'))
1056 self.assertEquals((True, ''), f('base/google.cc', 'base/google.h'))
1057 self.assertEquals((True, ''), f('base/google_test.cc', 'base/google.h'))
1058 self.assertEquals((True, ''),
1059 f('base/google_unittest.cc', 'base/google.h'))
1060 self.assertEquals((True, ''),
1061 f('base/internal/google_unittest.cc',
1062 'base/public/google.h'))
1063 self.assertEquals((True, 'xxx/yyy/'),
1064 f('xxx/yyy/base/internal/google_unittest.cc',
1065 'base/public/google.h'))
1066 self.assertEquals((True, 'xxx/yyy/'),
1067 f('xxx/yyy/base/google_unittest.cc',
1068 'base/public/google.h'))
1069 self.assertEquals((True, ''),
1070 f('base/google_unittest.cc', 'base/google-inl.h'))
1071 self.assertEquals((True, '/home/build/google3/'),
1072 f('/home/build/google3/base/google.cc', 'base/google.h'))
1073
1074 self.assertEquals((False, ''),
1075 f('/home/build/google3/base/google.cc', 'basu/google.h'))
1076 self.assertEquals((False, ''), f('a.cc', 'b.h'))
1077
erg@google.com4e00b9a2009-01-12 23:05:11 +00001078 def testCleanseLine(self):
erg@google.comd7d27472011-09-07 17:36:35 +00001079 self.assertEquals('int foo = 0;',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001080 cpplint.CleanseComments('int foo = 0; // danger!'))
1081 self.assertEquals('int o = 0;',
1082 cpplint.CleanseComments('int /* foo */ o = 0;'))
1083 self.assertEquals('foo(int a, int b);',
1084 cpplint.CleanseComments('foo(int a /* abc */, int b);'))
1085 self.assertEqual('f(a, b);',
1086 cpplint.CleanseComments('f(a, /* name */ b);'))
1087 self.assertEqual('f(a, b);',
erg@google.com2aa59982013-10-28 19:09:25 +00001088 cpplint.CleanseComments('f(a /* name */, b);'))
erg@google.com4e00b9a2009-01-12 23:05:11 +00001089 self.assertEqual('f(a, b);',
1090 cpplint.CleanseComments('f(a, /* name */b);'))
avakulenko@google.com02af6282014-06-04 18:53:25 +00001091 self.assertEqual('f(a, b, c);',
1092 cpplint.CleanseComments('f(a, /**/b, /**/c);'))
1093 self.assertEqual('f(a, b, c);',
1094 cpplint.CleanseComments('f(a, /**/b/**/, c);'))
erg@google.com4e00b9a2009-01-12 23:05:11 +00001095
erg@google.com2aa59982013-10-28 19:09:25 +00001096 def testRawStrings(self):
1097 self.TestMultiLineLint(
1098 """
1099 void Func() {
1100 static const char kString[] = R"(
1101 #endif <- invalid preprocessor should be ignored
1102 */ <- invalid comment should be ignored too
1103 )";
1104 }""",
1105 '')
1106 self.TestMultiLineLint(
1107 """
1108 void Func() {
1109 string s = R"TrueDelimiter(
1110 )"
1111 )FalseDelimiter"
1112 )TrueDelimiter";
1113 }""",
1114 '')
1115 self.TestMultiLineLint(
1116 """
1117 void Func() {
1118 char char kString[] = R"( ";" )";
1119 }""",
1120 '')
1121 self.TestMultiLineLint(
1122 """
1123 static const char kRawString[] = R"(
1124 \tstatic const int kLineWithTab = 1;
1125 static const int kLineWithTrailingWhiteSpace = 1;\x20
1126
1127 void WeirdNumberOfSpacesAtLineStart() {
1128 string x;
1129 x += StrCat("Use StrAppend instead");
1130 }
1131
1132 void BlankLineAtEndOfBlock() {
1133 // TODO incorrectly formatted
1134 //Badly formatted comment
1135
1136 }
1137
1138 )";""",
1139 '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00001140 self.TestMultiLineLint(
1141 """
1142 void Func() {
1143 string s = StrCat(R"TrueDelimiter(
1144 )"
1145 )FalseDelimiter"
1146 )TrueDelimiter", R"TrueDelimiter2(
1147 )"
1148 )FalseDelimiter2"
1149 )TrueDelimiter2");
1150 }""",
1151 '')
1152 self.TestMultiLineLint(
1153 """
1154 static SomeStruct kData = {
1155 {0, R"(line1
1156 line2
1157 )"}
1158 };""",
1159 '')
erg@google.com2aa59982013-10-28 19:09:25 +00001160
erg@google.com4e00b9a2009-01-12 23:05:11 +00001161 def testMultiLineComments(self):
1162 # missing explicit is bad
1163 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001164 r"""int a = 0;
erg@google.com4e00b9a2009-01-12 23:05:11 +00001165 /* multi-liner
1166 class Foo {
1167 Foo(int f); // should cause a lint warning in code
1168 }
erg@google.com8a95ecc2011-09-08 00:45:54 +00001169 */ """,
erg@google.com4e00b9a2009-01-12 23:05:11 +00001170 '')
1171 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001172 r"""/* int a = 0; multi-liner
1173 static const int b = 0;""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001174 'Could not find end of multi-line comment'
1175 ' [readability/multiline_comment] [5]')
erg@google.com8a95ecc2011-09-08 00:45:54 +00001176 self.TestMultiLineLint(r""" /* multi-line comment""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001177 'Could not find end of multi-line comment'
1178 ' [readability/multiline_comment] [5]')
erg@google.com8a95ecc2011-09-08 00:45:54 +00001179 self.TestMultiLineLint(r""" // /* comment, but not multi-line""", '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001180 self.TestMultiLineLint(r"""/**********
1181 */""", '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00001182 self.TestMultiLineLint(r"""/**
1183 * Doxygen comment
1184 */""",
1185 '')
1186 self.TestMultiLineLint(r"""/*!
1187 * Doxygen comment
1188 */""",
1189 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001190
1191 def testMultilineStrings(self):
1192 multiline_string_error_message = (
1193 'Multi-line string ("...") found. This lint script doesn\'t '
erg@google.com2aa59982013-10-28 19:09:25 +00001194 'do well with such strings, and may give bogus warnings. '
1195 'Use C++11 raw strings or concatenation instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00001196 ' [readability/multiline_string] [5]')
1197
1198 file_path = 'mydir/foo.cc'
1199
1200 error_collector = ErrorCollector(self.assert_)
1201 cpplint.ProcessFileData(file_path, 'cc',
1202 ['const char* str = "This is a\\',
1203 ' multiline string.";'],
1204 error_collector)
1205 self.assertEquals(
1206 2, # One per line.
1207 error_collector.ResultList().count(multiline_string_error_message))
1208
1209 # Test non-explicit single-argument constructors
1210 def testExplicitSingleArgumentConstructors(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001211 old_verbose_level = cpplint._cpplint_state.verbose_level
1212 cpplint._cpplint_state.verbose_level = 0
1213
1214 try:
1215 # missing explicit is bad
1216 self.TestMultiLineLint(
1217 """
1218 class Foo {
1219 Foo(int f);
1220 };""",
1221 'Single-parameter constructors should be marked explicit.'
1222 ' [runtime/explicit] [5]')
1223 # missing explicit is bad, even with whitespace
1224 self.TestMultiLineLint(
1225 """
1226 class Foo {
1227 Foo (int f);
1228 };""",
1229 ['Extra space before ( in function call [whitespace/parens] [4]',
1230 'Single-parameter constructors should be marked explicit.'
1231 ' [runtime/explicit] [5]'])
1232 # missing explicit, with distracting comment, is still bad
1233 self.TestMultiLineLint(
1234 """
1235 class Foo {
1236 Foo(int f); // simpler than Foo(blargh, blarg)
1237 };""",
1238 'Single-parameter constructors should be marked explicit.'
1239 ' [runtime/explicit] [5]')
1240 # missing explicit, with qualified classname
1241 self.TestMultiLineLint(
1242 """
1243 class Qualifier::AnotherOne::Foo {
1244 Foo(int f);
1245 };""",
1246 'Single-parameter constructors should be marked explicit.'
1247 ' [runtime/explicit] [5]')
1248 # missing explicit for inline constructors is bad as well
1249 self.TestMultiLineLint(
1250 """
1251 class Foo {
1252 inline Foo(int f);
1253 };""",
1254 'Single-parameter constructors should be marked explicit.'
1255 ' [runtime/explicit] [5]')
1256 # structs are caught as well.
1257 self.TestMultiLineLint(
1258 """
1259 struct Foo {
1260 Foo(int f);
1261 };""",
1262 'Single-parameter constructors should be marked explicit.'
1263 ' [runtime/explicit] [5]')
1264 # Templatized classes are caught as well.
1265 self.TestMultiLineLint(
1266 """
1267 template<typename T> class Foo {
1268 Foo(int f);
1269 };""",
1270 'Single-parameter constructors should be marked explicit.'
1271 ' [runtime/explicit] [5]')
1272 # inline case for templatized classes.
1273 self.TestMultiLineLint(
1274 """
1275 template<typename T> class Foo {
1276 inline Foo(int f);
1277 };""",
1278 'Single-parameter constructors should be marked explicit.'
1279 ' [runtime/explicit] [5]')
1280 # constructors with a default argument should still be marked explicit
1281 self.TestMultiLineLint(
1282 """
1283 class Foo {
1284 Foo(int f = 0);
1285 };""",
1286 'Constructors callable with one argument should be marked explicit.'
1287 ' [runtime/explicit] [5]')
1288 # multi-argument constructors with all but one default argument should be
1289 # marked explicit
1290 self.TestMultiLineLint(
1291 """
1292 class Foo {
1293 Foo(int f, int g = 0);
1294 };""",
1295 'Constructors callable with one argument should be marked explicit.'
1296 ' [runtime/explicit] [5]')
1297 # multi-argument constructors with all default arguments should be marked
1298 # explicit
1299 self.TestMultiLineLint(
1300 """
1301 class Foo {
1302 Foo(int f = 0, int g = 0);
1303 };""",
1304 'Constructors callable with one argument should be marked explicit.'
1305 ' [runtime/explicit] [5]')
1306 # explicit no-argument constructors are bad
1307 self.TestMultiLineLint(
1308 """
1309 class Foo {
1310 explicit Foo();
1311 };""",
1312 'Zero-parameter constructors should not be marked explicit.'
1313 ' [runtime/explicit] [5]')
1314 # void constructors are considered no-argument
1315 self.TestMultiLineLint(
1316 """
1317 class Foo {
1318 explicit Foo(void);
1319 };""",
1320 'Zero-parameter constructors should not be marked explicit.'
1321 ' [runtime/explicit] [5]')
Alex Vakulenko01e47232016-05-06 13:54:15 -07001322 # No warning for multi-parameter constructors
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001323 self.TestMultiLineLint(
1324 """
1325 class Foo {
1326 explicit Foo(int f, int g);
1327 };""",
Alex Vakulenko01e47232016-05-06 13:54:15 -07001328 '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001329 self.TestMultiLineLint(
1330 """
1331 class Foo {
1332 explicit Foo(int f, int g = 0);
1333 };""",
1334 '')
1335 # single-argument constructors that take a function that takes multiple
1336 # arguments should be explicit
1337 self.TestMultiLineLint(
1338 """
1339 class Foo {
1340 Foo(void (*f)(int f, int g));
1341 };""",
1342 'Single-parameter constructors should be marked explicit.'
1343 ' [runtime/explicit] [5]')
1344 # single-argument constructors that take a single template argument with
1345 # multiple parameters should be explicit
1346 self.TestMultiLineLint(
1347 """
1348 template <typename T, typename S>
1349 class Foo {
1350 Foo(Bar<T, S> b);
1351 };""",
1352 'Single-parameter constructors should be marked explicit.'
1353 ' [runtime/explicit] [5]')
1354 # but copy constructors that take multiple template parameters are OK
1355 self.TestMultiLineLint(
1356 """
1357 template <typename T, S>
1358 class Foo {
1359 Foo(Foo<T, S>& f);
1360 };""",
1361 '')
1362 # proper style is okay
1363 self.TestMultiLineLint(
1364 """
1365 class Foo {
1366 explicit Foo(int f);
1367 };""",
1368 '')
1369 # two argument constructor is okay
1370 self.TestMultiLineLint(
1371 """
1372 class Foo {
1373 Foo(int f, int b);
1374 };""",
1375 '')
1376 # two argument constructor, across two lines, is okay
1377 self.TestMultiLineLint(
1378 """
1379 class Foo {
1380 Foo(int f,
1381 int b);
1382 };""",
1383 '')
1384 # non-constructor (but similar name), is okay
1385 self.TestMultiLineLint(
1386 """
1387 class Foo {
1388 aFoo(int f);
1389 };""",
1390 '')
1391 # constructor with void argument is okay
1392 self.TestMultiLineLint(
1393 """
1394 class Foo {
1395 Foo(void);
1396 };""",
1397 '')
1398 # single argument method is okay
1399 self.TestMultiLineLint(
1400 """
1401 class Foo {
1402 Bar(int b);
1403 };""",
1404 '')
1405 # comments should be ignored
1406 self.TestMultiLineLint(
1407 """
1408 class Foo {
1409 // Foo(int f);
1410 };""",
1411 '')
1412 # single argument function following class definition is okay
1413 # (okay, it's not actually valid, but we don't want a false positive)
1414 self.TestMultiLineLint(
1415 """
1416 class Foo {
1417 Foo(int f, int b);
1418 };
1419 Foo(int f);""",
1420 '')
1421 # single argument function is okay
1422 self.TestMultiLineLint(
1423 """static Foo(int f);""",
1424 '')
1425 # single argument copy constructor is okay.
1426 self.TestMultiLineLint(
1427 """
1428 class Foo {
1429 Foo(const Foo&);
1430 };""",
1431 '')
1432 self.TestMultiLineLint(
1433 """
1434 class Foo {
1435 Foo(Foo const&);
1436 };""",
1437 '')
1438 self.TestMultiLineLint(
1439 """
1440 class Foo {
1441 Foo(Foo&);
1442 };""",
1443 '')
1444 # templatized copy constructor is okay.
1445 self.TestMultiLineLint(
1446 """
1447 template<typename T> class Foo {
1448 Foo(const Foo<T>&);
1449 };""",
1450 '')
1451 # Special case for std::initializer_list
1452 self.TestMultiLineLint(
1453 """
1454 class Foo {
1455 Foo(std::initializer_list<T> &arg) {}
1456 };""",
1457 '')
1458 # Anything goes inside an assembly block
1459 error_collector = ErrorCollector(self.assert_)
1460 cpplint.ProcessFileData('foo.cc', 'cc',
1461 ['void Func() {',
1462 ' __asm__ (',
1463 ' "hlt"',
1464 ' );',
1465 ' asm {',
1466 ' movdqa [edx + 32], xmm2',
1467 ' }',
1468 '}'],
1469 error_collector)
1470 self.assertEquals(
1471 0,
1472 error_collector.ResultList().count(
1473 'Extra space before ( in function call [whitespace/parens] [4]'))
1474 self.assertEquals(
1475 0,
1476 error_collector.ResultList().count(
1477 'Closing ) should be moved to the previous line '
1478 '[whitespace/parens] [2]'))
1479 self.assertEquals(
1480 0,
1481 error_collector.ResultList().count(
1482 'Extra space before [ [whitespace/braces] [5]'))
1483 finally:
1484 cpplint._cpplint_state.verbose_level = old_verbose_level
erg@google.com4e00b9a2009-01-12 23:05:11 +00001485
1486 def testSlashStarCommentOnSingleLine(self):
1487 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001488 """/* static */ Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001489 '')
1490 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001491 """/*/ static */ Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001492 '')
1493 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001494 """/*/ static Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001495 'Could not find end of multi-line comment'
1496 ' [readability/multiline_comment] [5]')
1497 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001498 """ /*/ static Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001499 'Could not find end of multi-line comment'
1500 ' [readability/multiline_comment] [5]')
1501 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001502 """ /**/ static Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001503 '')
1504
1505 # Test suspicious usage of "if" like this:
1506 # if (a == b) {
1507 # DoSomething();
1508 # } if (a == c) { // Should be "else if".
1509 # DoSomething(); // This gets called twice if a == b && a == c.
1510 # }
1511 def testSuspiciousUsageOfIf(self):
1512 self.TestLint(
1513 ' if (a == b) {',
1514 '')
1515 self.TestLint(
1516 ' } if (a == b) {',
1517 'Did you mean "else if"? If not, start a new line for "if".'
1518 ' [readability/braces] [4]')
1519
1520 # Test suspicious usage of memset. Specifically, a 0
1521 # as the final argument is almost certainly an error.
1522 def testSuspiciousUsageOfMemset(self):
1523 # Normal use is okay.
1524 self.TestLint(
1525 ' memset(buf, 0, sizeof(buf))',
1526 '')
1527
1528 # A 0 as the final argument is almost certainly an error.
1529 self.TestLint(
1530 ' memset(buf, sizeof(buf), 0)',
1531 'Did you mean "memset(buf, 0, sizeof(buf))"?'
1532 ' [runtime/memset] [4]')
1533 self.TestLint(
1534 ' memset(buf, xsize * ysize, 0)',
1535 'Did you mean "memset(buf, 0, xsize * ysize)"?'
1536 ' [runtime/memset] [4]')
1537
1538 # There is legitimate test code that uses this form.
1539 # This is okay since the second argument is a literal.
1540 self.TestLint(
1541 " memset(buf, 'y', 0)",
1542 '')
1543 self.TestLint(
1544 ' memset(buf, 4, 0)',
1545 '')
1546 self.TestLint(
1547 ' memset(buf, -1, 0)',
1548 '')
1549 self.TestLint(
1550 ' memset(buf, 0xF1, 0)',
1551 '')
1552 self.TestLint(
1553 ' memset(buf, 0xcd, 0)',
1554 '')
1555
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001556 def testRedundantVirtual(self):
1557 self.TestLint('virtual void F()', '')
1558 self.TestLint('virtual void F();', '')
1559 self.TestLint('virtual void F() {}', '')
1560
1561 message_template = ('"%s" is redundant since function is already '
1562 'declared as "%s" [readability/inheritance] [4]')
1563 for virt_specifier in ['override', 'final']:
1564 error_message = message_template % ('virtual', virt_specifier)
1565 self.TestLint('virtual int F() %s' % virt_specifier, error_message)
1566 self.TestLint('virtual int F() %s;' % virt_specifier, error_message)
1567 self.TestLint('virtual int F() %s {' % virt_specifier, error_message)
1568
1569 error_collector = ErrorCollector(self.assert_)
1570 cpplint.ProcessFileData(
1571 'foo.cc', 'cc',
1572 ['// Copyright 2014 Your Company.',
1573 'virtual void F(int a,',
1574 ' int b) ' + virt_specifier + ';',
1575 'virtual void F(int a,',
1576 ' int b) LOCKS_EXCLUDED(lock) ' + virt_specifier + ';',
1577 'virtual void F(int a,',
1578 ' int b)',
1579 ' LOCKS_EXCLUDED(lock) ' + virt_specifier + ';',
1580 ''],
1581 error_collector)
1582 self.assertEquals(
1583 [error_message, error_message, error_message],
1584 error_collector.Results())
1585
1586 error_message = message_template % ('override', 'final')
1587 self.TestLint('int F() override final', error_message)
1588 self.TestLint('int F() override final;', error_message)
1589 self.TestLint('int F() override final {}', error_message)
1590 self.TestLint('int F() final override', error_message)
1591 self.TestLint('int F() final override;', error_message)
1592 self.TestLint('int F() final override {}', error_message)
1593
avakulenko@google.com554223d2014-12-04 22:00:20 +00001594 error_collector = ErrorCollector(self.assert_)
1595 cpplint.ProcessFileData(
1596 'foo.cc', 'cc',
1597 ['// Copyright 2014 Your Company.',
1598 'struct A : virtual B {',
1599 ' ~A() override;'
1600 '};',
1601 'class C',
1602 ' : public D,',
1603 ' public virtual E {',
1604 ' void Func() override;',
1605 '}',
1606 ''],
1607 error_collector)
1608 self.assertEquals('', error_collector.Results())
1609
1610 self.TestLint('void Finalize(AnnotationProto *final) override;', '')
1611
erg@google.com4e00b9a2009-01-12 23:05:11 +00001612 def testCheckDeprecated(self):
erg@google.com4e00b9a2009-01-12 23:05:11 +00001613 self.TestLanguageRulesCheck('foo_test.cc', '#include <iostream>', '')
1614 self.TestLanguageRulesCheck('foo_unittest.cc', '#include <iostream>', '')
1615
1616 def testCheckPosixThreading(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00001617 self.TestLint('var = sctime_r()', '')
1618 self.TestLint('var = strtok_r()', '')
1619 self.TestLint('var = strtok_r(foo, ba, r)', '')
1620 self.TestLint('var = brand()', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001621 self.TestLint('_rand()', '')
1622 self.TestLint('.rand()', '')
erg@google.comd350fe52013-01-14 17:51:48 +00001623 self.TestLint('->rand()', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00001624 self.TestLint('ACMRandom rand(seed)', '')
1625 self.TestLint('ISAACRandom rand()', '')
1626 self.TestLint('var = rand()',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001627 'Consider using rand_r(...) instead of rand(...)'
1628 ' for improved thread safety.'
1629 ' [runtime/threadsafe_fn] [2]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00001630 self.TestLint('var = strtok(str, delim)',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001631 'Consider using strtok_r(...) '
1632 'instead of strtok(...)'
1633 ' for improved thread safety.'
1634 ' [runtime/threadsafe_fn] [2]')
1635
erg@google.com2aa59982013-10-28 19:09:25 +00001636 def testVlogMisuse(self):
1637 self.TestLint('VLOG(1)', '')
1638 self.TestLint('VLOG(99)', '')
1639 self.TestLint('LOG(ERROR)', '')
1640 self.TestLint('LOG(INFO)', '')
1641 self.TestLint('LOG(WARNING)', '')
1642 self.TestLint('LOG(FATAL)', '')
1643 self.TestLint('LOG(DFATAL)', '')
1644 self.TestLint('VLOG(SOMETHINGWEIRD)', '')
1645 self.TestLint('MYOWNVLOG(ERROR)', '')
1646 errmsg = ('VLOG() should be used with numeric verbosity level. '
1647 'Use LOG() if you want symbolic severity levels.'
1648 ' [runtime/vlog] [5]')
1649 self.TestLint('VLOG(ERROR)', errmsg)
1650 self.TestLint('VLOG(INFO)', errmsg)
1651 self.TestLint('VLOG(WARNING)', errmsg)
1652 self.TestLint('VLOG(FATAL)', errmsg)
1653 self.TestLint('VLOG(DFATAL)', errmsg)
1654 self.TestLint(' VLOG(ERROR)', errmsg)
1655 self.TestLint(' VLOG(INFO)', errmsg)
1656 self.TestLint(' VLOG(WARNING)', errmsg)
1657 self.TestLint(' VLOG(FATAL)', errmsg)
1658 self.TestLint(' VLOG(DFATAL)', errmsg)
1659
1660
erg@google.com4e00b9a2009-01-12 23:05:11 +00001661 # Test potential format string bugs like printf(foo).
1662 def testFormatStrings(self):
1663 self.TestLint('printf("foo")', '')
1664 self.TestLint('printf("foo: %s", foo)', '')
1665 self.TestLint('DocidForPrintf(docid)', '') # Should not trigger.
erg@google.com8a95ecc2011-09-08 00:45:54 +00001666 self.TestLint('printf(format, value)', '') # Should not trigger.
erg@google.comd350fe52013-01-14 17:51:48 +00001667 self.TestLint('printf(__VA_ARGS__)', '') # Should not trigger.
erg@google.com8a95ecc2011-09-08 00:45:54 +00001668 self.TestLint('printf(format.c_str(), value)', '') # Should not trigger.
1669 self.TestLint('printf(format(index).c_str(), value)', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001670 self.TestLint(
1671 'printf(foo)',
1672 'Potential format string bug. Do printf("%s", foo) instead.'
1673 ' [runtime/printf] [4]')
1674 self.TestLint(
1675 'printf(foo.c_str())',
1676 'Potential format string bug. '
1677 'Do printf("%s", foo.c_str()) instead.'
1678 ' [runtime/printf] [4]')
1679 self.TestLint(
1680 'printf(foo->c_str())',
1681 'Potential format string bug. '
1682 'Do printf("%s", foo->c_str()) instead.'
1683 ' [runtime/printf] [4]')
1684 self.TestLint(
1685 'StringPrintf(foo)',
1686 'Potential format string bug. Do StringPrintf("%s", foo) instead.'
1687 ''
1688 ' [runtime/printf] [4]')
1689
erg@google.coma868d2d2009-10-09 21:18:45 +00001690 # Test disallowed use of operator& and other operators.
1691 def testIllegalOperatorOverloading(self):
1692 errmsg = ('Unary operator& is dangerous. Do not use it.'
1693 ' [runtime/operator] [4]')
1694 self.TestLint('void operator=(const Myclass&)', '')
1695 self.TestLint('void operator&(int a, int b)', '') # binary operator& ok
1696 self.TestLint('void operator&() { }', errmsg)
1697 self.TestLint('void operator & ( ) { }',
avakulenko@google.com02af6282014-06-04 18:53:25 +00001698 ['Extra space after ( [whitespace/parens] [2]', errmsg])
erg@google.coma868d2d2009-10-09 21:18:45 +00001699
1700 # const string reference members are dangerous..
1701 def testConstStringReferenceMembers(self):
1702 errmsg = ('const string& members are dangerous. It is much better to use '
1703 'alternatives, such as pointers or simple constants.'
1704 ' [runtime/member_string_references] [2]')
1705
1706 members_declarations = ['const string& church',
1707 'const string &turing',
1708 'const string & godel']
1709 # TODO(unknown): Enable also these tests if and when we ever
1710 # decide to check for arbitrary member references.
1711 # "const Turing & a",
1712 # "const Church& a",
1713 # "const vector<int>& a",
1714 # "const Kurt::Godel & godel",
1715 # "const Kazimierz::Kuratowski& kk" ]
1716
1717 # The Good.
1718
1719 self.TestLint('void f(const string&)', '')
1720 self.TestLint('const string& f(const string& a, const string& b)', '')
1721 self.TestLint('typedef const string& A;', '')
1722
1723 for decl in members_declarations:
1724 self.TestLint(decl + ' = b;', '')
1725 self.TestLint(decl + ' =', '')
1726
1727 # The Bad.
1728
1729 for decl in members_declarations:
1730 self.TestLint(decl + ';', errmsg)
1731
erg@google.com4e00b9a2009-01-12 23:05:11 +00001732 # Variable-length arrays are not permitted.
1733 def testVariableLengthArrayDetection(self):
1734 errmsg = ('Do not use variable-length arrays. Use an appropriately named '
1735 "('k' followed by CamelCase) compile-time constant for the size."
1736 ' [runtime/arrays] [1]')
1737
1738 self.TestLint('int a[any_old_variable];', errmsg)
1739 self.TestLint('int doublesize[some_var * 2];', errmsg)
1740 self.TestLint('int a[afunction()];', errmsg)
1741 self.TestLint('int a[function(kMaxFooBars)];', errmsg)
1742 self.TestLint('bool a_list[items_->size()];', errmsg)
1743 self.TestLint('namespace::Type buffer[len+1];', errmsg)
1744
1745 self.TestLint('int a[64];', '')
1746 self.TestLint('int a[0xFF];', '')
1747 self.TestLint('int first[256], second[256];', '')
1748 self.TestLint('int array_name[kCompileTimeConstant];', '')
1749 self.TestLint('char buf[somenamespace::kBufSize];', '')
1750 self.TestLint('int array_name[ALL_CAPS];', '')
1751 self.TestLint('AClass array1[foo::bar::ALL_CAPS];', '')
1752 self.TestLint('int a[kMaxStrLen + 1];', '')
1753 self.TestLint('int a[sizeof(foo)];', '')
1754 self.TestLint('int a[sizeof(*foo)];', '')
1755 self.TestLint('int a[sizeof foo];', '')
1756 self.TestLint('int a[sizeof(struct Foo)];', '')
1757 self.TestLint('int a[128 - sizeof(const bar)];', '')
1758 self.TestLint('int a[(sizeof(foo) * 4)];', '')
1759 self.TestLint('int a[(arraysize(fixed_size_array)/2) << 1];', '')
1760 self.TestLint('delete a[some_var];', '')
1761 self.TestLint('return a[some_var];', '')
1762
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001763 # DISALLOW_COPY_AND_ASSIGN and DISALLOW_IMPLICIT_CONSTRUCTORS should be at
1764 # end of class if present.
1765 def testDisallowMacrosAtEnd(self):
erg@google.com4e00b9a2009-01-12 23:05:11 +00001766 for macro_name in (
erg@google.com4e00b9a2009-01-12 23:05:11 +00001767 'DISALLOW_COPY_AND_ASSIGN',
1768 'DISALLOW_IMPLICIT_CONSTRUCTORS'):
avakulenko@google.com554223d2014-12-04 22:00:20 +00001769 error_collector = ErrorCollector(self.assert_)
1770 cpplint.ProcessFileData(
1771 'foo.cc', 'cc',
1772 ['// Copyright 2014 Your Company.',
1773 'class SomeClass {',
1774 ' private:',
1775 ' %s(SomeClass);' % macro_name,
1776 ' int member_;',
1777 '};',
1778 ''],
1779 error_collector)
1780 self.assertEquals(
erg@google.com4e00b9a2009-01-12 23:05:11 +00001781 ('%s should be the last thing in the class' % macro_name) +
avakulenko@google.com554223d2014-12-04 22:00:20 +00001782 ' [readability/constructors] [3]',
1783 error_collector.Results())
1784
1785 error_collector = ErrorCollector(self.assert_)
1786 cpplint.ProcessFileData(
1787 'foo.cc', 'cc',
1788 ['// Copyright 2014 Your Company.',
1789 'class OuterClass {',
1790 ' private:',
1791 ' struct InnerClass {',
1792 ' private:',
1793 ' %s(InnerClass);' % macro_name,
1794 ' int member;',
1795 ' };',
1796 '};',
1797 ''],
1798 error_collector)
1799 self.assertEquals(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001800 ('%s should be the last thing in the class' % macro_name) +
avakulenko@google.com554223d2014-12-04 22:00:20 +00001801 ' [readability/constructors] [3]',
1802 error_collector.Results())
1803
1804 error_collector = ErrorCollector(self.assert_)
1805 cpplint.ProcessFileData(
1806 'foo.cc', 'cc',
1807 ['// Copyright 2014 Your Company.',
1808 'class OuterClass1 {',
1809 ' private:',
1810 ' struct InnerClass1 {',
1811 ' private:',
1812 ' %s(InnerClass1);' % macro_name,
1813 ' };',
1814 ' %s(OuterClass1);' % macro_name,
1815 '};',
1816 'struct OuterClass2 {',
1817 ' private:',
1818 ' class InnerClass2 {',
1819 ' private:',
1820 ' %s(InnerClass2);' % macro_name,
1821 ' // comment',
1822 ' };',
1823 '',
1824 ' %s(OuterClass2);' % macro_name,
1825 '',
1826 ' // comment',
1827 '};',
1828 'void Func() {',
1829 ' struct LocalClass {',
1830 ' private:',
1831 ' %s(LocalClass);' % macro_name,
1832 ' } variable;',
1833 '}',
1834 ''],
1835 error_collector)
1836 self.assertEquals('', error_collector.Results())
erg@google.com4e00b9a2009-01-12 23:05:11 +00001837
erg@google.comd350fe52013-01-14 17:51:48 +00001838 # DISALLOW* macros should be in the private: section.
1839 def testMisplacedDisallowMacros(self):
1840 for macro_name in (
erg@google.comd350fe52013-01-14 17:51:48 +00001841 'DISALLOW_COPY_AND_ASSIGN',
1842 'DISALLOW_IMPLICIT_CONSTRUCTORS'):
1843 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001844 """
1845 class A {'
erg@google.comd350fe52013-01-14 17:51:48 +00001846 public:
1847 %s(A);
1848 };""" % macro_name,
1849 ('%s must be in the private: section' % macro_name) +
1850 ' [readability/constructors] [3]')
1851
1852 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001853 """
1854 struct B {'
erg@google.comd350fe52013-01-14 17:51:48 +00001855 %s(B);
1856 };""" % macro_name,
1857 ('%s must be in the private: section' % macro_name) +
1858 ' [readability/constructors] [3]')
1859
1860 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001861 """
1862 class Outer1 {'
erg@google.comd350fe52013-01-14 17:51:48 +00001863 private:
1864 struct Inner1 {
1865 %s(Inner1);
1866 };
1867 %s(Outer1);
1868 };""" % (macro_name, macro_name),
1869 ('%s must be in the private: section' % macro_name) +
1870 ' [readability/constructors] [3]')
1871
1872 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001873 """
1874 class Outer2 {'
erg@google.comd350fe52013-01-14 17:51:48 +00001875 private:
1876 class Inner2 {
1877 %s(Inner2);
1878 };
1879 %s(Outer2);
1880 };""" % (macro_name, macro_name),
1881 '')
1882 # Extra checks to make sure that nested classes are handled
1883 # correctly. Use different macros for inner and outer classes so
1884 # that we can tell the error messages apart.
1885 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001886 """
1887 class Outer3 {
erg@google.comd350fe52013-01-14 17:51:48 +00001888 struct Inner3 {
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001889 DISALLOW_COPY_AND_ASSIGN(Inner3);
erg@google.comd350fe52013-01-14 17:51:48 +00001890 };
1891 DISALLOW_IMPLICIT_CONSTRUCTORS(Outer3);
1892 };""",
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001893 ('DISALLOW_COPY_AND_ASSIGN must be in the private: section'
erg@google.comd350fe52013-01-14 17:51:48 +00001894 ' [readability/constructors] [3]'))
1895 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001896 """
1897 struct Outer4 {
erg@google.comd350fe52013-01-14 17:51:48 +00001898 class Inner4 {
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001899 DISALLOW_COPY_AND_ASSIGN(Inner4);
erg@google.comd350fe52013-01-14 17:51:48 +00001900 };
1901 DISALLOW_IMPLICIT_CONSTRUCTORS(Outer4);
1902 };""",
1903 ('DISALLOW_IMPLICIT_CONSTRUCTORS must be in the private: section'
1904 ' [readability/constructors] [3]'))
1905
erg@google.com4e00b9a2009-01-12 23:05:11 +00001906 # Brace usage
1907 def testBraces(self):
1908 # Braces shouldn't be followed by a ; unless they're defining a struct
1909 # or initializing an array
1910 self.TestLint('int a[3] = { 1, 2, 3 };', '')
1911 self.TestLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001912 """const int foo[] =
1913 {1, 2, 3 };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001914 '')
1915 # For single line, unmatched '}' with a ';' is ignored (not enough context)
1916 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001917 """int a[3] = { 1,
erg@google.com4e00b9a2009-01-12 23:05:11 +00001918 2,
erg@google.com8a95ecc2011-09-08 00:45:54 +00001919 3 };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001920 '')
1921 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001922 """int a[2][3] = { { 1, 2 },
1923 { 3, 4 } };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001924 '')
1925 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001926 """int a[2][3] =
erg@google.com4e00b9a2009-01-12 23:05:11 +00001927 { { 1, 2 },
erg@google.com8a95ecc2011-09-08 00:45:54 +00001928 { 3, 4 } };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001929 '')
1930
1931 # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements
1932 def testCheckCheck(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001933 self.TestLint('CHECK(x == 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001934 'Consider using CHECK_EQ instead of CHECK(a == b)'
1935 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001936 self.TestLint('CHECK(x != 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001937 'Consider using CHECK_NE instead of CHECK(a != b)'
1938 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001939 self.TestLint('CHECK(x >= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001940 'Consider using CHECK_GE instead of CHECK(a >= b)'
1941 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001942 self.TestLint('CHECK(x > 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001943 'Consider using CHECK_GT instead of CHECK(a > b)'
1944 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001945 self.TestLint('CHECK(x <= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001946 'Consider using CHECK_LE instead of CHECK(a <= b)'
1947 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001948 self.TestLint('CHECK(x < 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001949 'Consider using CHECK_LT instead of CHECK(a < b)'
1950 ' [readability/check] [2]')
1951
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001952 self.TestLint('DCHECK(x == 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001953 'Consider using DCHECK_EQ instead of DCHECK(a == b)'
1954 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001955 self.TestLint('DCHECK(x != 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001956 'Consider using DCHECK_NE instead of DCHECK(a != b)'
1957 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001958 self.TestLint('DCHECK(x >= 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001959 'Consider using DCHECK_GE instead of DCHECK(a >= b)'
1960 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001961 self.TestLint('DCHECK(x > 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001962 'Consider using DCHECK_GT instead of DCHECK(a > b)'
1963 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001964 self.TestLint('DCHECK(x <= 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001965 'Consider using DCHECK_LE instead of DCHECK(a <= b)'
1966 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001967 self.TestLint('DCHECK(x < 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001968 'Consider using DCHECK_LT instead of DCHECK(a < b)'
1969 ' [readability/check] [2]')
1970
erg@google.com4e00b9a2009-01-12 23:05:11 +00001971 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001972 'EXPECT_TRUE("42" == x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001973 'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)'
1974 ' [readability/check] [2]')
1975 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001976 'EXPECT_TRUE("42" != x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001977 'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)'
1978 ' [readability/check] [2]')
1979 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001980 'EXPECT_TRUE(+42 >= x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001981 'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)'
1982 ' [readability/check] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001983
1984 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001985 'EXPECT_FALSE(x == 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001986 'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)'
1987 ' [readability/check] [2]')
1988 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001989 'EXPECT_FALSE(x != 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001990 'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)'
1991 ' [readability/check] [2]')
1992 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001993 'EXPECT_FALSE(x >= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001994 'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)'
1995 ' [readability/check] [2]')
1996 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001997 'ASSERT_FALSE(x > 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001998 'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)'
1999 ' [readability/check] [2]')
2000 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002001 'ASSERT_FALSE(x <= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002002 'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)'
2003 ' [readability/check] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002004
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002005 self.TestLint('CHECK(x<42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002006 ['Missing spaces around <'
2007 ' [whitespace/operators] [3]',
2008 'Consider using CHECK_LT instead of CHECK(a < b)'
2009 ' [readability/check] [2]'])
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002010 self.TestLint('CHECK(x>42);',
erg@google.comd350fe52013-01-14 17:51:48 +00002011 ['Missing spaces around >'
2012 ' [whitespace/operators] [3]',
2013 'Consider using CHECK_GT instead of CHECK(a > b)'
2014 ' [readability/check] [2]'])
erg@google.com4e00b9a2009-01-12 23:05:11 +00002015
erg@google.com0075d142013-11-05 22:28:07 +00002016 self.TestLint('using some::namespace::operator<<;', '')
2017 self.TestLint('using some::namespace::operator>>;', '')
erg@google.comc6671232013-10-25 21:44:03 +00002018
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002019 self.TestLint('CHECK(x->y == 42);',
erg@google.comc6671232013-10-25 21:44:03 +00002020 'Consider using CHECK_EQ instead of CHECK(a == b)'
2021 ' [readability/check] [2]')
2022
erg@google.com4e00b9a2009-01-12 23:05:11 +00002023 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002024 ' EXPECT_TRUE(42 < x); // Random comment.',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002025 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
2026 ' [readability/check] [2]')
2027 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002028 'EXPECT_TRUE( 42 < x );',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002029 ['Extra space after ( in function call'
2030 ' [whitespace/parens] [4]',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002031 'Extra space before ) [whitespace/parens] [2]',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002032 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
2033 ' [readability/check] [2]'])
erg@google.com4e00b9a2009-01-12 23:05:11 +00002034
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002035 self.TestLint('CHECK(4\'2 == x);',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002036 'Consider using CHECK_EQ instead of CHECK(a == b)'
2037 ' [readability/check] [2]')
2038
2039 def testCheckCheckFalsePositives(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002040 self.TestLint('CHECK(some_iterator == obj.end());', '')
2041 self.TestLint('EXPECT_TRUE(some_iterator == obj.end());', '')
2042 self.TestLint('EXPECT_FALSE(some_iterator == obj.end());', '')
2043 self.TestLint('CHECK(some_pointer != NULL);', '')
2044 self.TestLint('EXPECT_TRUE(some_pointer != NULL);', '')
2045 self.TestLint('EXPECT_FALSE(some_pointer != NULL);', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002046
2047 self.TestLint('CHECK(CreateTestFile(dir, (1 << 20)));', '')
2048 self.TestLint('CHECK(CreateTestFile(dir, (1 >> 20)));', '')
2049
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002050 self.TestLint('CHECK(x ^ (y < 42));', '')
2051 self.TestLint('CHECK((x > 42) ^ (x < 54));', '')
2052 self.TestLint('CHECK(a && b < 42);', '')
2053 self.TestLint('CHECK(42 < a && a < b);', '')
2054 self.TestLint('SOFT_CHECK(x > 42);', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002055
2056 self.TestMultiLineLint(
2057 """_STLP_DEFINE_BINARY_OP_CHECK(==, _OP_EQUAL);
2058 _STLP_DEFINE_BINARY_OP_CHECK(!=, _OP_NOT_EQUAL);
2059 _STLP_DEFINE_BINARY_OP_CHECK(<, _OP_LESS_THAN);
2060 _STLP_DEFINE_BINARY_OP_CHECK(<=, _OP_LESS_EQUAL);
2061 _STLP_DEFINE_BINARY_OP_CHECK(>, _OP_GREATER_THAN);
2062 _STLP_DEFINE_BINARY_OP_CHECK(>=, _OP_GREATER_EQUAL);
2063 _STLP_DEFINE_BINARY_OP_CHECK(+, _OP_PLUS);
2064 _STLP_DEFINE_BINARY_OP_CHECK(*, _OP_TIMES);
2065 _STLP_DEFINE_BINARY_OP_CHECK(/, _OP_DIVIDE);
2066 _STLP_DEFINE_BINARY_OP_CHECK(-, _OP_SUBTRACT);
2067 _STLP_DEFINE_BINARY_OP_CHECK(%, _OP_MOD);""",
2068 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002069
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002070 self.TestLint('CHECK(x < 42) << "Custom error message";', '')
2071
erg@google.comd350fe52013-01-14 17:51:48 +00002072 # Alternative token to punctuation operator replacements
2073 def testCheckAltTokens(self):
2074 self.TestLint('true or true',
2075 'Use operator || instead of or'
2076 ' [readability/alt_tokens] [2]')
2077 self.TestLint('true and true',
2078 'Use operator && instead of and'
2079 ' [readability/alt_tokens] [2]')
2080 self.TestLint('if (not true)',
2081 'Use operator ! instead of not'
2082 ' [readability/alt_tokens] [2]')
2083 self.TestLint('1 bitor 1',
2084 'Use operator | instead of bitor'
2085 ' [readability/alt_tokens] [2]')
2086 self.TestLint('1 xor 1',
2087 'Use operator ^ instead of xor'
2088 ' [readability/alt_tokens] [2]')
2089 self.TestLint('1 bitand 1',
2090 'Use operator & instead of bitand'
2091 ' [readability/alt_tokens] [2]')
2092 self.TestLint('x = compl 1',
2093 'Use operator ~ instead of compl'
2094 ' [readability/alt_tokens] [2]')
2095 self.TestLint('x and_eq y',
2096 'Use operator &= instead of and_eq'
2097 ' [readability/alt_tokens] [2]')
2098 self.TestLint('x or_eq y',
2099 'Use operator |= instead of or_eq'
2100 ' [readability/alt_tokens] [2]')
2101 self.TestLint('x xor_eq y',
2102 'Use operator ^= instead of xor_eq'
2103 ' [readability/alt_tokens] [2]')
2104 self.TestLint('x not_eq y',
2105 'Use operator != instead of not_eq'
2106 ' [readability/alt_tokens] [2]')
2107 self.TestLint('line_continuation or',
2108 'Use operator || instead of or'
2109 ' [readability/alt_tokens] [2]')
2110 self.TestLint('if(true and(parentheses',
2111 'Use operator && instead of and'
2112 ' [readability/alt_tokens] [2]')
2113
2114 self.TestLint('#include "base/false-and-false.h"', '')
2115 self.TestLint('#error false or false', '')
2116 self.TestLint('false nor false', '')
2117 self.TestLint('false nand false', '')
2118
erg@google.com4e00b9a2009-01-12 23:05:11 +00002119 # Passing and returning non-const references
2120 def testNonConstReference(self):
2121 # Passing a non-const reference as function parameter is forbidden.
2122 operand_error_message = ('Is this a non-const reference? '
erg@google.comfd5da632013-10-25 17:39:45 +00002123 'If so, make const or use a pointer: %s'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002124 ' [runtime/references] [2]')
2125 # Warn of use of a non-const reference in operators and functions
erg@google.comfd5da632013-10-25 17:39:45 +00002126 self.TestLint('bool operator>(Foo& s, Foo& f);',
2127 [operand_error_message % 'Foo& s',
2128 operand_error_message % 'Foo& f'])
2129 self.TestLint('bool operator+(Foo& s, Foo& f);',
2130 [operand_error_message % 'Foo& s',
2131 operand_error_message % 'Foo& f'])
2132 self.TestLint('int len(Foo& s);', operand_error_message % 'Foo& s')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002133 # Allow use of non-const references in a few specific cases
2134 self.TestLint('stream& operator>>(stream& s, Foo& f);', '')
2135 self.TestLint('stream& operator<<(stream& s, Foo& f);', '')
2136 self.TestLint('void swap(Bar& a, Bar& b);', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002137 self.TestLint('ostream& LogFunc(ostream& s);', '')
2138 self.TestLint('ostringstream& LogFunc(ostringstream& s);', '')
2139 self.TestLint('istream& LogFunc(istream& s);', '')
2140 self.TestLint('istringstream& LogFunc(istringstream& s);', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002141 # Returning a non-const reference from a function is OK.
2142 self.TestLint('int& g();', '')
2143 # Passing a const reference to a struct (using the struct keyword) is OK.
2144 self.TestLint('void foo(const struct tm& tm);', '')
2145 # Passing a const reference to a typename is OK.
2146 self.TestLint('void foo(const typename tm& tm);', '')
erg@google.comfd5da632013-10-25 17:39:45 +00002147 # Const reference to a pointer type is OK.
2148 self.TestLint('void foo(const Bar* const& p) {', '')
2149 self.TestLint('void foo(Bar const* const& p) {', '')
2150 self.TestLint('void foo(Bar* const& p) {', '')
2151 # Const reference to a templated type is OK.
2152 self.TestLint('void foo(const std::vector<std::string>& v);', '')
2153 # Non-const reference to a pointer type is not OK.
2154 self.TestLint('void foo(Bar*& p);',
2155 operand_error_message % 'Bar*& p')
2156 self.TestLint('void foo(const Bar*& p);',
2157 operand_error_message % 'const Bar*& p')
2158 self.TestLint('void foo(Bar const*& p);',
2159 operand_error_message % 'Bar const*& p')
2160 self.TestLint('void foo(struct Bar*& p);',
2161 operand_error_message % 'struct Bar*& p')
2162 self.TestLint('void foo(const struct Bar*& p);',
2163 operand_error_message % 'const struct Bar*& p')
2164 self.TestLint('void foo(struct Bar const*& p);',
2165 operand_error_message % 'struct Bar const*& p')
2166 # Non-const reference to a templated type is not OK.
2167 self.TestLint('void foo(std::vector<int>& p);',
2168 operand_error_message % 'std::vector<int>& p')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002169 # Returning an address of something is not prohibited.
2170 self.TestLint('return &something;', '')
erg@google.comd7d27472011-09-07 17:36:35 +00002171 self.TestLint('if (condition) {return &something; }', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002172 self.TestLint('if (condition) return &something;', '')
2173 self.TestLint('if (condition) address = &something;', '')
2174 self.TestLint('if (condition) result = lhs&rhs;', '')
2175 self.TestLint('if (condition) result = lhs & rhs;', '')
2176 self.TestLint('a = (b+c) * sizeof &f;', '')
2177 self.TestLint('a = MySize(b) * sizeof &f;', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002178 # We don't get confused by C++11 range-based for loops.
2179 self.TestLint('for (const string& s : c)', '')
2180 self.TestLint('for (auto& r : c)', '')
2181 self.TestLint('for (typename Type& a : b)', '')
erg@google.comfd5da632013-10-25 17:39:45 +00002182 # We don't get confused by some other uses of '&'.
2183 self.TestLint('T& operator=(const T& t);', '')
2184 self.TestLint('int g() { return (a & b); }', '')
2185 self.TestLint('T& r = (T&)*(vp());', '')
2186 self.TestLint('T& r = v', '')
2187 self.TestLint('static_assert((kBits & kMask) == 0, "text");', '')
2188 self.TestLint('COMPILE_ASSERT((kBits & kMask) == 0, text);', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002189 # Spaces before template arguments. This is poor style, but
2190 # happens 0.15% of the time.
2191 self.TestLint('void Func(const vector <int> &const_x, '
2192 'vector <int> &nonconst_x) {',
2193 operand_error_message % 'vector<int> &nonconst_x')
erg@google.comfd5da632013-10-25 17:39:45 +00002194
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002195 # Derived member functions are spared from override check
2196 self.TestLint('void Func(X& x);', operand_error_message % 'X& x')
2197 self.TestLint('void Func(X& x) {}', operand_error_message % 'X& x')
2198 self.TestLint('void Func(X& x) override;', '')
2199 self.TestLint('void Func(X& x) override {', '')
2200 self.TestLint('void Func(X& x) const override;', '')
2201 self.TestLint('void Func(X& x) const override {', '')
2202
avakulenko@google.com554223d2014-12-04 22:00:20 +00002203 # Don't warn on out-of-line method definitions.
2204 self.TestLint('void NS::Func(X& x) {', '')
2205 error_collector = ErrorCollector(self.assert_)
2206 cpplint.ProcessFileData(
2207 'foo.cc', 'cc',
2208 ['// Copyright 2014 Your Company. All Rights Reserved.',
2209 'void a::b() {}',
2210 'void f(int& q) {}',
2211 ''],
2212 error_collector)
2213 self.assertEquals(
2214 operand_error_message % 'int& q',
2215 error_collector.Results())
2216
avakulenko@google.com02af6282014-06-04 18:53:25 +00002217 # Other potential false positives. These need full parser
erg@google.comfd5da632013-10-25 17:39:45 +00002218 # state to reproduce as opposed to just TestLint.
2219 error_collector = ErrorCollector(self.assert_)
2220 cpplint.ProcessFileData(
2221 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002222 ['// Copyright 2014 Your Company. All Rights Reserved.',
erg@google.comfd5da632013-10-25 17:39:45 +00002223 'void swap(int &x,',
2224 ' int &y) {',
2225 '}',
2226 'void swap(',
2227 ' sparsegroup<T, GROUP_SIZE, Alloc> &x,',
2228 ' sparsegroup<T, GROUP_SIZE, Alloc> &y) {',
2229 '}',
2230 'ostream& operator<<(',
2231 ' ostream& out',
2232 ' const dense_hash_set<Value, Hash, Equals, Alloc>& seq) {',
2233 '}',
avakulenko@google.com554223d2014-12-04 22:00:20 +00002234 'class A {',
2235 ' void Function(',
2236 ' string &x) override {',
2237 ' }',
2238 '};',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002239 'void Derived::Function(',
avakulenko@google.com554223d2014-12-04 22:00:20 +00002240 ' string &x) {',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002241 '}',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002242 '#define UNSUPPORTED_MASK(_mask) \\',
2243 ' if (flags & _mask) { \\',
2244 ' LOG(FATAL) << "Unsupported flag: " << #_mask; \\',
2245 ' }',
2246 'Constructor::Constructor()',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002247 ' : initializer1_(a1 & b1),',
2248 ' initializer2_(a2 & b2) {',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002249 '}',
2250 'Constructor::Constructor()',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002251 ' : initializer1_{a3 & b3},',
2252 ' initializer2_(a4 & b4) {',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002253 '}',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002254 'Constructor::Constructor()',
2255 ' : initializer1_{a5 & b5},',
2256 ' initializer2_(a6 & b6) {}',
erg@google.comfd5da632013-10-25 17:39:45 +00002257 ''],
2258 error_collector)
2259 self.assertEquals('', error_collector.Results())
erg@google.com4e00b9a2009-01-12 23:05:11 +00002260
erg@google.comc6671232013-10-25 21:44:03 +00002261 # Multi-line references
avakulenko@google.com02af6282014-06-04 18:53:25 +00002262 error_collector = ErrorCollector(self.assert_)
erg@google.comc6671232013-10-25 21:44:03 +00002263 cpplint.ProcessFileData(
2264 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002265 ['// Copyright 2014 Your Company. All Rights Reserved.',
erg@google.comc6671232013-10-25 21:44:03 +00002266 'void Func(const Outer::',
2267 ' Inner& const_x,',
2268 ' const Outer',
2269 ' ::Inner& const_y,',
erg@google.com2aa59982013-10-28 19:09:25 +00002270 ' const Outer<',
2271 ' int>::Inner& const_z,',
erg@google.comc6671232013-10-25 21:44:03 +00002272 ' Outer::',
2273 ' Inner& nonconst_x,',
2274 ' Outer',
erg@google.com2aa59982013-10-28 19:09:25 +00002275 ' ::Inner& nonconst_y,',
2276 ' Outer<',
2277 ' int>::Inner& nonconst_z) {',
erg@google.comc6671232013-10-25 21:44:03 +00002278 '}',
2279 ''],
2280 error_collector)
2281 self.assertEquals(
2282 [operand_error_message % 'Outer::Inner& nonconst_x',
erg@google.com2aa59982013-10-28 19:09:25 +00002283 operand_error_message % 'Outer::Inner& nonconst_y',
2284 operand_error_message % 'Outer<int>::Inner& nonconst_z'],
erg@google.comc6671232013-10-25 21:44:03 +00002285 error_collector.Results())
2286
avakulenko@google.com02af6282014-06-04 18:53:25 +00002287 # A peculiar false positive due to bad template argument parsing
2288 error_collector = ErrorCollector(self.assert_)
2289 cpplint.ProcessFileData(
2290 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002291 ['// Copyright 2014 Your Company. All Rights Reserved.',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002292 'inline RCULocked<X>::ReadPtr::ReadPtr(const RCULocked* rcu) {',
2293 ' DCHECK(!(data & kFlagMask)) << "Error";',
2294 '}',
2295 '',
2296 'RCULocked<X>::WritePtr::WritePtr(RCULocked* rcu)',
2297 ' : lock_(&rcu_->mutex_) {',
2298 '}',
2299 ''],
2300 error_collector.Results())
2301 self.assertEquals('', error_collector.Results())
2302
erg@google.com4e00b9a2009-01-12 23:05:11 +00002303 def testBraceAtBeginOfLine(self):
2304 self.TestLint('{',
2305 '{ should almost always be at the end of the previous line'
2306 ' [whitespace/braces] [4]')
2307
erg@google.comd350fe52013-01-14 17:51:48 +00002308 error_collector = ErrorCollector(self.assert_)
2309 cpplint.ProcessFileData('foo.cc', 'cc',
2310 ['int function()',
2311 '{', # warning here
2312 ' MutexLock l(&mu);',
2313 '}',
2314 'int variable;'
2315 '{', # no warning
2316 ' MutexLock l(&mu);',
2317 '}',
erg@google.comc6671232013-10-25 21:44:03 +00002318 'MyType m = {',
2319 ' {value1, value2},',
2320 ' {', # no warning
2321 ' loooong_value1, looooong_value2',
2322 ' }',
2323 '};',
erg@google.comd350fe52013-01-14 17:51:48 +00002324 '#if PREPROCESSOR',
2325 '{', # no warning
2326 ' MutexLock l(&mu);',
2327 '}',
2328 '#endif'],
2329 error_collector)
2330 self.assertEquals(1, error_collector.Results().count(
2331 '{ should almost always be at the end of the previous line'
2332 ' [whitespace/braces] [4]'))
2333
erg@google.com2aa59982013-10-28 19:09:25 +00002334 self.TestMultiLineLint(
2335 """
2336 foo(
2337 {
2338 loooooooooooooooong_value,
2339 });""",
2340 '')
2341
erg@google.com4e00b9a2009-01-12 23:05:11 +00002342 def testMismatchingSpacesInParens(self):
2343 self.TestLint('if (foo ) {', 'Mismatching spaces inside () in if'
2344 ' [whitespace/parens] [5]')
2345 self.TestLint('switch ( foo) {', 'Mismatching spaces inside () in switch'
2346 ' [whitespace/parens] [5]')
erg@google.come35f7652009-06-19 20:52:09 +00002347 self.TestLint('for (foo; ba; bar ) {', 'Mismatching spaces inside () in for'
2348 ' [whitespace/parens] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002349 self.TestLint('for (; foo; bar) {', '')
2350 self.TestLint('for ( ; foo; bar) {', '')
2351 self.TestLint('for ( ; foo; bar ) {', '')
erg@google.come35f7652009-06-19 20:52:09 +00002352 self.TestLint('for (foo; bar; ) {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002353 self.TestLint('while ( foo ) {', 'Should have zero or one spaces inside'
2354 ' ( and ) in while [whitespace/parens] [5]')
2355
2356 def testSpacingForFncall(self):
2357 self.TestLint('if (foo) {', '')
erg@google.comd7d27472011-09-07 17:36:35 +00002358 self.TestLint('for (foo; bar; baz) {', '')
2359 self.TestLint('for (;;) {', '')
erg@google.comc6671232013-10-25 21:44:03 +00002360 # Space should be allowed in placement new operators.
2361 self.TestLint('Something* p = new (place) Something();', '')
erg@google.comd7d27472011-09-07 17:36:35 +00002362 # Test that there is no warning when increment statement is empty.
2363 self.TestLint('for (foo; baz;) {', '')
2364 self.TestLint('for (foo;bar;baz) {', 'Missing space after ;'
2365 ' [whitespace/semicolon] [3]')
2366 # we don't warn about this semicolon, at least for now
2367 self.TestLint('if (condition) {return &something; }',
2368 '')
2369 # seen in some macros
2370 self.TestLint('DoSth();\\', '')
2371 # Test that there is no warning about semicolon here.
2372 self.TestLint('abc;// this is abc',
2373 'At least two spaces is best between code'
2374 ' and comments [whitespace/comments] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002375 self.TestLint('while (foo) {', '')
2376 self.TestLint('switch (foo) {', '')
2377 self.TestLint('foo( bar)', 'Extra space after ( in function call'
2378 ' [whitespace/parens] [4]')
erg@google.comd7d27472011-09-07 17:36:35 +00002379 self.TestLint('foo( // comment', '')
2380 self.TestLint('foo( // comment',
2381 'At least two spaces is best between code'
2382 ' and comments [whitespace/comments] [2]')
erg@google.com36649102009-03-25 21:18:36 +00002383 self.TestLint('foobar( \\', '')
2384 self.TestLint('foobar( \\', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002385 self.TestLint('( a + b)', 'Extra space after ('
2386 ' [whitespace/parens] [2]')
2387 self.TestLint('((a+b))', '')
2388 self.TestLint('foo (foo)', 'Extra space before ( in function call'
2389 ' [whitespace/parens] [4]')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002390 # asm volatile () may have a space, as it isn't a function call.
2391 self.TestLint('asm volatile ("")', '')
2392 self.TestLint('__asm__ __volatile__ ("")', '')
erg@google.comfd5da632013-10-25 17:39:45 +00002393 self.TestLint('} catch (const Foo& ex) {', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00002394 self.TestLint('case (42):', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002395 self.TestLint('typedef foo (*foo)(foo)', '')
2396 self.TestLint('typedef foo (*foo12bar_)(foo)', '')
2397 self.TestLint('typedef foo (Foo::*bar)(foo)', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002398 self.TestLint('using foo = type (Foo::*bar)(foo)', '')
2399 self.TestLint('using foo = type (Foo::*bar)(', '')
2400 self.TestLint('using foo = type (Foo::*)(', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002401 self.TestLint('foo (Foo::*bar)(', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002402 self.TestLint('foo (x::y::*z)(', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002403 self.TestLint('foo (Foo::bar)(',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002404 'Extra space before ( in function call'
2405 ' [whitespace/parens] [4]')
erg@google.comd350fe52013-01-14 17:51:48 +00002406 self.TestLint('foo (*bar)(', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002407 self.TestLint('typedef foo (Foo::*bar)(', '')
2408 self.TestLint('(foo)(bar)', '')
2409 self.TestLint('Foo (*foo)(bar)', '')
2410 self.TestLint('Foo (*foo)(Bar bar,', '')
2411 self.TestLint('char (*p)[sizeof(foo)] = &foo', '')
2412 self.TestLint('char (&ref)[sizeof(foo)] = &foo', '')
2413 self.TestLint('const char32 (*table[])[6];', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002414 # The sizeof operator is often written as if it were a function call, with
2415 # an opening parenthesis directly following the operator name, but it can
2416 # also be written like any other operator, with a space following the
2417 # operator name, and the argument optionally in parentheses.
2418 self.TestLint('sizeof(foo)', '')
2419 self.TestLint('sizeof foo', '')
2420 self.TestLint('sizeof (foo)', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002421
2422 def testSpacingBeforeBraces(self):
2423 self.TestLint('if (foo){', 'Missing space before {'
2424 ' [whitespace/braces] [5]')
2425 self.TestLint('for{', 'Missing space before {'
2426 ' [whitespace/braces] [5]')
2427 self.TestLint('for {', '')
2428 self.TestLint('EXPECT_DEBUG_DEATH({', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00002429 self.TestLint('std::is_convertible<A, B>{}', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002430 self.TestLint('blah{32}', 'Missing space before {'
2431 ' [whitespace/braces] [5]')
2432 self.TestLint('int8_t{3}', '')
2433 self.TestLint('int16_t{3}', '')
2434 self.TestLint('int32_t{3}', '')
2435 self.TestLint('uint64_t{12345}', '')
2436 self.TestLint('constexpr int64_t kBatchGapMicros ='
2437 ' int64_t{7} * 24 * 3600 * 1000000; // 1 wk.', '')
2438 self.TestLint('MoveOnly(int i1, int i2) : ip1{new int{i1}}, '
2439 'ip2{new int{i2}} {}',
2440 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002441
erg@google.comfd5da632013-10-25 17:39:45 +00002442 def testSemiColonAfterBraces(self):
Alex Vakulenko01e47232016-05-06 13:54:15 -07002443 self.TestLint('if (cond) { func(); };',
erg@google.comfd5da632013-10-25 17:39:45 +00002444 'You don\'t need a ; after a } [readability/braces] [4]')
erg@google.com2aa59982013-10-28 19:09:25 +00002445 self.TestLint('void Func() {};',
2446 'You don\'t need a ; after a } [readability/braces] [4]')
2447 self.TestLint('void Func() const {};',
2448 'You don\'t need a ; after a } [readability/braces] [4]')
erg@google.comfd5da632013-10-25 17:39:45 +00002449 self.TestLint('class X {};', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00002450 for keyword in ['struct', 'union']:
2451 for align in ['', ' alignas(16)']:
2452 for typename in ['', ' X']:
2453 for identifier in ['', ' x']:
2454 self.TestLint(keyword + align + typename + ' {}' + identifier + ';',
2455 '')
erg@google.com2aa59982013-10-28 19:09:25 +00002456
2457 self.TestLint('class X : public Y {};', '')
2458 self.TestLint('class X : public MACRO() {};', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002459 self.TestLint('class X : public decltype(expr) {};', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002460 self.TestLint('DEFINE_FACADE(PCQueue::Watcher, PCQueue) {};', '')
2461 self.TestLint('VCLASS(XfaTest, XfaContextTest) {};', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002462 self.TestLint('class STUBBY_CLASS(H, E) {};', '')
2463 self.TestLint('class STUBBY2_CLASS(H, E) {};', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002464 self.TestLint('TEST(TestCase, TestName) {};',
2465 'You don\'t need a ; after a } [readability/braces] [4]')
2466 self.TestLint('TEST_F(TestCase, TestName) {};',
2467 'You don\'t need a ; after a } [readability/braces] [4]')
2468
2469 self.TestLint('file_tocs_[i] = (FileToc) {a, b, c};', '')
2470 self.TestMultiLineLint('class X : public Y,\npublic Z {};', '')
2471
avakulenko@google.com02af6282014-06-04 18:53:25 +00002472 def testLambda(self):
2473 self.TestLint('auto x = []() {};', '')
2474 self.TestLint('return []() {};', '')
2475 self.TestMultiLineLint('auto x = []() {\n};\n', '')
2476 self.TestLint('int operator[](int x) {};',
2477 'You don\'t need a ; after a } [readability/braces] [4]')
2478
2479 self.TestMultiLineLint('auto x = [&a,\nb]() {};', '')
2480 self.TestMultiLineLint('auto x = [&a,\nb]\n() {};', '')
2481 self.TestMultiLineLint('auto x = [&a,\n'
2482 ' b](\n'
2483 ' int a,\n'
2484 ' int b) {\n'
2485 ' return a +\n'
2486 ' b;\n'
2487 '};\n',
2488 '')
2489
avakulenko@google.com02af6282014-06-04 18:53:25 +00002490 # Avoid false positives with operator[]
2491 self.TestLint('table_to_children[&*table].push_back(dependent);', '')
2492
erg@google.com2aa59982013-10-28 19:09:25 +00002493 def testBraceInitializerList(self):
2494 self.TestLint('MyStruct p = {1, 2};', '')
2495 self.TestLint('MyStruct p{1, 2};', '')
2496 self.TestLint('vector<int> p = {1, 2};', '')
2497 self.TestLint('vector<int> p{1, 2};', '')
2498 self.TestLint('x = vector<int>{1, 2};', '')
2499 self.TestLint('x = (struct in_addr){ 0 };', '')
2500 self.TestLint('Func(vector<int>{1, 2})', '')
2501 self.TestLint('Func((struct in_addr){ 0 })', '')
2502 self.TestLint('Func(vector<int>{1, 2}, 3)', '')
2503 self.TestLint('Func((struct in_addr){ 0 }, 3)', '')
2504 self.TestLint('LOG(INFO) << char{7};', '')
2505 self.TestLint('LOG(INFO) << char{7} << "!";', '')
2506 self.TestLint('int p[2] = {1, 2};', '')
2507 self.TestLint('return {1, 2};', '')
2508 self.TestLint('std::unique_ptr<Foo> foo{new Foo{}};', '')
2509 self.TestLint('auto foo = std::unique_ptr<Foo>{new Foo{}};', '')
2510 self.TestLint('static_assert(Max7String{}.IsValid(), "");', '')
2511 self.TestLint('map_of_pairs[{1, 2}] = 3;', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002512 self.TestLint('ItemView{has_offer() ? new Offer{offer()} : nullptr', '')
2513 self.TestLint('template <class T, EnableIf<::std::is_const<T>{}> = 0>', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002514
2515 self.TestMultiLineLint('std::unique_ptr<Foo> foo{\n'
2516 ' new Foo{}\n'
2517 '};\n', '')
2518 self.TestMultiLineLint('std::unique_ptr<Foo> foo{\n'
2519 ' new Foo{\n'
2520 ' new Bar{}\n'
2521 ' }\n'
2522 '};\n', '')
2523 self.TestMultiLineLint('if (true) {\n'
Alex Vakulenko01e47232016-05-06 13:54:15 -07002524 ' if (false){ func(); }\n'
erg@google.com2aa59982013-10-28 19:09:25 +00002525 '}\n',
2526 'Missing space before { [whitespace/braces] [5]')
2527 self.TestMultiLineLint('MyClass::MyClass()\n'
2528 ' : initializer_{\n'
2529 ' Func()} {\n'
2530 '}\n', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002531 self.TestLint('const pair<string, string> kCL' +
2532 ('o' * 41) + 'gStr[] = {\n',
2533 'Lines should be <= 80 characters long'
2534 ' [whitespace/line_length] [2]')
2535 self.TestMultiLineLint('const pair<string, string> kCL' +
2536 ('o' * 40) + 'ngStr[] =\n'
2537 ' {\n'
2538 ' {"gooooo", "oooogle"},\n'
2539 '};\n', '')
2540 self.TestMultiLineLint('const pair<string, string> kCL' +
2541 ('o' * 39) + 'ngStr[] =\n'
2542 ' {\n'
2543 ' {"gooooo", "oooogle"},\n'
2544 '};\n', '{ should almost always be at the end of '
2545 'the previous line [whitespace/braces] [4]')
erg@google.comfd5da632013-10-25 17:39:45 +00002546
erg@google.com4e00b9a2009-01-12 23:05:11 +00002547 def testSpacingAroundElse(self):
2548 self.TestLint('}else {', 'Missing space before else'
2549 ' [whitespace/braces] [5]')
2550 self.TestLint('} else{', 'Missing space before {'
2551 ' [whitespace/braces] [5]')
2552 self.TestLint('} else {', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002553 self.TestLint('} else if (foo) {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002554
erg@google.com8a95ecc2011-09-08 00:45:54 +00002555 def testSpacingWithInitializerLists(self):
2556 self.TestLint('int v[1][3] = {{1, 2, 3}};', '')
2557 self.TestLint('int v[1][1] = {{0}};', '')
2558
erg@google.com4e00b9a2009-01-12 23:05:11 +00002559 def testSpacingForBinaryOps(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00002560 self.TestLint('if (foo||bar) {', 'Missing spaces around ||'
2561 ' [whitespace/operators] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002562 self.TestLint('if (foo<=bar) {', 'Missing spaces around <='
2563 ' [whitespace/operators] [3]')
2564 self.TestLint('if (foo<bar) {', 'Missing spaces around <'
2565 ' [whitespace/operators] [3]')
erg@google.comd350fe52013-01-14 17:51:48 +00002566 self.TestLint('if (foo>bar) {', 'Missing spaces around >'
2567 ' [whitespace/operators] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002568 self.TestLint('if (foo<bar->baz) {', 'Missing spaces around <'
2569 ' [whitespace/operators] [3]')
2570 self.TestLint('if (foo<bar->bar) {', 'Missing spaces around <'
2571 ' [whitespace/operators] [3]')
erg@google.comd350fe52013-01-14 17:51:48 +00002572 self.TestLint('template<typename T = double>', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002573 self.TestLint('std::unique_ptr<No<Spaces>>', '')
2574 self.TestLint('typedef hash_map<Foo, Bar>', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002575 self.TestLint('10<<20', '')
2576 self.TestLint('10<<a',
2577 'Missing spaces around << [whitespace/operators] [3]')
2578 self.TestLint('a<<20',
2579 'Missing spaces around << [whitespace/operators] [3]')
2580 self.TestLint('a<<b',
2581 'Missing spaces around << [whitespace/operators] [3]')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002582 self.TestLint('10LL<<20', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002583 self.TestLint('10ULL<<20', '')
2584 self.TestLint('a>>b',
2585 'Missing spaces around >> [whitespace/operators] [3]')
2586 self.TestLint('10>>b',
2587 'Missing spaces around >> [whitespace/operators] [3]')
2588 self.TestLint('LOG(ERROR)<<*foo',
2589 'Missing spaces around << [whitespace/operators] [3]')
2590 self.TestLint('LOG(ERROR)<<&foo',
2591 'Missing spaces around << [whitespace/operators] [3]')
2592 self.TestLint('StringCoder<vector<string>>::ToString()', '')
2593 self.TestLint('map<pair<int, int>, map<int, int>>::iterator', '')
2594 self.TestLint('func<int, pair<int, pair<int, int>>>()', '')
2595 self.TestLint('MACRO1(list<list<int>>)', '')
2596 self.TestLint('MACRO2(list<list<int>>, 42)', '')
2597 self.TestLint('void DoFoo(const set<vector<string>>& arg1);', '')
2598 self.TestLint('void SetFoo(set<vector<string>>* arg1);', '')
2599 self.TestLint('foo = new set<vector<string>>;', '')
2600 self.TestLint('reinterpret_cast<set<vector<string>>*>(a);', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002601 self.TestLint('MACRO(<<)', '')
2602 self.TestLint('MACRO(<<, arg)', '')
2603 self.TestLint('MACRO(<<=)', '')
2604 self.TestLint('MACRO(<<=, arg)', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002605
avakulenko@google.com02af6282014-06-04 18:53:25 +00002606 self.TestLint('using Vector3<T>::operator==;', '')
2607 self.TestLint('using Vector3<T>::operator!=;', '')
2608
erg@google.com4e00b9a2009-01-12 23:05:11 +00002609 def testSpacingBeforeLastSemicolon(self):
2610 self.TestLint('call_function() ;',
2611 'Extra space before last semicolon. If this should be an '
erg@google.comd350fe52013-01-14 17:51:48 +00002612 'empty statement, use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002613 ' [whitespace/semicolon] [5]')
2614 self.TestLint('while (true) ;',
2615 'Extra space before last semicolon. If this should be an '
erg@google.comd350fe52013-01-14 17:51:48 +00002616 'empty statement, use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002617 ' [whitespace/semicolon] [5]')
2618 self.TestLint('default:;',
erg@google.comd350fe52013-01-14 17:51:48 +00002619 'Semicolon defining empty statement. Use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002620 ' [whitespace/semicolon] [5]')
2621 self.TestLint(' ;',
2622 'Line contains only semicolon. If this should be an empty '
erg@google.comd350fe52013-01-14 17:51:48 +00002623 'statement, use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002624 ' [whitespace/semicolon] [5]')
2625 self.TestLint('for (int i = 0; ;', '')
2626
erg@google.comc6671232013-10-25 21:44:03 +00002627 def testEmptyBlockBody(self):
erg@google.comd350fe52013-01-14 17:51:48 +00002628 self.TestLint('while (true);',
2629 'Empty loop bodies should use {} or continue'
2630 ' [whitespace/empty_loop_body] [5]')
erg@google.comc6671232013-10-25 21:44:03 +00002631 self.TestLint('if (true);',
2632 'Empty conditional bodies should use {}'
2633 ' [whitespace/empty_conditional_body] [5]')
erg@google.comd350fe52013-01-14 17:51:48 +00002634 self.TestLint('while (true)', '')
2635 self.TestLint('while (true) continue;', '')
2636 self.TestLint('for (;;);',
2637 'Empty loop bodies should use {} or continue'
2638 ' [whitespace/empty_loop_body] [5]')
2639 self.TestLint('for (;;)', '')
2640 self.TestLint('for (;;) continue;', '')
2641 self.TestLint('for (;;) func();', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002642 self.TestLint('if (test) {}',
2643 'If statement had no body and no else clause'
2644 ' [whitespace/empty_if_body] [4]')
2645 self.TestLint('if (test) func();', '')
2646 self.TestLint('if (test) {} else {}', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002647 self.TestMultiLineLint("""while (true &&
2648 false);""",
2649 'Empty loop bodies should use {} or continue'
2650 ' [whitespace/empty_loop_body] [5]')
2651 self.TestMultiLineLint("""do {
2652 } while (false);""",
2653 '')
2654 self.TestMultiLineLint("""#define MACRO \\
2655 do { \\
2656 } while (false);""",
2657 '')
2658 self.TestMultiLineLint("""do {
2659 } while (false); // next line gets a warning
2660 while (false);""",
2661 'Empty loop bodies should use {} or continue'
2662 ' [whitespace/empty_loop_body] [5]')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002663 self.TestMultiLineLint("""if (test) {
2664 }""",
2665 'If statement had no body and no else clause'
2666 ' [whitespace/empty_if_body] [4]')
2667 self.TestMultiLineLint("""if (test,
2668 func({})) {
2669 }""",
2670 'If statement had no body and no else clause'
2671 ' [whitespace/empty_if_body] [4]')
2672 self.TestMultiLineLint("""if (test)
2673 func();""", '')
2674 self.TestLint('if (test) { hello; }', '')
2675 self.TestLint('if (test({})) { hello; }', '')
2676 self.TestMultiLineLint("""if (test) {
2677 func();
2678 }""", '')
2679 self.TestMultiLineLint("""if (test) {
2680 // multiline
2681 // comment
2682 }""", '')
2683 self.TestMultiLineLint("""if (test) { // comment
2684 }""", '')
2685 self.TestMultiLineLint("""if (test) {
2686 } else {
2687 }""", '')
2688 self.TestMultiLineLint("""if (func(p1,
2689 p2,
2690 p3)) {
2691 func();
2692 }""", '')
2693 self.TestMultiLineLint("""if (func({}, p1)) {
2694 func();
2695 }""", '')
erg@google.comd350fe52013-01-14 17:51:48 +00002696
2697 def testSpacingForRangeBasedFor(self):
2698 # Basic correctly formatted case:
2699 self.TestLint('for (int i : numbers) {', '')
2700
2701 # Missing space before colon:
2702 self.TestLint('for (int i: numbers) {',
2703 'Missing space around colon in range-based for loop'
2704 ' [whitespace/forcolon] [2]')
2705 # Missing space after colon:
2706 self.TestLint('for (int i :numbers) {',
2707 'Missing space around colon in range-based for loop'
2708 ' [whitespace/forcolon] [2]')
2709 # Missing spaces both before and after the colon.
2710 self.TestLint('for (int i:numbers) {',
2711 'Missing space around colon in range-based for loop'
2712 ' [whitespace/forcolon] [2]')
2713
2714 # The scope operator '::' shouldn't cause warnings...
2715 self.TestLint('for (std::size_t i : sizes) {}', '')
2716 # ...but it shouldn't suppress them either.
2717 self.TestLint('for (std::size_t i: sizes) {}',
2718 'Missing space around colon in range-based for loop'
2719 ' [whitespace/forcolon] [2]')
2720
2721
erg@google.com4e00b9a2009-01-12 23:05:11 +00002722 # Static or global STL strings.
2723 def testStaticOrGlobalSTLStrings(self):
Alex Vakulenko01e47232016-05-06 13:54:15 -07002724 # A template for the error message for a const global/static string.
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002725 error_msg = ('For a static/global string constant, use a C style '
2726 'string instead: "%s[]". [runtime/string] [4]')
2727
Alex Vakulenko01e47232016-05-06 13:54:15 -07002728 # The error message for a non-const global/static string variable.
2729 nonconst_error_msg = ('Static/global string variables are not permitted.'
2730 ' [runtime/string] [4]')
2731
erg@google.com4e00b9a2009-01-12 23:05:11 +00002732 self.TestLint('string foo;',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002733 nonconst_error_msg)
erg@google.com4e00b9a2009-01-12 23:05:11 +00002734 self.TestLint('string kFoo = "hello"; // English',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002735 nonconst_error_msg)
erg@google.com4e00b9a2009-01-12 23:05:11 +00002736 self.TestLint('static string foo;',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002737 nonconst_error_msg)
erg@google.com4e00b9a2009-01-12 23:05:11 +00002738 self.TestLint('static const string foo;',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002739 error_msg % 'static const char foo')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002740 self.TestLint('static const std::string foo;',
2741 error_msg % 'static const char foo')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002742 self.TestLint('string Foo::bar;',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002743 nonconst_error_msg)
2744
2745 self.TestLint('std::string foo;',
2746 nonconst_error_msg)
2747 self.TestLint('std::string kFoo = "hello"; // English',
2748 nonconst_error_msg)
2749 self.TestLint('static std::string foo;',
2750 nonconst_error_msg)
2751 self.TestLint('static const std::string foo;',
2752 error_msg % 'static const char foo')
2753 self.TestLint('std::string Foo::bar;',
2754 nonconst_error_msg)
2755
2756 self.TestLint('::std::string foo;',
2757 nonconst_error_msg)
2758 self.TestLint('::std::string kFoo = "hello"; // English',
2759 nonconst_error_msg)
2760 self.TestLint('static ::std::string foo;',
2761 nonconst_error_msg)
2762 self.TestLint('static const ::std::string foo;',
2763 error_msg % 'static const char foo')
2764 self.TestLint('::std::string Foo::bar;',
2765 nonconst_error_msg)
2766
avakulenko@google.com02af6282014-06-04 18:53:25 +00002767 self.TestLint('string* pointer', '')
2768 self.TestLint('string *pointer', '')
2769 self.TestLint('string* pointer = Func();', '')
2770 self.TestLint('string *pointer = Func();', '')
2771 self.TestLint('const string* pointer', '')
2772 self.TestLint('const string *pointer', '')
2773 self.TestLint('const string* pointer = Func();', '')
2774 self.TestLint('const string *pointer = Func();', '')
2775 self.TestLint('string const* pointer', '')
2776 self.TestLint('string const *pointer', '')
2777 self.TestLint('string const* pointer = Func();', '')
2778 self.TestLint('string const *pointer = Func();', '')
2779 self.TestLint('string* const pointer', '')
2780 self.TestLint('string *const pointer', '')
2781 self.TestLint('string* const pointer = Func();', '')
2782 self.TestLint('string *const pointer = Func();', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002783 self.TestLint('string Foo::bar() {}', '')
2784 self.TestLint('string Foo::operator*() {}', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002785 # Rare case.
Alex Vakulenko01e47232016-05-06 13:54:15 -07002786 self.TestLint('string foo("foobar");', nonconst_error_msg)
erg@google.com4e00b9a2009-01-12 23:05:11 +00002787 # Should not catch local or member variables.
2788 self.TestLint(' string foo', '')
2789 # Should not catch functions.
2790 self.TestLint('string EmptyString() { return ""; }', '')
2791 self.TestLint('string EmptyString () { return ""; }', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002792 self.TestLint('string const& FileInfo::Pathname() const;', '')
2793 self.TestLint('string const &FileInfo::Pathname() const;', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002794 self.TestLint('string VeryLongNameFunctionSometimesEndsWith(\n'
2795 ' VeryLongNameType very_long_name_variable) {}', '')
2796 self.TestLint('template<>\n'
2797 'string FunctionTemplateSpecialization<SomeType>(\n'
2798 ' int x) { return ""; }', '')
2799 self.TestLint('template<>\n'
2800 'string FunctionTemplateSpecialization<vector<A::B>* >(\n'
2801 ' int x) { return ""; }', '')
2802
2803 # should not catch methods of template classes.
2804 self.TestLint('string Class<Type>::Method() const {\n'
2805 ' return "";\n'
2806 '}\n', '')
2807 self.TestLint('string Class<Type>::Method(\n'
2808 ' int arg) const {\n'
2809 ' return "";\n'
2810 '}\n', '')
2811
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002812 # Check multiline cases.
2813 error_collector = ErrorCollector(self.assert_)
2814 cpplint.ProcessFileData('foo.cc', 'cc',
2815 ['// Copyright 2014 Your Company.',
2816 'string Class',
2817 '::MemberFunction1();',
2818 'string Class::',
2819 'MemberFunction2();',
2820 'string Class::',
2821 'NestedClass::MemberFunction3();',
2822 'string TemplateClass<T>::',
2823 'NestedClass::MemberFunction4();',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002824 'const string Class',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002825 '::static_member_variable1;',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002826 'const string Class::',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002827 'static_member_variable2;',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002828 'const string Class',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002829 '::static_member_variable3 = "initial value";',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002830 'const string Class::',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002831 'static_member_variable4 = "initial value";',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002832 'string Class::',
2833 'static_member_variable5;',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002834 ''],
2835 error_collector)
2836 self.assertEquals(error_collector.Results(),
Alex Vakulenko01e47232016-05-06 13:54:15 -07002837 [error_msg % 'const char Class::static_member_variable1',
2838 error_msg % 'const char Class::static_member_variable2',
2839 error_msg % 'const char Class::static_member_variable3',
2840 error_msg % 'const char Class::static_member_variable4',
2841 nonconst_error_msg])
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002842
erg@google.com4e00b9a2009-01-12 23:05:11 +00002843 def testNoSpacesInFunctionCalls(self):
2844 self.TestLint('TellStory(1, 3);',
2845 '')
2846 self.TestLint('TellStory(1, 3 );',
2847 'Extra space before )'
2848 ' [whitespace/parens] [2]')
2849 self.TestLint('TellStory(1 /* wolf */, 3 /* pigs */);',
2850 '')
erg@google.com8a95ecc2011-09-08 00:45:54 +00002851 self.TestMultiLineLint("""TellStory(1, 3
2852 );""",
2853 'Closing ) should be moved to the previous line'
2854 ' [whitespace/parens] [2]')
2855 self.TestMultiLineLint("""TellStory(Wolves(1),
2856 Pigs(3
2857 ));""",
2858 'Closing ) should be moved to the previous line'
2859 ' [whitespace/parens] [2]')
2860 self.TestMultiLineLint("""TellStory(1,
2861 3 );""",
2862 'Extra space before )'
2863 ' [whitespace/parens] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002864
2865 def testToDoComments(self):
2866 start_space = ('Too many spaces before TODO'
2867 ' [whitespace/todo] [2]')
2868 missing_username = ('Missing username in TODO; it should look like '
2869 '"// TODO(my_username): Stuff."'
2870 ' [readability/todo] [2]')
2871 end_space = ('TODO(my_username) should be followed by a space'
2872 ' [whitespace/todo] [2]')
2873
2874 self.TestLint('// TODOfix this',
2875 [start_space, missing_username, end_space])
2876 self.TestLint('// TODO(ljenkins)fix this',
2877 [start_space, end_space])
2878 self.TestLint('// TODO fix this',
2879 [start_space, missing_username])
2880 self.TestLint('// TODO fix this', missing_username)
2881 self.TestLint('// TODO: fix this', missing_username)
2882 self.TestLint('//TODO(ljenkins): Fix this',
2883 'Should have a space between // and comment'
2884 ' [whitespace/comments] [4]')
2885 self.TestLint('// TODO(ljenkins):Fix this', end_space)
2886 self.TestLint('// TODO(ljenkins):', '')
2887 self.TestLint('// TODO(ljenkins): fix this', '')
2888 self.TestLint('// TODO(ljenkins): Fix this', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002889 self.TestLint('#if 1 // TEST_URLTODOCID_WHICH_HAS_THAT_WORD_IN_IT_H_', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002890 self.TestLint('// See also similar TODO above', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002891 self.TestLint(r'EXPECT_EQ("\\", '
2892 r'NormalizePath("/./../foo///bar/..//x/../..", ""));',
2893 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002894
2895 def testTwoSpacesBetweenCodeAndComments(self):
2896 self.TestLint('} // namespace foo',
2897 'At least two spaces is best between code and comments'
2898 ' [whitespace/comments] [2]')
2899 self.TestLint('}// namespace foo',
2900 'At least two spaces is best between code and comments'
2901 ' [whitespace/comments] [2]')
2902 self.TestLint('printf("foo"); // Outside quotes.',
2903 'At least two spaces is best between code and comments'
2904 ' [whitespace/comments] [2]')
2905 self.TestLint('int i = 0; // Having two spaces is fine.', '')
2906 self.TestLint('int i = 0; // Having three spaces is OK.', '')
2907 self.TestLint('// Top level comment', '')
2908 self.TestLint(' // Line starts with two spaces.', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002909 self.TestMultiLineLint('void foo() {\n'
2910 ' { // A scope is opening.\n'
2911 ' int a;', '')
2912 self.TestMultiLineLint('void foo() {\n'
2913 ' { // A scope is opening.\n'
2914 '#define A a',
2915 'At least two spaces is best between code and '
2916 'comments [whitespace/comments] [2]')
2917 self.TestMultiLineLint(' foo();\n'
2918 ' { // An indented scope is opening.\n'
2919 ' int a;', '')
2920 self.TestMultiLineLint('vector<int> my_elements = {// first\n'
2921 ' 1,', '')
2922 self.TestMultiLineLint('vector<int> my_elements = {// my_elements is ..\n'
2923 ' 1,',
2924 'At least two spaces is best between code and '
2925 'comments [whitespace/comments] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002926 self.TestLint('if (foo) { // not a pure scope; comment is too close!',
2927 'At least two spaces is best between code and comments'
2928 ' [whitespace/comments] [2]')
2929 self.TestLint('printf("// In quotes.")', '')
2930 self.TestLint('printf("\\"%s // In quotes.")', '')
2931 self.TestLint('printf("%s", "// In quotes.")', '')
2932
2933 def testSpaceAfterCommentMarker(self):
2934 self.TestLint('//', '')
2935 self.TestLint('//x', 'Should have a space between // and comment'
2936 ' [whitespace/comments] [4]')
2937 self.TestLint('// x', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00002938 self.TestLint('///', '')
2939 self.TestLint('/// x', '')
2940 self.TestLint('//!', '')
erg@google.come35f7652009-06-19 20:52:09 +00002941 self.TestLint('//----', '')
2942 self.TestLint('//====', '')
2943 self.TestLint('//////', '')
2944 self.TestLint('////// x', '')
erg@google.com6d8d9832013-10-31 19:46:18 +00002945 self.TestLint('///< x', '') # After-member Doxygen comment
2946 self.TestLint('//!< x', '') # After-member Doxygen comment
erg@google.come35f7652009-06-19 20:52:09 +00002947 self.TestLint('////x', 'Should have a space between // and comment'
2948 ' [whitespace/comments] [4]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002949 self.TestLint('//}', '')
2950 self.TestLint('//}x', 'Should have a space between // and comment'
2951 ' [whitespace/comments] [4]')
erg@google.com6d8d9832013-10-31 19:46:18 +00002952 self.TestLint('//!<x', 'Should have a space between // and comment'
2953 ' [whitespace/comments] [4]')
2954 self.TestLint('///<x', 'Should have a space between // and comment'
2955 ' [whitespace/comments] [4]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002956
2957 # Test a line preceded by empty or comment lines. There was a bug
2958 # that caused it to print the same warning N times if the erroneous
2959 # line was preceded by N lines of empty or comment lines. To be
2960 # precise, the '// marker so line numbers and indices both start at
2961 # 1' line was also causing the issue.
2962 def testLinePrecededByEmptyOrCommentLines(self):
2963 def DoTest(self, lines):
2964 error_collector = ErrorCollector(self.assert_)
2965 cpplint.ProcessFileData('foo.cc', 'cc', lines, error_collector)
2966 # The warning appears only once.
2967 self.assertEquals(
2968 1,
2969 error_collector.Results().count(
2970 'Do not use namespace using-directives. '
2971 'Use using-declarations instead.'
2972 ' [build/namespaces] [5]'))
2973 DoTest(self, ['using namespace foo;'])
2974 DoTest(self, ['', '', '', 'using namespace foo;'])
2975 DoTest(self, ['// hello', 'using namespace foo;'])
2976
2977 def testNewlineAtEOF(self):
2978 def DoTest(self, data, is_missing_eof):
2979 error_collector = ErrorCollector(self.assert_)
2980 cpplint.ProcessFileData('foo.cc', 'cc', data.split('\n'),
2981 error_collector)
2982 # The warning appears only once.
2983 self.assertEquals(
2984 int(is_missing_eof),
2985 error_collector.Results().count(
2986 'Could not find a newline character at the end of the file.'
2987 ' [whitespace/ending_newline] [5]'))
2988
2989 DoTest(self, '// Newline\n// at EOF\n', False)
2990 DoTest(self, '// No newline\n// at EOF', True)
2991
2992 def testInvalidUtf8(self):
2993 def DoTest(self, raw_bytes, has_invalid_utf8):
2994 error_collector = ErrorCollector(self.assert_)
2995 cpplint.ProcessFileData(
2996 'foo.cc', 'cc',
2997 unicode(raw_bytes, 'utf8', 'replace').split('\n'),
2998 error_collector)
2999 # The warning appears only once.
3000 self.assertEquals(
3001 int(has_invalid_utf8),
3002 error_collector.Results().count(
3003 'Line contains invalid UTF-8'
3004 ' (or Unicode replacement character).'
3005 ' [readability/utf8] [5]'))
3006
3007 DoTest(self, 'Hello world\n', False)
3008 DoTest(self, '\xe9\x8e\xbd\n', False)
3009 DoTest(self, '\xe9x\x8e\xbd\n', True)
3010 # This is the encoding of the replacement character itself (which
3011 # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')).
3012 DoTest(self, '\xef\xbf\xbd\n', True)
3013
erg@google.com2aa59982013-10-28 19:09:25 +00003014 def testBadCharacters(self):
3015 # Test for NUL bytes only
3016 error_collector = ErrorCollector(self.assert_)
3017 cpplint.ProcessFileData('nul.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003018 ['// Copyright 2014 Your Company.',
erg@google.com2aa59982013-10-28 19:09:25 +00003019 '\0', ''], error_collector)
3020 self.assertEquals(
3021 error_collector.Results(),
3022 'Line contains NUL byte. [readability/nul] [5]')
3023
3024 # Make sure both NUL bytes and UTF-8 are caught if they appear on
3025 # the same line.
3026 error_collector = ErrorCollector(self.assert_)
3027 cpplint.ProcessFileData(
3028 'nul_utf8.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003029 ['// Copyright 2014 Your Company.',
erg@google.com2aa59982013-10-28 19:09:25 +00003030 unicode('\xe9x\0', 'utf8', 'replace'), ''],
3031 error_collector)
3032 self.assertEquals(
3033 error_collector.Results(),
3034 ['Line contains invalid UTF-8 (or Unicode replacement character).'
3035 ' [readability/utf8] [5]',
3036 'Line contains NUL byte. [readability/nul] [5]'])
3037
erg@google.com4e00b9a2009-01-12 23:05:11 +00003038 def testIsBlankLine(self):
3039 self.assert_(cpplint.IsBlankLine(''))
3040 self.assert_(cpplint.IsBlankLine(' '))
3041 self.assert_(cpplint.IsBlankLine(' \t\r\n'))
3042 self.assert_(not cpplint.IsBlankLine('int a;'))
3043 self.assert_(not cpplint.IsBlankLine('{'))
3044
3045 def testBlankLinesCheck(self):
3046 self.TestBlankLinesCheck(['{\n', '\n', '\n', '}\n'], 1, 1)
3047 self.TestBlankLinesCheck([' if (foo) {\n', '\n', ' }\n'], 1, 1)
3048 self.TestBlankLinesCheck(
3049 ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0)
3050 self.TestBlankLinesCheck(['\n', 'run("{");\n', '\n'], 0, 0)
3051 self.TestBlankLinesCheck(['\n', ' if (foo) { return 0; }\n', '\n'], 0, 0)
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003052 self.TestBlankLinesCheck(
3053 ['int x(\n', ' int a) {\n', '\n', 'return 0;\n', '}'], 0, 0)
3054 self.TestBlankLinesCheck(
3055 ['int x(\n', ' int a) const {\n', '\n', 'return 0;\n', '}'], 0, 0)
3056 self.TestBlankLinesCheck(
3057 ['int x(\n', ' int a) {\n', '\n', 'return 0;\n', '}'], 1, 0)
3058 self.TestBlankLinesCheck(
3059 ['int x(\n', ' int a) {\n', '\n', 'return 0;\n', '}'], 1, 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00003060
3061 def testAllowBlankLineBeforeClosingNamespace(self):
3062 error_collector = ErrorCollector(self.assert_)
3063 cpplint.ProcessFileData('foo.cc', 'cc',
erg@google.comd350fe52013-01-14 17:51:48 +00003064 ['namespace {',
3065 '',
3066 '} // namespace',
3067 'namespace another_namespace {',
3068 '',
3069 '}',
3070 'namespace {',
3071 '',
3072 'template<class T, ',
3073 ' class A = hoge<T>, ',
3074 ' class B = piyo<T>, ',
3075 ' class C = fuga<T> >',
3076 'class D {',
3077 ' public:',
3078 '};',
3079 '', '', '', '',
3080 '}'],
erg@google.com4e00b9a2009-01-12 23:05:11 +00003081 error_collector)
3082 self.assertEquals(0, error_collector.Results().count(
erg@google.com2aa59982013-10-28 19:09:25 +00003083 'Redundant blank line at the end of a code block should be deleted.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00003084 ' [whitespace/blank_line] [3]'))
3085
3086 def testAllowBlankLineBeforeIfElseChain(self):
3087 error_collector = ErrorCollector(self.assert_)
3088 cpplint.ProcessFileData('foo.cc', 'cc',
3089 ['if (hoge) {',
3090 '', # No warning
3091 '} else if (piyo) {',
3092 '', # No warning
3093 '} else if (piyopiyo) {',
3094 ' hoge = true;', # No warning
3095 '} else {',
3096 '', # Warning on this line
3097 '}'],
3098 error_collector)
3099 self.assertEquals(1, error_collector.Results().count(
erg@google.com2aa59982013-10-28 19:09:25 +00003100 'Redundant blank line at the end of a code block should be deleted.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00003101 ' [whitespace/blank_line] [3]'))
3102
avakulenko@google.com02af6282014-06-04 18:53:25 +00003103 def testAllowBlankLineAfterExtern(self):
3104 error_collector = ErrorCollector(self.assert_)
3105 cpplint.ProcessFileData('foo.cc', 'cc',
3106 ['extern "C" {',
3107 '',
3108 'EXPORTAPI void APICALL Some_function() {}',
3109 '',
3110 '}'],
3111 error_collector)
3112 self.assertEquals(0, error_collector.Results().count(
3113 'Redundant blank line at the start of a code block should be deleted.'
3114 ' [whitespace/blank_line] [2]'))
3115 self.assertEquals(0, error_collector.Results().count(
3116 'Redundant blank line at the end of a code block should be deleted.'
3117 ' [whitespace/blank_line] [3]'))
3118
erg@google.com8a95ecc2011-09-08 00:45:54 +00003119 def testBlankLineBeforeSectionKeyword(self):
3120 error_collector = ErrorCollector(self.assert_)
3121 cpplint.ProcessFileData('foo.cc', 'cc',
3122 ['class A {',
3123 ' public:',
3124 ' protected:', # warning 1
3125 ' private:', # warning 2
3126 ' struct B {',
3127 ' public:',
3128 ' private:'] + # warning 3
3129 ([''] * 100) + # Make A and B longer than 100 lines
3130 [' };',
3131 ' struct C {',
3132 ' protected:',
3133 ' private:', # C is too short for warnings
3134 ' };',
3135 '};',
3136 'class D',
3137 ' : public {',
3138 ' public:', # no warning
erg@google.comd350fe52013-01-14 17:51:48 +00003139 '};',
3140 'class E {\\',
3141 ' public:\\'] +
3142 (['\\'] * 100) + # Makes E > 100 lines
3143 [' int non_empty_line;\\',
3144 ' private:\\', # no warning
3145 ' int a;\\',
erg@google.com8a95ecc2011-09-08 00:45:54 +00003146 '};'],
3147 error_collector)
3148 self.assertEquals(2, error_collector.Results().count(
3149 '"private:" should be preceded by a blank line'
3150 ' [whitespace/blank_line] [3]'))
3151 self.assertEquals(1, error_collector.Results().count(
3152 '"protected:" should be preceded by a blank line'
3153 ' [whitespace/blank_line] [3]'))
3154
3155 def testNoBlankLineAfterSectionKeyword(self):
3156 error_collector = ErrorCollector(self.assert_)
3157 cpplint.ProcessFileData('foo.cc', 'cc',
3158 ['class A {',
3159 ' public:',
3160 '', # warning 1
3161 ' private:',
3162 '', # warning 2
3163 ' struct B {',
3164 ' protected:',
3165 '', # warning 3
3166 ' };',
3167 '};'],
3168 error_collector)
3169 self.assertEquals(1, error_collector.Results().count(
3170 'Do not leave a blank line after "public:"'
3171 ' [whitespace/blank_line] [3]'))
3172 self.assertEquals(1, error_collector.Results().count(
3173 'Do not leave a blank line after "protected:"'
3174 ' [whitespace/blank_line] [3]'))
3175 self.assertEquals(1, error_collector.Results().count(
3176 'Do not leave a blank line after "private:"'
3177 ' [whitespace/blank_line] [3]'))
3178
avakulenko@google.com02af6282014-06-04 18:53:25 +00003179 def testAllowBlankLinesInRawStrings(self):
3180 error_collector = ErrorCollector(self.assert_)
3181 cpplint.ProcessFileData('foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003182 ['// Copyright 2014 Your Company.',
avakulenko@google.com02af6282014-06-04 18:53:25 +00003183 'static const char *kData[] = {R"(',
3184 '',
3185 ')", R"(',
3186 '',
3187 ')"};',
3188 ''],
3189 error_collector)
3190 self.assertEquals('', error_collector.Results())
3191
erg@google.com4e00b9a2009-01-12 23:05:11 +00003192 def testElseOnSameLineAsClosingBraces(self):
3193 error_collector = ErrorCollector(self.assert_)
3194 cpplint.ProcessFileData('foo.cc', 'cc',
3195 ['if (hoge) {',
avakulenko@google.com02af6282014-06-04 18:53:25 +00003196 '}',
3197 'else if (piyo) {', # Warning on this line
erg@google.com4e00b9a2009-01-12 23:05:11 +00003198 '}',
3199 ' else {' # Warning on this line
3200 '',
3201 '}'],
3202 error_collector)
avakulenko@google.com02af6282014-06-04 18:53:25 +00003203 self.assertEquals(2, error_collector.Results().count(
3204 'An else should appear on the same line as the preceding }'
3205 ' [whitespace/newline] [4]'))
3206
3207 error_collector = ErrorCollector(self.assert_)
3208 cpplint.ProcessFileData('foo.cc', 'cc',
3209 ['if (hoge) {',
3210 '',
3211 '}',
3212 'else', # Warning on this line
3213 '{',
3214 '',
3215 '}'],
3216 error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +00003217 self.assertEquals(1, error_collector.Results().count(
3218 'An else should appear on the same line as the preceding }'
3219 ' [whitespace/newline] [4]'))
3220
avakulenko@google.com02af6282014-06-04 18:53:25 +00003221 error_collector = ErrorCollector(self.assert_)
3222 cpplint.ProcessFileData('foo.cc', 'cc',
3223 ['if (hoge) {',
3224 '',
3225 '}',
3226 'else_function();'],
3227 error_collector)
3228 self.assertEquals(0, error_collector.Results().count(
3229 'An else should appear on the same line as the preceding }'
3230 ' [whitespace/newline] [4]'))
3231
erg@google.comd350fe52013-01-14 17:51:48 +00003232 def testMultipleStatementsOnSameLine(self):
3233 error_collector = ErrorCollector(self.assert_)
3234 cpplint.ProcessFileData('foo.cc', 'cc',
3235 ['for (int i = 0; i < 1; i++) {}',
3236 'switch (x) {',
3237 ' case 0: func(); break; ',
3238 '}',
3239 'sum += MathUtil::SafeIntRound(x); x += 0.1;'],
3240 error_collector)
3241 self.assertEquals(0, error_collector.Results().count(
3242 'More than one command on the same line [whitespace/newline] [0]'))
3243
3244 old_verbose_level = cpplint._cpplint_state.verbose_level
3245 cpplint._cpplint_state.verbose_level = 0
3246 cpplint.ProcessFileData('foo.cc', 'cc',
3247 ['sum += MathUtil::SafeIntRound(x); x += 0.1;'],
3248 error_collector)
3249 cpplint._cpplint_state.verbose_level = old_verbose_level
3250
3251 def testEndOfNamespaceComments(self):
3252 error_collector = ErrorCollector(self.assert_)
3253 cpplint.ProcessFileData('foo.cc', 'cc',
3254 ['namespace {',
3255 '',
3256 '}', # No warning (too short)
3257 'namespace expected {',
3258 '} // namespace mismatched', # Warning here
3259 'namespace {',
3260 '} // namespace mismatched', # Warning here
3261 'namespace outer { namespace nested {'] +
3262 ([''] * 10) +
3263 ['}', # Warning here
3264 '}', # Warning here
3265 'namespace {'] +
3266 ([''] * 10) +
3267 ['}', # Warning here
3268 'namespace {'] +
3269 ([''] * 10) +
avakulenko@google.com02af6282014-06-04 18:53:25 +00003270 ['} // namespace some description', # Anon warning
3271 'namespace {'] +
3272 ([''] * 10) +
3273 ['} // namespace anonymous', # Variant warning
3274 'namespace {'] +
3275 ([''] * 10) +
3276 ['} // anonymous namespace (utils)', # Variant
3277 'namespace {'] +
3278 ([''] * 10) +
3279 ['} // anonymous namespace', # No warning
erg@google.comd350fe52013-01-14 17:51:48 +00003280 'namespace missing_comment {'] +
3281 ([''] * 10) +
3282 ['}', # Warning here
3283 'namespace no_warning {'] +
3284 ([''] * 10) +
3285 ['} // namespace no_warning',
3286 'namespace no_warning {'] +
3287 ([''] * 10) +
3288 ['}; // end namespace no_warning',
3289 '#define MACRO \\',
3290 'namespace c_style { \\'] +
3291 (['\\'] * 10) +
3292 ['} /* namespace c_style. */ \\',
3293 ';'],
3294 error_collector)
3295 self.assertEquals(1, error_collector.Results().count(
3296 'Namespace should be terminated with "// namespace expected"'
3297 ' [readability/namespace] [5]'))
3298 self.assertEquals(1, error_collector.Results().count(
3299 'Namespace should be terminated with "// namespace outer"'
3300 ' [readability/namespace] [5]'))
3301 self.assertEquals(1, error_collector.Results().count(
3302 'Namespace should be terminated with "// namespace nested"'
3303 ' [readability/namespace] [5]'))
3304 self.assertEquals(3, error_collector.Results().count(
avakulenko@google.com02af6282014-06-04 18:53:25 +00003305 'Anonymous namespace should be terminated with "// namespace"'
3306 ' [readability/namespace] [5]'))
3307 self.assertEquals(2, error_collector.Results().count(
3308 'Anonymous namespace should be terminated with "// namespace" or'
3309 ' "// anonymous namespace"'
erg@google.comd350fe52013-01-14 17:51:48 +00003310 ' [readability/namespace] [5]'))
3311 self.assertEquals(1, error_collector.Results().count(
3312 'Namespace should be terminated with "// namespace missing_comment"'
3313 ' [readability/namespace] [5]'))
3314 self.assertEquals(0, error_collector.Results().count(
3315 'Namespace should be terminated with "// namespace no_warning"'
3316 ' [readability/namespace] [5]'))
3317
erg@google.com4e00b9a2009-01-12 23:05:11 +00003318 def testElseClauseNotOnSameLineAsElse(self):
3319 self.TestLint(' else DoSomethingElse();',
3320 'Else clause should never be on same line as else '
3321 '(use 2 lines) [whitespace/newline] [4]')
3322 self.TestLint(' else ifDoSomethingElse();',
3323 'Else clause should never be on same line as else '
3324 '(use 2 lines) [whitespace/newline] [4]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003325 self.TestLint(' } else if (blah) {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003326 self.TestLint(' variable_ends_in_else = true;', '')
3327
3328 def testComma(self):
3329 self.TestLint('a = f(1,2);',
3330 'Missing space after , [whitespace/comma] [3]')
3331 self.TestLint('int tmp=a,a=b,b=tmp;',
3332 ['Missing spaces around = [whitespace/operators] [4]',
3333 'Missing space after , [whitespace/comma] [3]'])
3334 self.TestLint('f(a, /* name */ b);', '')
3335 self.TestLint('f(a, /* name */b);', '')
erg@google.com2aa59982013-10-28 19:09:25 +00003336 self.TestLint('f(a, /* name */-1);', '')
3337 self.TestLint('f(a, /* name */"1");', '')
erg@google.comc6671232013-10-25 21:44:03 +00003338 self.TestLint('f(1, /* empty macro arg */, 2)', '')
3339 self.TestLint('f(1,, 2)', '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003340 self.TestLint('operator,()', '')
3341 self.TestLint('operator,(a,b)',
3342 'Missing space after , [whitespace/comma] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003343
avakulenko@google.com554223d2014-12-04 22:00:20 +00003344 def testEqualsOperatorSpacing(self):
3345 self.TestLint('int tmp= a;',
3346 'Missing spaces around = [whitespace/operators] [4]')
3347 self.TestLint('int tmp =a;',
3348 'Missing spaces around = [whitespace/operators] [4]')
3349 self.TestLint('int tmp=a;',
3350 'Missing spaces around = [whitespace/operators] [4]')
3351 self.TestLint('int tmp= 7;',
3352 'Missing spaces around = [whitespace/operators] [4]')
3353 self.TestLint('int tmp =7;',
3354 'Missing spaces around = [whitespace/operators] [4]')
3355 self.TestLint('int tmp=7;',
3356 'Missing spaces around = [whitespace/operators] [4]')
3357 self.TestLint('int* tmp=*p;',
3358 'Missing spaces around = [whitespace/operators] [4]')
3359 self.TestLint('int* tmp= *p;',
3360 'Missing spaces around = [whitespace/operators] [4]')
3361 self.TestMultiLineLint(
3362 TrimExtraIndent('''
3363 lookahead_services_=
3364 ::strings::Split(FLAGS_ls, ",", ::strings::SkipEmpty());'''),
3365 'Missing spaces around = [whitespace/operators] [4]')
3366 self.TestLint('bool result = a>=42;',
3367 'Missing spaces around >= [whitespace/operators] [3]')
3368 self.TestLint('bool result = a<=42;',
3369 'Missing spaces around <= [whitespace/operators] [3]')
3370 self.TestLint('bool result = a==42;',
3371 'Missing spaces around == [whitespace/operators] [3]')
3372 self.TestLint('auto result = a!=42;',
3373 'Missing spaces around != [whitespace/operators] [3]')
3374 self.TestLint('int a = b!=c;',
3375 'Missing spaces around != [whitespace/operators] [3]')
3376 self.TestLint('a&=42;', '')
3377 self.TestLint('a|=42;', '')
3378 self.TestLint('a^=42;', '')
3379 self.TestLint('a+=42;', '')
3380 self.TestLint('a*=42;', '')
3381 self.TestLint('a/=42;', '')
3382 self.TestLint('a%=42;', '')
3383 self.TestLint('a>>=5;', '')
3384 self.TestLint('a<<=5;', '')
3385
3386 def testShiftOperatorSpacing(self):
3387 self.TestLint('a<<b',
3388 'Missing spaces around << [whitespace/operators] [3]')
3389 self.TestLint('a>>b',
3390 'Missing spaces around >> [whitespace/operators] [3]')
3391 self.TestLint('1<<20', '')
3392 self.TestLint('1024>>10', '')
3393 self.TestLint('Kernel<<<1, 2>>>()', '')
3394
erg@google.com4e00b9a2009-01-12 23:05:11 +00003395 def testIndent(self):
3396 self.TestLint('static int noindent;', '')
3397 self.TestLint(' int two_space_indent;', '')
3398 self.TestLint(' int four_space_indent;', '')
3399 self.TestLint(' int one_space_indent;',
3400 'Weird number of spaces at line-start. '
3401 'Are you using a 2-space indent? [whitespace/indent] [3]')
3402 self.TestLint(' int three_space_indent;',
3403 'Weird number of spaces at line-start. '
3404 'Are you using a 2-space indent? [whitespace/indent] [3]')
3405 self.TestLint(' char* one_space_indent = "public:";',
3406 'Weird number of spaces at line-start. '
3407 'Are you using a 2-space indent? [whitespace/indent] [3]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003408 self.TestLint(' public:', '')
3409 self.TestLint(' protected:', '')
3410 self.TestLint(' private:', '')
3411 self.TestLint(' protected: \\', '')
3412 self.TestLint(' public: \\', '')
3413 self.TestLint(' private: \\', '')
3414 self.TestMultiLineLint(
3415 TrimExtraIndent("""
3416 class foo {
3417 public slots:
3418 void bar();
3419 };"""),
3420 'Weird number of spaces at line-start. '
3421 'Are you using a 2-space indent? [whitespace/indent] [3]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003422 self.TestMultiLineLint(
3423 TrimExtraIndent('''
3424 static const char kRawString[] = R"("
3425 ")";'''),
3426 '')
3427 self.TestMultiLineLint(
3428 TrimExtraIndent('''
Alex Vakulenko01e47232016-05-06 13:54:15 -07003429 KV<Query,
3430 Tuple<TaxonomyId, PetacatCategoryId, double>>'''),
3431 '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003432 self.TestMultiLineLint(
3433 ' static const char kSingleLineRawString[] = R"(...)";',
3434 'Weird number of spaces at line-start. '
3435 'Are you using a 2-space indent? [whitespace/indent] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003436
erg@google.comfd5da632013-10-25 17:39:45 +00003437 def testSectionIndent(self):
3438 self.TestMultiLineLint(
3439 """
3440 class A {
3441 public: // no warning
3442 private: // warning here
3443 };""",
3444 'private: should be indented +1 space inside class A'
3445 ' [whitespace/indent] [3]')
3446 self.TestMultiLineLint(
3447 """
3448 class B {
3449 public: // no warning
3450 template<> struct C {
3451 public: // warning here
3452 protected: // no warning
3453 };
3454 };""",
3455 'public: should be indented +1 space inside struct C'
3456 ' [whitespace/indent] [3]')
3457 self.TestMultiLineLint(
3458 """
3459 struct D {
3460 };""",
3461 'Closing brace should be aligned with beginning of struct D'
3462 ' [whitespace/indent] [3]')
3463 self.TestMultiLineLint(
3464 """
3465 template<typename E> class F {
3466 };""",
3467 'Closing brace should be aligned with beginning of class F'
3468 ' [whitespace/indent] [3]')
3469 self.TestMultiLineLint(
3470 """
3471 class G {
3472 Q_OBJECT
3473 public slots:
3474 signals:
3475 };""",
3476 ['public slots: should be indented +1 space inside class G'
3477 ' [whitespace/indent] [3]',
3478 'signals: should be indented +1 space inside class G'
3479 ' [whitespace/indent] [3]'])
3480 self.TestMultiLineLint(
3481 """
3482 class H {
3483 /* comments */ class I {
3484 public: // no warning
3485 private: // warning here
3486 };
3487 };""",
3488 'private: should be indented +1 space inside class I'
3489 ' [whitespace/indent] [3]')
3490 self.TestMultiLineLint(
3491 """
3492 class J
3493 : public ::K {
3494 public: // no warning
3495 protected: // warning here
3496 };""",
3497 'protected: should be indented +1 space inside class J'
3498 ' [whitespace/indent] [3]')
3499 self.TestMultiLineLint(
3500 """
3501 class L
3502 : public M,
3503 public ::N {
3504 };""",
3505 '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003506 self.TestMultiLineLint(
3507 """
3508 template <class O,
3509 class P,
3510 class Q,
3511 typename R>
3512 static void Func() {
3513 }""",
3514 '')
3515
3516 def testConditionals(self):
3517 self.TestMultiLineLint(
3518 """
3519 if (foo)
3520 goto fail;
3521 goto fail;""",
3522 'If/else bodies with multiple statements require braces'
3523 ' [readability/braces] [4]')
3524 self.TestMultiLineLint(
3525 """
3526 if (foo)
3527 goto fail; goto fail;""",
3528 'If/else bodies with multiple statements require braces'
3529 ' [readability/braces] [4]')
3530 self.TestMultiLineLint(
3531 """
3532 if (foo)
3533 foo;
3534 else
3535 goto fail;
3536 goto fail;""",
3537 'If/else bodies with multiple statements require braces'
3538 ' [readability/braces] [4]')
3539 self.TestMultiLineLint(
3540 """
3541 if (foo) goto fail;
3542 goto fail;""",
3543 'If/else bodies with multiple statements require braces'
3544 ' [readability/braces] [4]')
3545 self.TestMultiLineLint(
3546 """
3547 if (foo)
3548 if (bar)
3549 baz;
3550 else
3551 qux;""",
3552 'Else clause should be indented at the same level as if. Ambiguous'
3553 ' nested if/else chains require braces. [readability/braces] [4]')
3554 self.TestMultiLineLint(
3555 """
3556 if (foo)
3557 if (bar)
3558 baz;
3559 else
3560 qux;""",
3561 'Else clause should be indented at the same level as if. Ambiguous'
3562 ' nested if/else chains require braces. [readability/braces] [4]')
3563 self.TestMultiLineLint(
3564 """
3565 if (foo) {
3566 bar;
3567 baz;
3568 } else
3569 qux;""",
3570 'If an else has a brace on one side, it should have it on both'
3571 ' [readability/braces] [5]')
3572 self.TestMultiLineLint(
3573 """
3574 if (foo)
3575 bar;
3576 else {
3577 baz;
3578 }""",
3579 'If an else has a brace on one side, it should have it on both'
3580 ' [readability/braces] [5]')
3581 self.TestMultiLineLint(
3582 """
3583 if (foo)
3584 bar;
3585 else if (baz) {
3586 qux;
3587 }""",
3588 'If an else has a brace on one side, it should have it on both'
3589 ' [readability/braces] [5]')
3590 self.TestMultiLineLint(
3591 """
3592 if (foo) {
3593 bar;
3594 } else if (baz)
3595 qux;""",
3596 'If an else has a brace on one side, it should have it on both'
3597 ' [readability/braces] [5]')
3598 self.TestMultiLineLint(
3599 """
3600 if (foo)
3601 goto fail;
3602 bar;""",
3603 '')
3604 self.TestMultiLineLint(
3605 """
3606 if (foo
3607 && bar) {
3608 baz;
3609 qux;
3610 }""",
3611 '')
3612 self.TestMultiLineLint(
3613 """
3614 if (foo)
3615 goto
3616 fail;""",
3617 '')
3618 self.TestMultiLineLint(
3619 """
3620 if (foo)
3621 bar;
3622 else
3623 baz;
3624 qux;""",
3625 '')
3626 self.TestMultiLineLint(
3627 """
3628 for (;;) {
3629 if (foo)
3630 bar;
3631 else
3632 baz;
3633 }""",
3634 '')
3635 self.TestMultiLineLint(
3636 """
3637 if (foo)
3638 bar;
3639 else if (baz)
3640 baz;""",
3641 '')
3642 self.TestMultiLineLint(
3643 """
3644 if (foo)
3645 bar;
3646 else
3647 baz;""",
3648 '')
3649 self.TestMultiLineLint(
3650 """
3651 if (foo) {
3652 bar;
3653 } else {
3654 baz;
3655 }""",
3656 '')
3657 self.TestMultiLineLint(
3658 """
3659 if (foo) {
3660 bar;
3661 } else if (baz) {
3662 qux;
3663 }""",
3664 '')
3665 # Note: this is an error for a different reason, but should not trigger the
3666 # single-line if error.
3667 self.TestMultiLineLint(
3668 """
3669 if (foo)
3670 {
3671 bar;
3672 baz;
3673 }""",
3674 '{ should almost always be at the end of the previous line'
3675 ' [whitespace/braces] [4]')
3676 self.TestMultiLineLint(
3677 """
3678 if (foo) { \\
3679 bar; \\
3680 baz; \\
3681 }""",
3682 '')
3683 self.TestMultiLineLint(
3684 """
3685 void foo() { if (bar) baz; }""",
3686 '')
3687 self.TestMultiLineLint(
3688 """
3689 #if foo
3690 bar;
3691 #else
3692 baz;
3693 qux;
3694 #endif""",
3695 '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00003696 self.TestMultiLineLint(
3697 """void F() {
3698 variable = [] { if (true); };
3699 variable =
3700 [] { if (true); };
3701 Call(
3702 [] { if (true); },
3703 [] { if (true); });
3704 }""",
3705 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003706
3707 def testTab(self):
3708 self.TestLint('\tint a;',
3709 'Tab found; better to use spaces [whitespace/tab] [1]')
3710 self.TestLint('int a = 5;\t\t// set a to 5',
3711 'Tab found; better to use spaces [whitespace/tab] [1]')
3712
3713 def testParseArguments(self):
3714 old_usage = cpplint._USAGE
3715 old_error_categories = cpplint._ERROR_CATEGORIES
3716 old_output_format = cpplint._cpplint_state.output_format
3717 old_verbose_level = cpplint._cpplint_state.verbose_level
3718 old_filters = cpplint._cpplint_state.filters
erg@google.comab53edf2013-11-05 22:23:37 +00003719 old_line_length = cpplint._line_length
erg@google.com19680272013-12-16 22:48:54 +00003720 old_valid_extensions = cpplint._valid_extensions
erg@google.com4e00b9a2009-01-12 23:05:11 +00003721 try:
3722 # Don't print usage during the tests, or filter categories
3723 cpplint._USAGE = ''
3724 cpplint._ERROR_CATEGORIES = ''
3725
3726 self.assertRaises(SystemExit, cpplint.ParseArguments, [])
3727 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--badopt'])
3728 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--help'])
3729 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--v=0'])
3730 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter='])
3731 # This is illegal because all filters must start with + or -
3732 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter=foo'])
3733 self.assertRaises(SystemExit, cpplint.ParseArguments,
3734 ['--filter=+a,b,-c'])
3735
3736 self.assertEquals(['foo.cc'], cpplint.ParseArguments(['foo.cc']))
3737 self.assertEquals(old_output_format, cpplint._cpplint_state.output_format)
3738 self.assertEquals(old_verbose_level, cpplint._cpplint_state.verbose_level)
3739
3740 self.assertEquals(['foo.cc'],
3741 cpplint.ParseArguments(['--v=1', 'foo.cc']))
3742 self.assertEquals(1, cpplint._cpplint_state.verbose_level)
3743 self.assertEquals(['foo.h'],
3744 cpplint.ParseArguments(['--v=3', 'foo.h']))
3745 self.assertEquals(3, cpplint._cpplint_state.verbose_level)
3746 self.assertEquals(['foo.cpp'],
3747 cpplint.ParseArguments(['--verbose=5', 'foo.cpp']))
3748 self.assertEquals(5, cpplint._cpplint_state.verbose_level)
3749 self.assertRaises(ValueError,
3750 cpplint.ParseArguments, ['--v=f', 'foo.cc'])
3751
3752 self.assertEquals(['foo.cc'],
3753 cpplint.ParseArguments(['--output=emacs', 'foo.cc']))
3754 self.assertEquals('emacs', cpplint._cpplint_state.output_format)
3755 self.assertEquals(['foo.h'],
3756 cpplint.ParseArguments(['--output=vs7', 'foo.h']))
3757 self.assertEquals('vs7', cpplint._cpplint_state.output_format)
3758 self.assertRaises(SystemExit,
3759 cpplint.ParseArguments, ['--output=blah', 'foo.cc'])
3760
3761 filt = '-,+whitespace,-whitespace/indent'
3762 self.assertEquals(['foo.h'],
3763 cpplint.ParseArguments(['--filter='+filt, 'foo.h']))
3764 self.assertEquals(['-', '+whitespace', '-whitespace/indent'],
3765 cpplint._cpplint_state.filters)
3766
3767 self.assertEquals(['foo.cc', 'foo.h'],
3768 cpplint.ParseArguments(['foo.cc', 'foo.h']))
erg@google.comab53edf2013-11-05 22:23:37 +00003769
3770 self.assertEqual(['foo.h'],
3771 cpplint.ParseArguments(['--linelength=120', 'foo.h']))
3772 self.assertEqual(120, cpplint._line_length)
erg@google.com19680272013-12-16 22:48:54 +00003773
3774 self.assertEqual(['foo.h'],
3775 cpplint.ParseArguments(['--extensions=hpp,cpp,cpp', 'foo.h']))
3776 self.assertEqual(set(['hpp', 'cpp']), cpplint._valid_extensions)
erg@google.com4e00b9a2009-01-12 23:05:11 +00003777 finally:
3778 cpplint._USAGE = old_usage
3779 cpplint._ERROR_CATEGORIES = old_error_categories
3780 cpplint._cpplint_state.output_format = old_output_format
3781 cpplint._cpplint_state.verbose_level = old_verbose_level
3782 cpplint._cpplint_state.filters = old_filters
erg@google.comab53edf2013-11-05 22:23:37 +00003783 cpplint._line_length = old_line_length
erg@google.com19680272013-12-16 22:48:54 +00003784 cpplint._valid_extensions = old_valid_extensions
erg@google.comab53edf2013-11-05 22:23:37 +00003785
3786 def testLineLength(self):
3787 old_line_length = cpplint._line_length
3788 try:
3789 cpplint._line_length = 80
3790 self.TestLint(
Alex Vakulenko01e47232016-05-06 13:54:15 -07003791 '// H %s' % ('H' * 75),
erg@google.comab53edf2013-11-05 22:23:37 +00003792 '')
3793 self.TestLint(
Alex Vakulenko01e47232016-05-06 13:54:15 -07003794 '// H %s' % ('H' * 76),
erg@google.comab53edf2013-11-05 22:23:37 +00003795 'Lines should be <= 80 characters long'
3796 ' [whitespace/line_length] [2]')
3797 cpplint._line_length = 120
3798 self.TestLint(
Alex Vakulenko01e47232016-05-06 13:54:15 -07003799 '// H %s' % ('H' * 115),
erg@google.comab53edf2013-11-05 22:23:37 +00003800 '')
3801 self.TestLint(
Alex Vakulenko01e47232016-05-06 13:54:15 -07003802 '// H %s' % ('H' * 116),
erg@google.comab53edf2013-11-05 22:23:37 +00003803 'Lines should be <= 120 characters long'
3804 ' [whitespace/line_length] [2]')
3805 finally:
3806 cpplint._line_length = old_line_length
erg@google.com4e00b9a2009-01-12 23:05:11 +00003807
3808 def testFilter(self):
3809 old_filters = cpplint._cpplint_state.filters
3810 try:
3811 cpplint._cpplint_state.SetFilters('-,+whitespace,-whitespace/indent')
3812 self.TestLint(
3813 '// Hello there ',
3814 'Line ends in whitespace. Consider deleting these extra spaces.'
3815 ' [whitespace/end_of_line] [4]')
3816 self.TestLint('int a = (int)1.0;', '')
3817 self.TestLint(' weird opening space', '')
3818 finally:
3819 cpplint._cpplint_state.filters = old_filters
3820
erg@google.come35f7652009-06-19 20:52:09 +00003821 def testDefaultFilter(self):
3822 default_filters = cpplint._DEFAULT_FILTERS
3823 old_filters = cpplint._cpplint_state.filters
erg@google.com8a95ecc2011-09-08 00:45:54 +00003824 cpplint._DEFAULT_FILTERS = ['-whitespace']
erg@google.come35f7652009-06-19 20:52:09 +00003825 try:
3826 # Reset filters
3827 cpplint._cpplint_state.SetFilters('')
3828 self.TestLint('// Hello there ', '')
3829 cpplint._cpplint_state.SetFilters('+whitespace/end_of_line')
3830 self.TestLint(
3831 '// Hello there ',
3832 'Line ends in whitespace. Consider deleting these extra spaces.'
3833 ' [whitespace/end_of_line] [4]')
3834 self.TestLint(' weird opening space', '')
3835 finally:
3836 cpplint._cpplint_state.filters = old_filters
3837 cpplint._DEFAULT_FILTERS = default_filters
3838
avakulenko@google.com554223d2014-12-04 22:00:20 +00003839 def testDuplicateHeader(self):
3840 error_collector = ErrorCollector(self.assert_)
3841 cpplint.ProcessFileData('path/self.cc', 'cc',
3842 ['// Copyright 2014 Your Company. All Rights Reserved.',
3843 '#include "path/self.h"',
3844 '#include "path/duplicate.h"',
3845 '#include "path/duplicate.h"',
3846 '#ifdef MACRO',
3847 '#include "path/unique.h"',
3848 '#else',
3849 '#include "path/unique.h"',
3850 '#endif',
3851 ''],
3852 error_collector)
3853 self.assertEquals(
3854 ['"path/duplicate.h" already included at path/self.cc:3 '
3855 '[build/include] [4]'],
3856 error_collector.ResultList())
3857
erg@google.com4e00b9a2009-01-12 23:05:11 +00003858 def testUnnamedNamespacesInHeaders(self):
3859 self.TestLanguageRulesCheck(
3860 'foo.h', 'namespace {',
3861 'Do not use unnamed namespaces in header files. See'
Ackermann Yuriy79692902016-04-01 21:41:34 +13003862 ' https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
erg@google.com4e00b9a2009-01-12 23:05:11 +00003863 ' for more information. [build/namespaces] [4]')
3864 # namespace registration macros are OK.
3865 self.TestLanguageRulesCheck('foo.h', 'namespace { \\', '')
3866 # named namespaces are OK.
3867 self.TestLanguageRulesCheck('foo.h', 'namespace foo {', '')
3868 self.TestLanguageRulesCheck('foo.h', 'namespace foonamespace {', '')
3869 self.TestLanguageRulesCheck('foo.cc', 'namespace {', '')
3870 self.TestLanguageRulesCheck('foo.cc', 'namespace foo {', '')
3871
3872 def testBuildClass(self):
3873 # Test that the linter can parse to the end of class definitions,
3874 # and that it will report when it can't.
3875 # Use multi-line linter because it performs the ClassState check.
3876 self.TestMultiLineLint(
3877 'class Foo {',
3878 'Failed to find complete declaration of class Foo'
3879 ' [build/class] [5]')
erg@google.com2aa59982013-10-28 19:09:25 +00003880 # Do the same for namespaces
3881 self.TestMultiLineLint(
3882 'namespace Foo {',
3883 'Failed to find complete declaration of namespace Foo'
3884 ' [build/namespaces] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003885 # Don't warn on forward declarations of various types.
3886 self.TestMultiLineLint(
3887 'class Foo;',
3888 '')
3889 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00003890 """struct Foo*
3891 foo = NewFoo();""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00003892 '')
erg@google.comd350fe52013-01-14 17:51:48 +00003893 # Test preprocessor.
3894 self.TestMultiLineLint(
3895 """#ifdef DERIVE_FROM_GOO
3896 struct Foo : public Goo {
3897 #else
3898 struct Foo : public Hoo {
3899 #endif
3900 };""",
3901 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003902 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00003903 """
3904 class Foo
erg@google.com4e00b9a2009-01-12 23:05:11 +00003905 #ifdef DERIVE_FROM_GOO
3906 : public Goo {
3907 #else
3908 : public Hoo {
3909 #endif
erg@google.comfd5da632013-10-25 17:39:45 +00003910 };""",
erg@google.comd350fe52013-01-14 17:51:48 +00003911 '')
3912 # Test incomplete class
3913 self.TestMultiLineLint(
3914 'class Foo {',
erg@google.com4e00b9a2009-01-12 23:05:11 +00003915 'Failed to find complete declaration of class Foo'
3916 ' [build/class] [5]')
3917
3918 def testBuildEndComment(self):
3919 # The crosstool compiler we currently use will fail to compile the
3920 # code in this test, so we might consider removing the lint check.
erg@google.comd350fe52013-01-14 17:51:48 +00003921 self.TestMultiLineLint(
3922 """#if 0
3923 #endif Not a comment""",
3924 'Uncommented text after #endif is non-standard. Use a comment.'
3925 ' [build/endif_comment] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003926
3927 def testBuildForwardDecl(self):
3928 # The crosstool compiler we currently use will fail to compile the
3929 # code in this test, so we might consider removing the lint check.
3930 self.TestLint('class Foo::Goo;',
3931 'Inner-style forward declarations are invalid.'
3932 ' Remove this line.'
3933 ' [build/forward_decl] [5]')
3934
avakulenko@google.com554223d2014-12-04 22:00:20 +00003935 def GetBuildHeaderGuardPreprocessorSymbol(self, file_path):
3936 # Figure out the expected header guard by processing an empty file.
erg@google.com4e00b9a2009-01-12 23:05:11 +00003937 error_collector = ErrorCollector(self.assert_)
3938 cpplint.ProcessFileData(file_path, 'h', [], error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +00003939 for error in error_collector.ResultList():
avakulenko@google.com554223d2014-12-04 22:00:20 +00003940 matched = re.search(
Alex Vakulenko01e47232016-05-06 13:54:15 -07003941 'No #ifndef header guard found, suggested CPP variable is: '
3942 '([A-Z0-9_]+)',
avakulenko@google.com554223d2014-12-04 22:00:20 +00003943 error)
3944 if matched is not None:
3945 return matched.group(1)
erg@google.com4e00b9a2009-01-12 23:05:11 +00003946
avakulenko@google.com554223d2014-12-04 22:00:20 +00003947 def testBuildHeaderGuard(self):
3948 file_path = 'mydir/foo.h'
3949 expected_guard = self.GetBuildHeaderGuardPreprocessorSymbol(file_path)
3950 self.assertTrue(re.search('MYDIR_FOO_H_$', expected_guard))
3951
3952 # No guard at all: expect one error.
3953 error_collector = ErrorCollector(self.assert_)
3954 cpplint.ProcessFileData(file_path, 'h', [], error_collector)
3955 self.assertEquals(
3956 1,
3957 error_collector.ResultList().count(
3958 'No #ifndef header guard found, suggested CPP variable is: %s'
3959 ' [build/header_guard] [5]' % expected_guard),
3960 error_collector.ResultList())
erg@google.com4e00b9a2009-01-12 23:05:11 +00003961
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003962 # No header guard, but the error is suppressed.
3963 error_collector = ErrorCollector(self.assert_)
3964 cpplint.ProcessFileData(file_path, 'h',
3965 ['// Copyright 2014 Your Company.',
3966 '// NOLINT(build/header_guard)', ''],
3967 error_collector)
3968 self.assertEquals([], error_collector.ResultList())
3969
erg@google.com4e00b9a2009-01-12 23:05:11 +00003970 # Wrong guard
3971 error_collector = ErrorCollector(self.assert_)
3972 cpplint.ProcessFileData(file_path, 'h',
3973 ['#ifndef FOO_H', '#define FOO_H'], error_collector)
3974 self.assertEquals(
3975 1,
3976 error_collector.ResultList().count(
3977 '#ifndef header guard has wrong style, please use: %s'
3978 ' [build/header_guard] [5]' % expected_guard),
3979 error_collector.ResultList())
3980
3981 # No define
3982 error_collector = ErrorCollector(self.assert_)
3983 cpplint.ProcessFileData(file_path, 'h',
3984 ['#ifndef %s' % expected_guard], error_collector)
3985 self.assertEquals(
3986 1,
3987 error_collector.ResultList().count(
avakulenko@google.com554223d2014-12-04 22:00:20 +00003988 'No #ifndef header guard found, suggested CPP variable is: %s'
erg@google.com4e00b9a2009-01-12 23:05:11 +00003989 ' [build/header_guard] [5]' % expected_guard),
3990 error_collector.ResultList())
3991
3992 # Mismatched define
3993 error_collector = ErrorCollector(self.assert_)
3994 cpplint.ProcessFileData(file_path, 'h',
3995 ['#ifndef %s' % expected_guard,
3996 '#define FOO_H'],
3997 error_collector)
3998 self.assertEquals(
3999 1,
4000 error_collector.ResultList().count(
avakulenko@google.com554223d2014-12-04 22:00:20 +00004001 'No #ifndef header guard found, suggested CPP variable is: %s'
erg@google.com4e00b9a2009-01-12 23:05:11 +00004002 ' [build/header_guard] [5]' % expected_guard),
4003 error_collector.ResultList())
4004
4005 # No endif
4006 error_collector = ErrorCollector(self.assert_)
4007 cpplint.ProcessFileData(file_path, 'h',
4008 ['#ifndef %s' % expected_guard,
avakulenko@google.com554223d2014-12-04 22:00:20 +00004009 '#define %s' % expected_guard,
4010 ''],
erg@google.com4e00b9a2009-01-12 23:05:11 +00004011 error_collector)
4012 self.assertEquals(
4013 1,
4014 error_collector.ResultList().count(
4015 '#endif line should be "#endif // %s"'
4016 ' [build/header_guard] [5]' % expected_guard),
4017 error_collector.ResultList())
4018
4019 # Commentless endif
4020 error_collector = ErrorCollector(self.assert_)
4021 cpplint.ProcessFileData(file_path, 'h',
4022 ['#ifndef %s' % expected_guard,
4023 '#define %s' % expected_guard,
4024 '#endif'],
4025 error_collector)
4026 self.assertEquals(
4027 1,
4028 error_collector.ResultList().count(
4029 '#endif line should be "#endif // %s"'
4030 ' [build/header_guard] [5]' % expected_guard),
4031 error_collector.ResultList())
4032
4033 # Commentless endif for old-style guard
4034 error_collector = ErrorCollector(self.assert_)
4035 cpplint.ProcessFileData(file_path, 'h',
4036 ['#ifndef %s_' % expected_guard,
4037 '#define %s_' % expected_guard,
4038 '#endif'],
4039 error_collector)
4040 self.assertEquals(
4041 1,
4042 error_collector.ResultList().count(
4043 '#endif line should be "#endif // %s"'
4044 ' [build/header_guard] [5]' % expected_guard),
4045 error_collector.ResultList())
4046
4047 # No header guard errors
4048 error_collector = ErrorCollector(self.assert_)
4049 cpplint.ProcessFileData(file_path, 'h',
4050 ['#ifndef %s' % expected_guard,
4051 '#define %s' % expected_guard,
4052 '#endif // %s' % expected_guard],
4053 error_collector)
4054 for line in error_collector.ResultList():
4055 if line.find('build/header_guard') != -1:
4056 self.fail('Unexpected error: %s' % line)
4057
4058 # No header guard errors for old-style guard
4059 error_collector = ErrorCollector(self.assert_)
4060 cpplint.ProcessFileData(file_path, 'h',
4061 ['#ifndef %s_' % expected_guard,
4062 '#define %s_' % expected_guard,
4063 '#endif // %s_' % expected_guard],
4064 error_collector)
4065 for line in error_collector.ResultList():
4066 if line.find('build/header_guard') != -1:
4067 self.fail('Unexpected error: %s' % line)
4068
4069 old_verbose_level = cpplint._cpplint_state.verbose_level
4070 try:
4071 cpplint._cpplint_state.verbose_level = 0
4072 # Warn on old-style guard if verbosity is 0.
4073 error_collector = ErrorCollector(self.assert_)
4074 cpplint.ProcessFileData(file_path, 'h',
4075 ['#ifndef %s_' % expected_guard,
4076 '#define %s_' % expected_guard,
4077 '#endif // %s_' % expected_guard],
4078 error_collector)
4079 self.assertEquals(
4080 1,
4081 error_collector.ResultList().count(
4082 '#ifndef header guard has wrong style, please use: %s'
4083 ' [build/header_guard] [0]' % expected_guard),
4084 error_collector.ResultList())
4085 finally:
4086 cpplint._cpplint_state.verbose_level = old_verbose_level
4087
4088 # Completely incorrect header guard
4089 error_collector = ErrorCollector(self.assert_)
4090 cpplint.ProcessFileData(file_path, 'h',
4091 ['#ifndef FOO',
4092 '#define FOO',
4093 '#endif // FOO'],
4094 error_collector)
4095 self.assertEquals(
4096 1,
4097 error_collector.ResultList().count(
4098 '#ifndef header guard has wrong style, please use: %s'
4099 ' [build/header_guard] [5]' % expected_guard),
4100 error_collector.ResultList())
4101 self.assertEquals(
4102 1,
4103 error_collector.ResultList().count(
4104 '#endif line should be "#endif // %s"'
4105 ' [build/header_guard] [5]' % expected_guard),
4106 error_collector.ResultList())
4107
erg@google.coma868d2d2009-10-09 21:18:45 +00004108 # incorrect header guard with nolint
4109 error_collector = ErrorCollector(self.assert_)
4110 cpplint.ProcessFileData(file_path, 'h',
4111 ['#ifndef FOO // NOLINT',
4112 '#define FOO',
4113 '#endif // FOO NOLINT'],
4114 error_collector)
4115 self.assertEquals(
4116 0,
4117 error_collector.ResultList().count(
4118 '#ifndef header guard has wrong style, please use: %s'
4119 ' [build/header_guard] [5]' % expected_guard),
4120 error_collector.ResultList())
4121 self.assertEquals(
4122 0,
4123 error_collector.ResultList().count(
4124 '#endif line should be "#endif // %s"'
4125 ' [build/header_guard] [5]' % expected_guard),
4126 error_collector.ResultList())
4127
erg+personal@google.com05189642010-04-30 20:43:03 +00004128 # Special case for flymake
erg@google.comd350fe52013-01-14 17:51:48 +00004129 for test_file in ['mydir/foo_flymake.h', 'mydir/.flymake/foo.h']:
4130 error_collector = ErrorCollector(self.assert_)
avakulenko@google.com554223d2014-12-04 22:00:20 +00004131 cpplint.ProcessFileData(test_file, 'h',
4132 ['// Copyright 2014 Your Company.', ''],
4133 error_collector)
erg@google.comd350fe52013-01-14 17:51:48 +00004134 self.assertEquals(
4135 1,
4136 error_collector.ResultList().count(
4137 'No #ifndef header guard found, suggested CPP variable is: %s'
4138 ' [build/header_guard] [5]' % expected_guard),
4139 error_collector.ResultList())
erg@google.coma868d2d2009-10-09 21:18:45 +00004140
erg@google.com4d70a882013-04-16 21:06:32 +00004141 def testBuildHeaderGuardWithRoot(self):
4142 file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
4143 'cpplint_test_header.h')
4144 file_info = cpplint.FileInfo(file_path)
4145 if file_info.FullName() == file_info.RepositoryName():
4146 # When FileInfo cannot deduce the root directory of the repository,
4147 # FileInfo.RepositoryName returns the same value as FileInfo.FullName.
4148 # This can happen when this source file was obtained without .svn or
4149 # .git directory. (e.g. using 'svn export' or 'git archive').
4150 # Skip this test in such a case because --root flag makes sense only
4151 # when the root directory of the repository is properly deduced.
4152 return
4153
4154 self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_',
4155 cpplint.GetHeaderGuardCPPVariable(file_path))
4156 cpplint._root = 'cpplint'
4157 self.assertEquals('CPPLINT_TEST_HEADER_H_',
4158 cpplint.GetHeaderGuardCPPVariable(file_path))
4159 # --root flag is ignored if an non-existent directory is specified.
4160 cpplint._root = 'NON_EXISTENT_DIR'
4161 self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_',
4162 cpplint.GetHeaderGuardCPPVariable(file_path))
4163
erg@google.com4e00b9a2009-01-12 23:05:11 +00004164 def testBuildInclude(self):
4165 # Test that include statements have slashes in them.
4166 self.TestLint('#include "foo.h"',
4167 'Include the directory when naming .h files'
4168 ' [build/include] [4]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004169 self.TestLint('#include "Python.h"', '')
4170 self.TestLint('#include "lua.h"', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004171
4172 def testBuildPrintfFormat(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004173 error_collector = ErrorCollector(self.assert_)
4174 cpplint.ProcessFileData(
4175 'foo.cc', 'cc',
4176 [r'printf("\%%d", value);',
4177 r'snprintf(buffer, sizeof(buffer), "\[%d", value);',
4178 r'fprintf(file, "\(%d", value);',
4179 r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);'],
4180 error_collector)
4181 self.assertEquals(
4182 4,
4183 error_collector.Results().count(
4184 '%, [, (, and { are undefined character escapes. Unescape them.'
4185 ' [build/printf_format] [3]'))
erg@google.com4e00b9a2009-01-12 23:05:11 +00004186
avakulenko@google.com02af6282014-06-04 18:53:25 +00004187 error_collector = ErrorCollector(self.assert_)
4188 cpplint.ProcessFileData(
4189 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004190 ['// Copyright 2014 Your Company.',
avakulenko@google.com02af6282014-06-04 18:53:25 +00004191 r'printf("\\%%%d", value);',
4192 r'printf(R"(\[)");',
4193 r'printf(R"(\[%s)", R"(\])");',
4194 ''],
4195 error_collector)
4196 self.assertEquals('', error_collector.Results())
erg@google.com4e00b9a2009-01-12 23:05:11 +00004197
4198 def testRuntimePrintfFormat(self):
4199 self.TestLint(
4200 r'fprintf(file, "%q", value);',
4201 '%q in format strings is deprecated. Use %ll instead.'
4202 ' [runtime/printf_format] [3]')
4203
4204 self.TestLint(
4205 r'aprintf(file, "The number is %12q", value);',
4206 '%q in format strings is deprecated. Use %ll instead.'
4207 ' [runtime/printf_format] [3]')
4208
4209 self.TestLint(
4210 r'printf(file, "The number is" "%-12q", value);',
4211 '%q in format strings is deprecated. Use %ll instead.'
4212 ' [runtime/printf_format] [3]')
4213
4214 self.TestLint(
4215 r'printf(file, "The number is" "%+12q", value);',
4216 '%q in format strings is deprecated. Use %ll instead.'
4217 ' [runtime/printf_format] [3]')
4218
4219 self.TestLint(
4220 r'printf(file, "The number is" "% 12q", value);',
4221 '%q in format strings is deprecated. Use %ll instead.'
4222 ' [runtime/printf_format] [3]')
4223
4224 self.TestLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00004225 r'snprintf(file, "Never mix %d and %1$d parameters!", value);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00004226 '%N$ formats are unconventional. Try rewriting to avoid them.'
4227 ' [runtime/printf_format] [2]')
4228
4229 def TestLintLogCodeOnError(self, code, expected_message):
4230 # Special TestLint which logs the input code on error.
4231 result = self.PerformSingleLineLint(code)
4232 if result != expected_message:
4233 self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"'
4234 % (code, result, expected_message))
4235
4236 def testBuildStorageClass(self):
4237 qualifiers = [None, 'const', 'volatile']
4238 signs = [None, 'signed', 'unsigned']
4239 types = ['void', 'char', 'int', 'float', 'double',
4240 'schar', 'int8', 'uint8', 'int16', 'uint16',
4241 'int32', 'uint32', 'int64', 'uint64']
erg@google.comd350fe52013-01-14 17:51:48 +00004242 storage_classes = ['extern', 'register', 'static', 'typedef']
erg@google.com4e00b9a2009-01-12 23:05:11 +00004243
4244 build_storage_class_error_message = (
Alex Vakulenko01e47232016-05-06 13:54:15 -07004245 'Storage-class specifier (static, extern, typedef, etc) should be '
4246 'at the beginning of the declaration. [build/storage_class] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004247
4248 # Some explicit cases. Legal in C++, deprecated in C99.
4249 self.TestLint('const int static foo = 5;',
4250 build_storage_class_error_message)
4251
4252 self.TestLint('char static foo;',
4253 build_storage_class_error_message)
4254
4255 self.TestLint('double const static foo = 2.0;',
4256 build_storage_class_error_message)
4257
4258 self.TestLint('uint64 typedef unsigned_long_long;',
4259 build_storage_class_error_message)
4260
4261 self.TestLint('int register foo = 0;',
4262 build_storage_class_error_message)
4263
4264 # Since there are a very large number of possibilities, randomly
4265 # construct declarations.
4266 # Make sure that the declaration is logged if there's an error.
4267 # Seed generator with an integer for absolute reproducibility.
4268 random.seed(25)
4269 for unused_i in range(10):
4270 # Build up random list of non-storage-class declaration specs.
4271 other_decl_specs = [random.choice(qualifiers), random.choice(signs),
4272 random.choice(types)]
4273 # remove None
erg@google.comc6671232013-10-25 21:44:03 +00004274 other_decl_specs = [x for x in other_decl_specs if x is not None]
erg@google.com4e00b9a2009-01-12 23:05:11 +00004275
4276 # shuffle
4277 random.shuffle(other_decl_specs)
4278
4279 # insert storage class after the first
4280 storage_class = random.choice(storage_classes)
4281 insertion_point = random.randint(1, len(other_decl_specs))
4282 decl_specs = (other_decl_specs[0:insertion_point]
4283 + [storage_class]
4284 + other_decl_specs[insertion_point:])
4285
4286 self.TestLintLogCodeOnError(
4287 ' '.join(decl_specs) + ';',
4288 build_storage_class_error_message)
4289
4290 # but no error if storage class is first
4291 self.TestLintLogCodeOnError(
4292 storage_class + ' ' + ' '.join(other_decl_specs),
4293 '')
4294
4295 def testLegalCopyright(self):
4296 legal_copyright_message = (
4297 'No copyright message found. '
4298 'You should have a line: "Copyright [year] <Copyright Owner>"'
4299 ' [legal/copyright] [5]')
4300
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004301 copyright_line = '// Copyright 2014 Google Inc. All Rights Reserved.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00004302
4303 file_path = 'mydir/googleclient/foo.cc'
4304
4305 # There should be a copyright message in the first 10 lines
4306 error_collector = ErrorCollector(self.assert_)
4307 cpplint.ProcessFileData(file_path, 'cc', [], error_collector)
4308 self.assertEquals(
4309 1,
4310 error_collector.ResultList().count(legal_copyright_message))
4311
4312 error_collector = ErrorCollector(self.assert_)
4313 cpplint.ProcessFileData(
4314 file_path, 'cc',
4315 ['' for unused_i in range(10)] + [copyright_line],
4316 error_collector)
4317 self.assertEquals(
4318 1,
4319 error_collector.ResultList().count(legal_copyright_message))
4320
4321 # Test that warning isn't issued if Copyright line appears early enough.
4322 error_collector = ErrorCollector(self.assert_)
4323 cpplint.ProcessFileData(file_path, 'cc', [copyright_line], error_collector)
4324 for message in error_collector.ResultList():
4325 if message.find('legal/copyright') != -1:
4326 self.fail('Unexpected error: %s' % message)
4327
4328 error_collector = ErrorCollector(self.assert_)
4329 cpplint.ProcessFileData(
4330 file_path, 'cc',
4331 ['' for unused_i in range(9)] + [copyright_line],
4332 error_collector)
4333 for message in error_collector.ResultList():
4334 if message.find('legal/copyright') != -1:
4335 self.fail('Unexpected error: %s' % message)
4336
erg@google.com36649102009-03-25 21:18:36 +00004337 def testInvalidIncrement(self):
4338 self.TestLint('*count++;',
4339 'Changing pointer instead of value (or unused value of '
4340 'operator*). [runtime/invalid_increment] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004341
erg@google.comd350fe52013-01-14 17:51:48 +00004342 def testSnprintfSize(self):
4343 self.TestLint('vsnprintf(NULL, 0, format)', '')
4344 self.TestLint('snprintf(fisk, 1, format)',
4345 'If you can, use sizeof(fisk) instead of 1 as the 2nd arg '
4346 'to snprintf. [runtime/printf] [3]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00004347class Cxx11Test(CpplintTestBase):
4348
4349 def Helper(self, package, extension, lines, count):
4350 filename = package + '/foo.' + extension
4351 lines = lines[:]
4352
4353 # Header files need to have an ifdef guard wrapped around their code.
4354 if extension == 'h':
4355 guard = filename.upper().replace('/', '_').replace('.', '_') + '_'
4356 lines.insert(0, '#ifndef ' + guard)
4357 lines.insert(1, '#define ' + guard)
4358 lines.append('#endif // ' + guard)
4359
4360 # All files need a final blank line.
4361 lines.append('')
4362
4363 # Process the file and check resulting error count.
4364 collector = ErrorCollector(self.assert_)
4365 cpplint.ProcessFileData(filename, extension, lines, collector)
4366 error_list = collector.ResultList()
4367 self.assertEquals(count, len(error_list), error_list)
4368
4369 def TestCxx11Feature(self, code, expected_error):
4370 lines = code.split('\n')
4371 collector = ErrorCollector(self.assert_)
4372 cpplint.RemoveMultiLineComments('foo.h', lines, collector)
4373 clean_lines = cpplint.CleansedLines(lines)
4374 cpplint.FlagCxx11Features('foo.cc', clean_lines, 0, collector)
4375 self.assertEquals(expected_error, collector.Results())
4376
4377 def testBlockedHeaders(self):
Alex Vakulenko01e47232016-05-06 13:54:15 -07004378 self.TestCxx11Feature('#include <tr1/regex>',
4379 'C++ TR1 headers such as <tr1/regex> are '
4380 'unapproved. [build/c++tr1] [5]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00004381 self.TestCxx11Feature('#include <mutex>',
4382 '<mutex> is an unapproved C++11 header.'
4383 ' [build/c++11] [5]')
4384
4385 def testBlockedClasses(self):
4386 self.TestCxx11Feature('std::alignment_of<T>',
4387 'std::alignment_of is an unapproved '
4388 'C++11 class or function. Send c-style an example '
4389 'of where it would make your code more readable, '
4390 'and they may let you use it.'
4391 ' [build/c++11] [5]')
4392 self.TestCxx11Feature('std::alignment_offer', '')
4393 self.TestCxx11Feature('mystd::alignment_of', '')
4394 self.TestCxx11Feature('std::binomial_distribution', '')
4395
4396 def testBlockedFunctions(self):
4397 self.TestCxx11Feature('std::alignment_of<int>',
4398 'std::alignment_of is an unapproved '
4399 'C++11 class or function. Send c-style an example '
4400 'of where it would make your code more readable, '
4401 'and they may let you use it.'
4402 ' [build/c++11] [5]')
4403 # Missed because of the lack of "std::". Compiles because ADL
4404 # looks in the namespace of my_shared_ptr, which (presumably) is
4405 # std::. But there will be a lint error somewhere in this file
4406 # since my_shared_ptr had to be defined.
4407 self.TestCxx11Feature('static_pointer_cast<Base>(my_shared_ptr)', '')
4408 self.TestCxx11Feature('std::declval<T>()', '')
erg@google.comd350fe52013-01-14 17:51:48 +00004409
4410 def testExplicitMakePair(self):
4411 self.TestLint('make_pair', '')
4412 self.TestLint('make_pair(42, 42)', '')
4413 self.TestLint('make_pair<',
4414 'For C++11-compatibility, omit template arguments from'
4415 ' make_pair OR use pair directly OR if appropriate,'
4416 ' construct a pair directly'
4417 ' [build/explicit_make_pair] [4]')
4418 self.TestLint('make_pair <',
4419 'For C++11-compatibility, omit template arguments from'
4420 ' make_pair OR use pair directly OR if appropriate,'
4421 ' construct a pair directly'
4422 ' [build/explicit_make_pair] [4]')
4423 self.TestLint('my_make_pair<int, int>', '')
4424
Alex Vakulenko01e47232016-05-06 13:54:15 -07004425class Cxx14Test(CpplintTestBase):
4426
4427 def TestCxx14Feature(self, code, expected_error):
4428 lines = code.split('\n')
4429 collector = ErrorCollector(self.assert_)
4430 cpplint.RemoveMultiLineComments('foo.h', lines, collector)
4431 clean_lines = cpplint.CleansedLines(lines)
4432 cpplint.FlagCxx14Features('foo.cc', clean_lines, 0, collector)
4433 self.assertEquals(expected_error, collector.Results())
4434
4435 def testBlockedHeaders(self):
4436 self.TestCxx14Feature('#include <scoped_allocator>',
4437 '<scoped_allocator> is an unapproved C++14 header.'
4438 ' [build/c++14] [5]')
4439 self.TestCxx14Feature('#include <shared_mutex>',
4440 '<shared_mutex> is an unapproved C++14 header.'
4441 ' [build/c++14] [5]')
4442
4443
erg@google.com4e00b9a2009-01-12 23:05:11 +00004444class CleansedLinesTest(unittest.TestCase):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004445
erg@google.com4e00b9a2009-01-12 23:05:11 +00004446 def testInit(self):
4447 lines = ['Line 1',
4448 'Line 2',
4449 'Line 3 // Comment test',
erg@google.comd7d27472011-09-07 17:36:35 +00004450 'Line 4 /* Comment test */',
4451 'Line 5 "foo"']
4452
erg@google.com4e00b9a2009-01-12 23:05:11 +00004453 clean_lines = cpplint.CleansedLines(lines)
4454 self.assertEquals(lines, clean_lines.raw_lines)
erg@google.comd7d27472011-09-07 17:36:35 +00004455 self.assertEquals(5, clean_lines.NumLines())
erg@google.com4e00b9a2009-01-12 23:05:11 +00004456
4457 self.assertEquals(['Line 1',
4458 'Line 2',
erg@google.comd7d27472011-09-07 17:36:35 +00004459 'Line 3',
4460 'Line 4',
4461 'Line 5 "foo"'],
erg@google.com4e00b9a2009-01-12 23:05:11 +00004462 clean_lines.lines)
4463
4464 self.assertEquals(['Line 1',
4465 'Line 2',
erg@google.comd7d27472011-09-07 17:36:35 +00004466 'Line 3',
4467 'Line 4',
4468 'Line 5 ""'],
erg@google.com4e00b9a2009-01-12 23:05:11 +00004469 clean_lines.elided)
4470
4471 def testInitEmpty(self):
4472 clean_lines = cpplint.CleansedLines([])
4473 self.assertEquals([], clean_lines.raw_lines)
4474 self.assertEquals(0, clean_lines.NumLines())
4475
4476 def testCollapseStrings(self):
4477 collapse = cpplint.CleansedLines._CollapseStrings
4478 self.assertEquals('""', collapse('""')) # "" (empty)
4479 self.assertEquals('"""', collapse('"""')) # """ (bad)
4480 self.assertEquals('""', collapse('"xyz"')) # "xyz" (string)
4481 self.assertEquals('""', collapse('"\\\""')) # "\"" (string)
4482 self.assertEquals('""', collapse('"\'"')) # "'" (string)
4483 self.assertEquals('"\"', collapse('"\"')) # "\" (bad)
4484 self.assertEquals('""', collapse('"\\\\"')) # "\\" (string)
4485 self.assertEquals('"', collapse('"\\\\\\"')) # "\\\" (bad)
4486 self.assertEquals('""', collapse('"\\\\\\\\"')) # "\\\\" (string)
4487
4488 self.assertEquals('\'\'', collapse('\'\'')) # '' (empty)
4489 self.assertEquals('\'\'', collapse('\'a\'')) # 'a' (char)
4490 self.assertEquals('\'\'', collapse('\'\\\'\'')) # '\'' (char)
4491 self.assertEquals('\'', collapse('\'\\\'')) # '\' (bad)
4492 self.assertEquals('', collapse('\\012')) # '\012' (char)
4493 self.assertEquals('', collapse('\\xfF0')) # '\xfF0' (char)
4494 self.assertEquals('', collapse('\\n')) # '\n' (char)
avakulenko@google.com02af6282014-06-04 18:53:25 +00004495 self.assertEquals(r'\#', collapse('\\#')) # '\#' (bad)
4496
4497 self.assertEquals('"" + ""', collapse('"\'" + "\'"'))
4498 self.assertEquals("'', ''", collapse("'\"', '\"'"))
4499 self.assertEquals('""[0b10]', collapse('"a\'b"[0b1\'0]'))
4500
4501 self.assertEquals('42', collapse("4'2"))
4502 self.assertEquals('0b0101', collapse("0b0'1'0'1"))
4503 self.assertEquals('1048576', collapse("1'048'576"))
4504 self.assertEquals('0X100000', collapse("0X10'0000"))
4505 self.assertEquals('0004000000', collapse("0'004'000'000"))
4506 self.assertEquals('1.602176565e-19', collapse("1.602'176'565e-19"))
4507 self.assertEquals('\'\' + 0xffff', collapse("'i' + 0xf'f'f'f"))
4508 self.assertEquals('sizeof\'\' == 1', collapse("sizeof'x' == 1"))
4509 self.assertEquals('0x.03p100', collapse('0x.0\'3p1\'0\'0'))
4510 self.assertEquals('123.45', collapse('1\'23.4\'5'))
erg@google.com4e00b9a2009-01-12 23:05:11 +00004511
4512 self.assertEquals('StringReplace(body, "", "");',
4513 collapse('StringReplace(body, "\\\\", "\\\\\\\\");'))
4514 self.assertEquals('\'\' ""',
4515 collapse('\'"\' "foo"'))
4516
4517
4518class OrderOfIncludesTest(CpplintTestBase):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004519
erg@google.com4e00b9a2009-01-12 23:05:11 +00004520 def setUp(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004521 CpplintTestBase.setUp(self)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004522 self.include_state = cpplint._IncludeState()
erg@google.com4e00b9a2009-01-12 23:05:11 +00004523 os.path.abspath = lambda value: value
4524
erg@google.com4e00b9a2009-01-12 23:05:11 +00004525 def testCheckNextIncludeOrder_OtherThenCpp(self):
4526 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4527 cpplint._OTHER_HEADER))
4528 self.assertEqual('Found C++ system header after other header',
4529 self.include_state.CheckNextIncludeOrder(
4530 cpplint._CPP_SYS_HEADER))
4531
4532 def testCheckNextIncludeOrder_CppThenC(self):
4533 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4534 cpplint._CPP_SYS_HEADER))
4535 self.assertEqual('Found C system header after C++ system header',
4536 self.include_state.CheckNextIncludeOrder(
4537 cpplint._C_SYS_HEADER))
4538
4539 def testCheckNextIncludeOrder_LikelyThenCpp(self):
4540 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4541 cpplint._LIKELY_MY_HEADER))
4542 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4543 cpplint._CPP_SYS_HEADER))
4544
4545 def testCheckNextIncludeOrder_PossibleThenCpp(self):
4546 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4547 cpplint._POSSIBLE_MY_HEADER))
4548 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4549 cpplint._CPP_SYS_HEADER))
4550
4551 def testCheckNextIncludeOrder_CppThenLikely(self):
4552 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4553 cpplint._CPP_SYS_HEADER))
4554 # This will eventually fail.
4555 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4556 cpplint._LIKELY_MY_HEADER))
4557
4558 def testCheckNextIncludeOrder_CppThenPossible(self):
4559 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4560 cpplint._CPP_SYS_HEADER))
4561 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4562 cpplint._POSSIBLE_MY_HEADER))
4563
4564 def testClassifyInclude(self):
4565 file_info = cpplint.FileInfo
4566 classify_include = cpplint._ClassifyInclude
4567 self.assertEqual(cpplint._C_SYS_HEADER,
4568 classify_include(file_info('foo/foo.cc'),
4569 'stdio.h',
4570 True))
4571 self.assertEqual(cpplint._CPP_SYS_HEADER,
4572 classify_include(file_info('foo/foo.cc'),
4573 'string',
4574 True))
4575 self.assertEqual(cpplint._CPP_SYS_HEADER,
4576 classify_include(file_info('foo/foo.cc'),
4577 'typeinfo',
4578 True))
4579 self.assertEqual(cpplint._OTHER_HEADER,
4580 classify_include(file_info('foo/foo.cc'),
4581 'string',
4582 False))
4583
4584 self.assertEqual(cpplint._LIKELY_MY_HEADER,
4585 classify_include(file_info('foo/foo.cc'),
4586 'foo/foo-inl.h',
4587 False))
4588 self.assertEqual(cpplint._LIKELY_MY_HEADER,
4589 classify_include(file_info('foo/internal/foo.cc'),
4590 'foo/public/foo.h',
4591 False))
4592 self.assertEqual(cpplint._POSSIBLE_MY_HEADER,
4593 classify_include(file_info('foo/internal/foo.cc'),
4594 'foo/other/public/foo.h',
4595 False))
4596 self.assertEqual(cpplint._OTHER_HEADER,
4597 classify_include(file_info('foo/internal/foo.cc'),
4598 'foo/other/public/foop.h',
4599 False))
4600
4601 def testTryDropCommonSuffixes(self):
4602 self.assertEqual('foo/foo', cpplint._DropCommonSuffixes('foo/foo-inl.h'))
4603 self.assertEqual('foo/bar/foo',
4604 cpplint._DropCommonSuffixes('foo/bar/foo_inl.h'))
4605 self.assertEqual('foo/foo', cpplint._DropCommonSuffixes('foo/foo.cc'))
4606 self.assertEqual('foo/foo_unusualinternal',
4607 cpplint._DropCommonSuffixes('foo/foo_unusualinternal.h'))
4608 self.assertEqual('',
4609 cpplint._DropCommonSuffixes('_test.cc'))
4610 self.assertEqual('test',
4611 cpplint._DropCommonSuffixes('test.cc'))
4612
4613 def testRegression(self):
4614 def Format(includes):
erg@google.comfd5da632013-10-25 17:39:45 +00004615 include_list = []
avakulenko@google.com554223d2014-12-04 22:00:20 +00004616 for item in includes:
4617 if item.startswith('"') or item.startswith('<'):
4618 include_list.append('#include %s\n' % item)
erg@google.comfd5da632013-10-25 17:39:45 +00004619 else:
avakulenko@google.com554223d2014-12-04 22:00:20 +00004620 include_list.append(item + '\n')
erg@google.comfd5da632013-10-25 17:39:45 +00004621 return ''.join(include_list)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004622
4623 # Test singleton cases first.
4624 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"foo/foo.h"']), '')
4625 self.TestLanguageRulesCheck('foo/foo.cc', Format(['<stdio.h>']), '')
4626 self.TestLanguageRulesCheck('foo/foo.cc', Format(['<string>']), '')
4627 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"foo/foo-inl.h"']), '')
4628 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"bar/bar-inl.h"']), '')
4629 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"bar/bar.h"']), '')
4630
4631 # Test everything in a good and new order.
4632 self.TestLanguageRulesCheck('foo/foo.cc',
4633 Format(['"foo/foo.h"',
4634 '"foo/foo-inl.h"',
4635 '<stdio.h>',
4636 '<string>',
avakulenko@google.com02af6282014-06-04 18:53:25 +00004637 '<unordered_map>',
erg@google.com4e00b9a2009-01-12 23:05:11 +00004638 '"bar/bar-inl.h"',
4639 '"bar/bar.h"']),
4640 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004641
4642 # Test bad orders.
4643 self.TestLanguageRulesCheck(
4644 'foo/foo.cc',
4645 Format(['<string>', '<stdio.h>']),
4646 'Found C system header after C++ system header.'
4647 ' Should be: foo.h, c system, c++ system, other.'
4648 ' [build/include_order] [4]')
4649 self.TestLanguageRulesCheck(
4650 'foo/foo.cc',
4651 Format(['"foo/bar-inl.h"',
4652 '"foo/foo-inl.h"']),
4653 '')
erg@google.comfd5da632013-10-25 17:39:45 +00004654 self.TestLanguageRulesCheck(
4655 'foo/foo.cc',
4656 Format(['"foo/e.h"',
4657 '"foo/b.h"', # warning here (e>b)
4658 '"foo/c.h"',
4659 '"foo/d.h"',
4660 '"foo/a.h"']), # warning here (d>a)
4661 ['Include "foo/b.h" not in alphabetical order'
4662 ' [build/include_alpha] [4]',
4663 'Include "foo/a.h" not in alphabetical order'
4664 ' [build/include_alpha] [4]'])
erg@google.com4e00b9a2009-01-12 23:05:11 +00004665 # -inl.h headers are no longer special.
4666 self.TestLanguageRulesCheck('foo/foo.cc',
4667 Format(['"foo/foo-inl.h"', '<string>']),
4668 '')
4669 self.TestLanguageRulesCheck('foo/foo.cc',
4670 Format(['"foo/bar.h"', '"foo/bar-inl.h"']),
4671 '')
4672 # Test componentized header. OK to have my header in ../public dir.
4673 self.TestLanguageRulesCheck('foo/internal/foo.cc',
4674 Format(['"foo/public/foo.h"', '<string>']),
4675 '')
4676 # OK to have my header in other dir (not stylistically, but
4677 # cpplint isn't as good as a human).
4678 self.TestLanguageRulesCheck('foo/internal/foo.cc',
4679 Format(['"foo/other/public/foo.h"',
4680 '<string>']),
4681 '')
erg@google.coma868d2d2009-10-09 21:18:45 +00004682 self.TestLanguageRulesCheck('foo/foo.cc',
4683 Format(['"foo/foo.h"',
4684 '<string>',
4685 '"base/google.h"',
4686 '"base/flags.h"']),
4687 'Include "base/flags.h" not in alphabetical '
4688 'order [build/include_alpha] [4]')
4689 # According to the style, -inl.h should come before .h, but we don't
4690 # complain about that.
4691 self.TestLanguageRulesCheck('foo/foo.cc',
4692 Format(['"foo/foo-inl.h"',
4693 '"foo/foo.h"',
4694 '"base/google.h"',
4695 '"base/google-inl.h"']),
4696 '')
erg@google.comfd5da632013-10-25 17:39:45 +00004697 # Allow project includes to be separated by blank lines
4698 self.TestLanguageRulesCheck('a/a.cc',
4699 Format(['"a/a.h"',
4700 '<string>',
4701 '"base/google.h"',
4702 '',
avakulenko@google.com554223d2014-12-04 22:00:20 +00004703 '"b/c.h"',
4704 '',
4705 'MACRO',
erg@google.comfd5da632013-10-25 17:39:45 +00004706 '"a/b.h"']),
4707 '')
4708 self.TestLanguageRulesCheck('a/a.cc',
4709 Format(['"a/a.h"',
4710 '<string>',
4711 '"base/google.h"',
4712 '"a/b.h"']),
4713 'Include "a/b.h" not in alphabetical '
4714 'order [build/include_alpha] [4]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004715
erg@google.com2aa59982013-10-28 19:09:25 +00004716 # Test conditional includes
4717 self.TestLanguageRulesCheck(
4718 'a/a.cc',
4719 ''.join(['#include <string.h>\n',
4720 '#include "base/port.h"\n',
4721 '#include <initializer_list>\n']),
4722 ('Found C++ system header after other header. '
4723 'Should be: a.h, c system, c++ system, other. '
4724 '[build/include_order] [4]'))
4725 self.TestLanguageRulesCheck(
4726 'a/a.cc',
4727 ''.join(['#include <string.h>\n',
4728 '#include "base/port.h"\n',
4729 '#ifdef LANG_CXX11\n',
4730 '#include <initializer_list>\n',
4731 '#endif // LANG_CXX11\n']),
4732 '')
4733 self.TestLanguageRulesCheck(
4734 'a/a.cc',
4735 ''.join(['#include <string.h>\n',
4736 '#ifdef LANG_CXX11\n',
4737 '#include "base/port.h"\n',
4738 '#include <initializer_list>\n',
4739 '#endif // LANG_CXX11\n']),
4740 ('Found C++ system header after other header. '
4741 'Should be: a.h, c system, c++ system, other. '
4742 '[build/include_order] [4]'))
4743
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004744 # Third party headers are exempt from order checks
4745 self.TestLanguageRulesCheck('foo/foo.cc',
4746 Format(['<string>', '"Python.h"', '<vector>']),
4747 '')
4748
erg@google.com4e00b9a2009-01-12 23:05:11 +00004749
4750class CheckForFunctionLengthsTest(CpplintTestBase):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004751
erg@google.com4e00b9a2009-01-12 23:05:11 +00004752 def setUp(self):
4753 # Reducing these thresholds for the tests speeds up tests significantly.
4754 self.old_normal_trigger = cpplint._FunctionState._NORMAL_TRIGGER
4755 self.old_test_trigger = cpplint._FunctionState._TEST_TRIGGER
4756
4757 cpplint._FunctionState._NORMAL_TRIGGER = 10
4758 cpplint._FunctionState._TEST_TRIGGER = 25
4759
4760 def tearDown(self):
4761 cpplint._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger
4762 cpplint._FunctionState._TEST_TRIGGER = self.old_test_trigger
4763
4764 def TestFunctionLengthsCheck(self, code, expected_message):
4765 """Check warnings for long function bodies are as expected.
4766
4767 Args:
4768 code: C++ source code expected to generate a warning message.
4769 expected_message: Message expected to be generated by the C++ code.
4770 """
4771 self.assertEquals(expected_message,
4772 self.PerformFunctionLengthsCheck(code))
4773
4774 def TriggerLines(self, error_level):
4775 """Return number of lines needed to trigger a function length warning.
4776
4777 Args:
4778 error_level: --v setting for cpplint.
4779
4780 Returns:
4781 Number of lines needed to trigger a function length warning.
4782 """
4783 return cpplint._FunctionState._NORMAL_TRIGGER * 2**error_level
4784
4785 def TestLines(self, error_level):
4786 """Return number of lines needed to trigger a test function length warning.
4787
4788 Args:
4789 error_level: --v setting for cpplint.
4790
4791 Returns:
4792 Number of lines needed to trigger a test function length warning.
4793 """
4794 return cpplint._FunctionState._TEST_TRIGGER * 2**error_level
4795
4796 def TestFunctionLengthCheckDefinition(self, lines, error_level):
4797 """Generate long function definition and check warnings are as expected.
4798
4799 Args:
4800 lines: Number of lines to generate.
4801 error_level: --v setting for cpplint.
4802 """
4803 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4804 self.TestFunctionLengthsCheck(
4805 'void test(int x)' + self.FunctionBody(lines),
4806 ('Small and focused functions are preferred: '
4807 'test() has %d non-comment lines '
4808 '(error triggered by exceeding %d lines).'
4809 ' [readability/fn_size] [%d]'
4810 % (lines, trigger_level, error_level)))
4811
4812 def TestFunctionLengthCheckDefinitionOK(self, lines):
4813 """Generate shorter function definition and check no warning is produced.
4814
4815 Args:
4816 lines: Number of lines to generate.
4817 """
4818 self.TestFunctionLengthsCheck(
4819 'void test(int x)' + self.FunctionBody(lines),
4820 '')
4821
4822 def TestFunctionLengthCheckAtErrorLevel(self, error_level):
4823 """Generate and check function at the trigger level for --v setting.
4824
4825 Args:
4826 error_level: --v setting for cpplint.
4827 """
4828 self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level),
4829 error_level)
4830
4831 def TestFunctionLengthCheckBelowErrorLevel(self, error_level):
4832 """Generate and check function just below the trigger level for --v setting.
4833
4834 Args:
4835 error_level: --v setting for cpplint.
4836 """
4837 self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level)-1,
4838 error_level-1)
4839
4840 def TestFunctionLengthCheckAboveErrorLevel(self, error_level):
4841 """Generate and check function just above the trigger level for --v setting.
4842
4843 Args:
4844 error_level: --v setting for cpplint.
4845 """
4846 self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level)+1,
4847 error_level)
4848
4849 def FunctionBody(self, number_of_lines):
4850 return ' {\n' + ' this_is_just_a_test();\n'*number_of_lines + '}'
4851
4852 def FunctionBodyWithBlankLines(self, number_of_lines):
4853 return ' {\n' + ' this_is_just_a_test();\n\n'*number_of_lines + '}'
4854
4855 def FunctionBodyWithNoLints(self, number_of_lines):
4856 return (' {\n' +
4857 ' this_is_just_a_test(); // NOLINT\n'*number_of_lines + '}')
4858
4859 # Test line length checks.
4860 def testFunctionLengthCheckDeclaration(self):
4861 self.TestFunctionLengthsCheck(
4862 'void test();', # Not a function definition
4863 '')
4864
4865 def testFunctionLengthCheckDeclarationWithBlockFollowing(self):
4866 self.TestFunctionLengthsCheck(
4867 ('void test();\n'
4868 + self.FunctionBody(66)), # Not a function definition
4869 '')
4870
4871 def testFunctionLengthCheckClassDefinition(self):
4872 self.TestFunctionLengthsCheck( # Not a function definition
4873 'class Test' + self.FunctionBody(66) + ';',
4874 '')
4875
4876 def testFunctionLengthCheckTrivial(self):
4877 self.TestFunctionLengthsCheck(
4878 'void test() {}', # Not counted
4879 '')
4880
4881 def testFunctionLengthCheckEmpty(self):
4882 self.TestFunctionLengthsCheck(
4883 'void test() {\n}',
4884 '')
4885
4886 def testFunctionLengthCheckDefinitionBelowSeverity0(self):
4887 old_verbosity = cpplint._SetVerboseLevel(0)
4888 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(0)-1)
4889 cpplint._SetVerboseLevel(old_verbosity)
4890
4891 def testFunctionLengthCheckDefinitionAtSeverity0(self):
4892 old_verbosity = cpplint._SetVerboseLevel(0)
4893 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(0))
4894 cpplint._SetVerboseLevel(old_verbosity)
4895
4896 def testFunctionLengthCheckDefinitionAboveSeverity0(self):
4897 old_verbosity = cpplint._SetVerboseLevel(0)
4898 self.TestFunctionLengthCheckAboveErrorLevel(0)
4899 cpplint._SetVerboseLevel(old_verbosity)
4900
4901 def testFunctionLengthCheckDefinitionBelowSeverity1v0(self):
4902 old_verbosity = cpplint._SetVerboseLevel(0)
4903 self.TestFunctionLengthCheckBelowErrorLevel(1)
4904 cpplint._SetVerboseLevel(old_verbosity)
4905
4906 def testFunctionLengthCheckDefinitionAtSeverity1v0(self):
4907 old_verbosity = cpplint._SetVerboseLevel(0)
4908 self.TestFunctionLengthCheckAtErrorLevel(1)
4909 cpplint._SetVerboseLevel(old_verbosity)
4910
4911 def testFunctionLengthCheckDefinitionBelowSeverity1(self):
4912 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(1)-1)
4913
4914 def testFunctionLengthCheckDefinitionAtSeverity1(self):
4915 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(1))
4916
4917 def testFunctionLengthCheckDefinitionAboveSeverity1(self):
4918 self.TestFunctionLengthCheckAboveErrorLevel(1)
4919
4920 def testFunctionLengthCheckDefinitionSeverity1PlusBlanks(self):
4921 error_level = 1
4922 error_lines = self.TriggerLines(error_level) + 1
4923 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4924 self.TestFunctionLengthsCheck(
4925 'void test_blanks(int x)' + self.FunctionBody(error_lines),
4926 ('Small and focused functions are preferred: '
4927 'test_blanks() has %d non-comment lines '
4928 '(error triggered by exceeding %d lines).'
4929 ' [readability/fn_size] [%d]')
4930 % (error_lines, trigger_level, error_level))
4931
4932 def testFunctionLengthCheckComplexDefinitionSeverity1(self):
4933 error_level = 1
4934 error_lines = self.TriggerLines(error_level) + 1
4935 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4936 self.TestFunctionLengthsCheck(
4937 ('my_namespace::my_other_namespace::MyVeryLongTypeName*\n'
4938 'my_namespace::my_other_namespace::MyFunction(int arg1, char* arg2)'
4939 + self.FunctionBody(error_lines)),
4940 ('Small and focused functions are preferred: '
4941 'my_namespace::my_other_namespace::MyFunction()'
4942 ' has %d non-comment lines '
4943 '(error triggered by exceeding %d lines).'
4944 ' [readability/fn_size] [%d]')
4945 % (error_lines, trigger_level, error_level))
4946
4947 def testFunctionLengthCheckDefinitionSeverity1ForTest(self):
4948 error_level = 1
4949 error_lines = self.TestLines(error_level) + 1
4950 trigger_level = self.TestLines(cpplint._VerboseLevel())
4951 self.TestFunctionLengthsCheck(
4952 'TEST_F(Test, Mutator)' + self.FunctionBody(error_lines),
4953 ('Small and focused functions are preferred: '
4954 'TEST_F(Test, Mutator) has %d non-comment lines '
4955 '(error triggered by exceeding %d lines).'
4956 ' [readability/fn_size] [%d]')
4957 % (error_lines, trigger_level, error_level))
4958
4959 def testFunctionLengthCheckDefinitionSeverity1ForSplitLineTest(self):
4960 error_level = 1
4961 error_lines = self.TestLines(error_level) + 1
4962 trigger_level = self.TestLines(cpplint._VerboseLevel())
4963 self.TestFunctionLengthsCheck(
4964 ('TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,\n'
4965 ' FixGoogleUpdate_AllValues_MachineApp)' # note: 4 spaces
4966 + self.FunctionBody(error_lines)),
4967 ('Small and focused functions are preferred: '
4968 'TEST_F(GoogleUpdateRecoveryRegistryProtectedTest, ' # 1 space
4969 'FixGoogleUpdate_AllValues_MachineApp) has %d non-comment lines '
4970 '(error triggered by exceeding %d lines).'
4971 ' [readability/fn_size] [%d]')
4972 % (error_lines+1, trigger_level, error_level))
4973
4974 def testFunctionLengthCheckDefinitionSeverity1ForBadTestDoesntBreak(self):
4975 error_level = 1
4976 error_lines = self.TestLines(error_level) + 1
4977 trigger_level = self.TestLines(cpplint._VerboseLevel())
4978 self.TestFunctionLengthsCheck(
4979 ('TEST_F('
4980 + self.FunctionBody(error_lines)),
4981 ('Small and focused functions are preferred: '
4982 'TEST_F has %d non-comment lines '
4983 '(error triggered by exceeding %d lines).'
4984 ' [readability/fn_size] [%d]')
4985 % (error_lines, trigger_level, error_level))
4986
4987 def testFunctionLengthCheckDefinitionSeverity1WithEmbeddedNoLints(self):
4988 error_level = 1
4989 error_lines = self.TriggerLines(error_level)+1
4990 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4991 self.TestFunctionLengthsCheck(
4992 'void test(int x)' + self.FunctionBodyWithNoLints(error_lines),
4993 ('Small and focused functions are preferred: '
4994 'test() has %d non-comment lines '
4995 '(error triggered by exceeding %d lines).'
4996 ' [readability/fn_size] [%d]')
4997 % (error_lines, trigger_level, error_level))
4998
4999 def testFunctionLengthCheckDefinitionSeverity1WithNoLint(self):
5000 self.TestFunctionLengthsCheck(
5001 ('void test(int x)' + self.FunctionBody(self.TriggerLines(1))
5002 + ' // NOLINT -- long function'),
5003 '')
5004
5005 def testFunctionLengthCheckDefinitionBelowSeverity2(self):
5006 self.TestFunctionLengthCheckBelowErrorLevel(2)
5007
5008 def testFunctionLengthCheckDefinitionSeverity2(self):
5009 self.TestFunctionLengthCheckAtErrorLevel(2)
5010
5011 def testFunctionLengthCheckDefinitionAboveSeverity2(self):
5012 self.TestFunctionLengthCheckAboveErrorLevel(2)
5013
5014 def testFunctionLengthCheckDefinitionBelowSeverity3(self):
5015 self.TestFunctionLengthCheckBelowErrorLevel(3)
5016
5017 def testFunctionLengthCheckDefinitionSeverity3(self):
5018 self.TestFunctionLengthCheckAtErrorLevel(3)
5019
5020 def testFunctionLengthCheckDefinitionAboveSeverity3(self):
5021 self.TestFunctionLengthCheckAboveErrorLevel(3)
5022
5023 def testFunctionLengthCheckDefinitionBelowSeverity4(self):
5024 self.TestFunctionLengthCheckBelowErrorLevel(4)
5025
5026 def testFunctionLengthCheckDefinitionSeverity4(self):
5027 self.TestFunctionLengthCheckAtErrorLevel(4)
5028
5029 def testFunctionLengthCheckDefinitionAboveSeverity4(self):
5030 self.TestFunctionLengthCheckAboveErrorLevel(4)
5031
5032 def testFunctionLengthCheckDefinitionBelowSeverity5(self):
5033 self.TestFunctionLengthCheckBelowErrorLevel(5)
5034
5035 def testFunctionLengthCheckDefinitionAtSeverity5(self):
5036 self.TestFunctionLengthCheckAtErrorLevel(5)
5037
5038 def testFunctionLengthCheckDefinitionAboveSeverity5(self):
5039 self.TestFunctionLengthCheckAboveErrorLevel(5)
5040
5041 def testFunctionLengthCheckDefinitionHugeLines(self):
5042 # 5 is the limit
5043 self.TestFunctionLengthCheckDefinition(self.TriggerLines(10), 5)
5044
5045 def testFunctionLengthNotDeterminable(self):
erg@google.com4e00b9a2009-01-12 23:05:11 +00005046 # Macro invocation without terminating semicolon.
5047 self.TestFunctionLengthsCheck(
5048 'MACRO(arg)',
5049 '')
5050
5051 # Macro with underscores
5052 self.TestFunctionLengthsCheck(
5053 'MACRO_WITH_UNDERSCORES(arg1, arg2, arg3)',
5054 '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00005055
erg@google.com4e00b9a2009-01-12 23:05:11 +00005056 self.TestFunctionLengthsCheck(
5057 'NonMacro(arg)',
5058 'Lint failed to find start of function body.'
5059 ' [readability/fn_size] [5]')
5060
Alex Vakulenko01e47232016-05-06 13:54:15 -07005061 def testFunctionLengthCheckWithNamespace(self):
5062 old_verbosity = cpplint._SetVerboseLevel(1)
5063 self.TestFunctionLengthsCheck(
5064 ('namespace {\n'
5065 'void CodeCoverageCL35256059() {\n' +
5066 (' X++;\n' * 3000) +
5067 '}\n'
5068 '} // namespace\n'),
5069 ('Small and focused functions are preferred: '
5070 'CodeCoverageCL35256059() has 3000 non-comment lines '
5071 '(error triggered by exceeding 20 lines).'
5072 ' [readability/fn_size] [5]'))
5073 cpplint._SetVerboseLevel(old_verbosity)
5074
avakulenko@google.com02af6282014-06-04 18:53:25 +00005075
5076def TrimExtraIndent(text_block):
5077 """Trim a uniform amount of whitespace off of each line in a string.
5078
5079 Compute the minimum indent on all non blank lines and trim that from each, so
5080 that the block of text has no extra indentation.
5081
5082 Args:
5083 text_block: a multiline string
5084
5085 Returns:
5086 text_block with the common whitespace indent of each line removed.
5087 """
5088
5089 def CountLeadingWhitespace(s):
5090 count = 0
5091 for c in s:
5092 if not c.isspace():
5093 break
5094 count += 1
5095 return count
5096 # find the minimum indent (except for blank lines)
5097 min_indent = min([CountLeadingWhitespace(line)
5098 for line in text_block.split('\n') if line])
5099 return '\n'.join([line[min_indent:] for line in text_block.split('\n')])
5100
5101
5102class CloseExpressionTest(unittest.TestCase):
5103
erg@google.comd350fe52013-01-14 17:51:48 +00005104 def setUp(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00005105 self.lines = cpplint.CleansedLines(
5106 # 1 2 3 4 5
5107 # 0123456789012345678901234567890123456789012345678901234567890
5108 ['// Line 0',
5109 'inline RCULocked<X>::ReadPtr::ReadPtr(const RCULocked* rcu) {',
5110 ' DCHECK(!(data & kFlagMask)) << "Error";',
5111 '}',
5112 '// Line 4',
5113 'RCULocked<X>::WritePtr::WritePtr(RCULocked* rcu)',
5114 ' : lock_(&rcu_->mutex_) {',
5115 '}',
5116 '// Line 8',
5117 'template <typename T, typename... A>',
5118 'typename std::enable_if<',
5119 ' std::is_array<T>::value && (std::extent<T>::value > 0)>::type',
5120 'MakeUnique(A&&... a) = delete;',
5121 '// Line 13',
5122 'auto x = []() {};',
5123 '// Line 15',
5124 'template <typename U>',
5125 'friend bool operator==(const reffed_ptr& a,',
5126 ' const reffed_ptr<U>& b) {',
5127 ' return a.get() == b.get();',
5128 '}',
5129 '// Line 21'])
5130
5131 def testCloseExpression(self):
5132 # List of positions to test:
5133 # (start line, start position, end line, end position + 1)
5134 positions = [(1, 16, 1, 19),
5135 (1, 37, 1, 59),
5136 (1, 60, 3, 1),
5137 (2, 8, 2, 29),
5138 (2, 30, 22, -1), # Left shift operator
5139 (9, 9, 9, 36),
5140 (10, 23, 11, 59),
5141 (11, 54, 22, -1), # Greater than operator
5142 (14, 9, 14, 11),
5143 (14, 11, 14, 13),
5144 (14, 14, 14, 16),
5145 (17, 22, 18, 46),
5146 (18, 47, 20, 1)]
5147 for p in positions:
5148 (_, line, column) = cpplint.CloseExpression(self.lines, p[0], p[1])
5149 self.assertEquals((p[2], p[3]), (line, column))
5150
5151 def testReverseCloseExpression(self):
5152 # List of positions to test:
5153 # (end line, end position, start line, start position)
5154 positions = [(1, 18, 1, 16),
5155 (1, 58, 1, 37),
5156 (2, 27, 2, 10),
5157 (2, 28, 2, 8),
5158 (6, 18, 0, -1), # -> operator
5159 (9, 35, 9, 9),
5160 (11, 54, 0, -1), # Greater than operator
5161 (11, 57, 11, 31),
5162 (14, 10, 14, 9),
5163 (14, 12, 14, 11),
5164 (14, 15, 14, 14),
5165 (18, 45, 17, 22),
5166 (20, 0, 18, 47)]
5167 for p in positions:
5168 (_, line, column) = cpplint.ReverseCloseExpression(self.lines, p[0], p[1])
5169 self.assertEquals((p[2], p[3]), (line, column))
5170
5171
5172class NestingStateTest(unittest.TestCase):
5173
5174 def setUp(self):
5175 self.nesting_state = cpplint.NestingState()
erg@google.comd350fe52013-01-14 17:51:48 +00005176 self.error_collector = ErrorCollector(self.assert_)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005177
erg@google.comd350fe52013-01-14 17:51:48 +00005178 def UpdateWithLines(self, lines):
5179 clean_lines = cpplint.CleansedLines(lines)
5180 for line in xrange(clean_lines.NumLines()):
5181 self.nesting_state.Update('test.cc',
5182 clean_lines, line, self.error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005183
erg@google.comd350fe52013-01-14 17:51:48 +00005184 def testEmpty(self):
5185 self.UpdateWithLines([])
5186 self.assertEquals(self.nesting_state.stack, [])
erg@google.com4e00b9a2009-01-12 23:05:11 +00005187
erg@google.comd350fe52013-01-14 17:51:48 +00005188 def testNamespace(self):
5189 self.UpdateWithLines(['namespace {'])
5190 self.assertEquals(len(self.nesting_state.stack), 1)
5191 self.assertTrue(isinstance(self.nesting_state.stack[0],
5192 cpplint._NamespaceInfo))
5193 self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
5194 self.assertEquals(self.nesting_state.stack[0].name, '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005195
erg@google.comd350fe52013-01-14 17:51:48 +00005196 self.UpdateWithLines(['namespace outer { namespace inner'])
5197 self.assertEquals(len(self.nesting_state.stack), 3)
5198 self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
5199 self.assertTrue(self.nesting_state.stack[1].seen_open_brace)
5200 self.assertFalse(self.nesting_state.stack[2].seen_open_brace)
5201 self.assertEquals(self.nesting_state.stack[0].name, '')
5202 self.assertEquals(self.nesting_state.stack[1].name, 'outer')
5203 self.assertEquals(self.nesting_state.stack[2].name, 'inner')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005204
erg@google.comd350fe52013-01-14 17:51:48 +00005205 self.UpdateWithLines(['{'])
5206 self.assertTrue(self.nesting_state.stack[2].seen_open_brace)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005207
erg@google.comd350fe52013-01-14 17:51:48 +00005208 self.UpdateWithLines(['}', '}}'])
5209 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005210
erg@google.comd350fe52013-01-14 17:51:48 +00005211 def testClass(self):
5212 self.UpdateWithLines(['class A {'])
5213 self.assertEquals(len(self.nesting_state.stack), 1)
5214 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5215 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5216 self.assertFalse(self.nesting_state.stack[0].is_derived)
erg@google.comfd5da632013-10-25 17:39:45 +00005217 self.assertEquals(self.nesting_state.stack[0].class_indent, 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005218
erg@google.comd350fe52013-01-14 17:51:48 +00005219 self.UpdateWithLines(['};',
5220 'struct B : public A {'])
5221 self.assertEquals(len(self.nesting_state.stack), 1)
5222 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5223 self.assertEquals(self.nesting_state.stack[0].name, 'B')
5224 self.assertTrue(self.nesting_state.stack[0].is_derived)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005225
erg@google.comd350fe52013-01-14 17:51:48 +00005226 self.UpdateWithLines(['};',
5227 'class C',
5228 ': public A {'])
5229 self.assertEquals(len(self.nesting_state.stack), 1)
5230 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5231 self.assertEquals(self.nesting_state.stack[0].name, 'C')
5232 self.assertTrue(self.nesting_state.stack[0].is_derived)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005233
erg@google.comd350fe52013-01-14 17:51:48 +00005234 self.UpdateWithLines(['};',
5235 'template<T>'])
5236 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005237
erg@google.comfd5da632013-10-25 17:39:45 +00005238 self.UpdateWithLines(['class D {', ' class E {'])
erg@google.comd350fe52013-01-14 17:51:48 +00005239 self.assertEquals(len(self.nesting_state.stack), 2)
5240 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5241 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5242 self.assertFalse(self.nesting_state.stack[0].is_derived)
5243 self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5244 self.assertEquals(self.nesting_state.stack[1].name, 'E')
5245 self.assertFalse(self.nesting_state.stack[1].is_derived)
erg@google.comfd5da632013-10-25 17:39:45 +00005246 self.assertEquals(self.nesting_state.stack[1].class_indent, 2)
erg@google.comd350fe52013-01-14 17:51:48 +00005247 self.assertEquals(self.nesting_state.InnermostClass().name, 'E')
erg@google.comd7d27472011-09-07 17:36:35 +00005248
erg@google.comd350fe52013-01-14 17:51:48 +00005249 self.UpdateWithLines(['}', '}'])
5250 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.comd7d27472011-09-07 17:36:35 +00005251
erg@google.comd350fe52013-01-14 17:51:48 +00005252 def testClassAccess(self):
5253 self.UpdateWithLines(['class A {'])
5254 self.assertEquals(len(self.nesting_state.stack), 1)
5255 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5256 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.comd7d27472011-09-07 17:36:35 +00005257
erg@google.comd350fe52013-01-14 17:51:48 +00005258 self.UpdateWithLines([' public:'])
5259 self.assertEquals(self.nesting_state.stack[0].access, 'public')
5260 self.UpdateWithLines([' protracted:'])
5261 self.assertEquals(self.nesting_state.stack[0].access, 'public')
5262 self.UpdateWithLines([' protected:'])
5263 self.assertEquals(self.nesting_state.stack[0].access, 'protected')
5264 self.UpdateWithLines([' private:'])
5265 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005266
erg@google.comd350fe52013-01-14 17:51:48 +00005267 self.UpdateWithLines([' struct B {'])
5268 self.assertEquals(len(self.nesting_state.stack), 2)
5269 self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5270 self.assertEquals(self.nesting_state.stack[1].access, 'public')
5271 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005272
erg@google.comd350fe52013-01-14 17:51:48 +00005273 self.UpdateWithLines([' protected :'])
5274 self.assertEquals(self.nesting_state.stack[1].access, 'protected')
5275 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005276
erg@google.comd350fe52013-01-14 17:51:48 +00005277 self.UpdateWithLines([' }', '}'])
5278 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005279
erg@google.comd350fe52013-01-14 17:51:48 +00005280 def testStruct(self):
5281 self.UpdateWithLines(['struct A {'])
5282 self.assertEquals(len(self.nesting_state.stack), 1)
5283 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5284 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5285 self.assertFalse(self.nesting_state.stack[0].is_derived)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005286
erg@google.comd350fe52013-01-14 17:51:48 +00005287 self.UpdateWithLines(['}',
5288 'void Func(struct B arg) {'])
5289 self.assertEquals(len(self.nesting_state.stack), 1)
5290 self.assertFalse(isinstance(self.nesting_state.stack[0],
5291 cpplint._ClassInfo))
erg@google.com4e00b9a2009-01-12 23:05:11 +00005292
erg@google.comd350fe52013-01-14 17:51:48 +00005293 self.UpdateWithLines(['}'])
5294 self.assertEquals(len(self.nesting_state.stack), 0)
erg+personal@google.com05189642010-04-30 20:43:03 +00005295
erg@google.comd350fe52013-01-14 17:51:48 +00005296 def testPreprocessor(self):
5297 self.assertEquals(len(self.nesting_state.pp_stack), 0)
5298 self.UpdateWithLines(['#if MACRO1'])
5299 self.assertEquals(len(self.nesting_state.pp_stack), 1)
5300 self.UpdateWithLines(['#endif'])
5301 self.assertEquals(len(self.nesting_state.pp_stack), 0)
5302
5303 self.UpdateWithLines(['#ifdef MACRO2'])
5304 self.assertEquals(len(self.nesting_state.pp_stack), 1)
5305 self.UpdateWithLines(['#else'])
5306 self.assertEquals(len(self.nesting_state.pp_stack), 1)
5307 self.UpdateWithLines(['#ifdef MACRO3'])
5308 self.assertEquals(len(self.nesting_state.pp_stack), 2)
5309 self.UpdateWithLines(['#elif MACRO4'])
5310 self.assertEquals(len(self.nesting_state.pp_stack), 2)
5311 self.UpdateWithLines(['#endif'])
5312 self.assertEquals(len(self.nesting_state.pp_stack), 1)
5313 self.UpdateWithLines(['#endif'])
5314 self.assertEquals(len(self.nesting_state.pp_stack), 0)
5315
5316 self.UpdateWithLines(['#ifdef MACRO5',
5317 'class A {',
5318 '#elif MACRO6',
5319 'class B {',
5320 '#else',
5321 'class C {',
5322 '#endif'])
5323 self.assertEquals(len(self.nesting_state.pp_stack), 0)
5324 self.assertEquals(len(self.nesting_state.stack), 1)
5325 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5326 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5327 self.UpdateWithLines(['};'])
5328 self.assertEquals(len(self.nesting_state.stack), 0)
5329
5330 self.UpdateWithLines(['class D',
5331 '#ifdef MACRO7'])
5332 self.assertEquals(len(self.nesting_state.pp_stack), 1)
5333 self.assertEquals(len(self.nesting_state.stack), 1)
5334 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5335 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5336 self.assertFalse(self.nesting_state.stack[0].is_derived)
5337
5338 self.UpdateWithLines(['#elif MACRO8',
5339 ': public E'])
5340 self.assertEquals(len(self.nesting_state.stack), 1)
5341 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5342 self.assertTrue(self.nesting_state.stack[0].is_derived)
5343 self.assertFalse(self.nesting_state.stack[0].seen_open_brace)
5344
5345 self.UpdateWithLines(['#else',
5346 '{'])
5347 self.assertEquals(len(self.nesting_state.stack), 1)
5348 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5349 self.assertFalse(self.nesting_state.stack[0].is_derived)
5350 self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
5351
5352 self.UpdateWithLines(['#endif'])
5353 self.assertEquals(len(self.nesting_state.pp_stack), 0)
5354 self.assertEquals(len(self.nesting_state.stack), 1)
5355 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5356 self.assertFalse(self.nesting_state.stack[0].is_derived)
5357 self.assertFalse(self.nesting_state.stack[0].seen_open_brace)
5358
5359 self.UpdateWithLines([';'])
5360 self.assertEquals(len(self.nesting_state.stack), 0)
5361
5362 def testTemplate(self):
5363 self.UpdateWithLines(['template <T,',
5364 ' class Arg1 = tmpl<T> >'])
5365 self.assertEquals(len(self.nesting_state.stack), 0)
5366 self.UpdateWithLines(['class A {'])
5367 self.assertEquals(len(self.nesting_state.stack), 1)
5368 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5369 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5370
5371 self.UpdateWithLines(['};',
5372 'template <T,',
5373 ' template <typename, typename> class B>',
5374 'class C'])
5375 self.assertEquals(len(self.nesting_state.stack), 1)
5376 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5377 self.assertEquals(self.nesting_state.stack[0].name, 'C')
5378 self.UpdateWithLines([';'])
5379 self.assertEquals(len(self.nesting_state.stack), 0)
5380
5381 self.UpdateWithLines(['class D : public Tmpl<E>'])
5382 self.assertEquals(len(self.nesting_state.stack), 1)
5383 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5384 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5385
avakulenko@google.com02af6282014-06-04 18:53:25 +00005386 self.UpdateWithLines(['{', '};'])
5387 self.assertEquals(len(self.nesting_state.stack), 0)
5388
5389 self.UpdateWithLines(['template <class F,',
5390 ' class G,',
5391 ' class H,',
5392 ' typename I>',
5393 'static void Func() {'])
5394 self.assertEquals(len(self.nesting_state.stack), 1)
5395 self.assertFalse(isinstance(self.nesting_state.stack[0],
5396 cpplint._ClassInfo))
5397 self.UpdateWithLines(['}',
5398 'template <class J> class K {'])
5399 self.assertEquals(len(self.nesting_state.stack), 1)
5400 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5401 self.assertEquals(self.nesting_state.stack[0].name, 'K')
5402
erg@google.comfd5da632013-10-25 17:39:45 +00005403 def testTemplateInnerClass(self):
5404 self.UpdateWithLines(['class A {',
5405 ' public:'])
5406 self.assertEquals(len(self.nesting_state.stack), 1)
5407 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5408
5409 self.UpdateWithLines([' template <class B>',
5410 ' class C<alloc<B> >',
5411 ' : public A {'])
5412 self.assertEquals(len(self.nesting_state.stack), 2)
5413 self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5414
erg@google.comd350fe52013-01-14 17:51:48 +00005415 def testArguments(self):
5416 self.UpdateWithLines(['class A {'])
5417 self.assertEquals(len(self.nesting_state.stack), 1)
5418 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5419 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5420 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5421
5422 self.UpdateWithLines([' void Func(',
5423 ' struct X arg1,'])
5424 self.assertEquals(len(self.nesting_state.stack), 1)
5425 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5426 self.UpdateWithLines([' struct X *arg2);'])
5427 self.assertEquals(len(self.nesting_state.stack), 1)
5428 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5429
5430 self.UpdateWithLines(['};'])
5431 self.assertEquals(len(self.nesting_state.stack), 0)
5432
5433 self.UpdateWithLines(['struct B {'])
5434 self.assertEquals(len(self.nesting_state.stack), 1)
5435 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5436 self.assertEquals(self.nesting_state.stack[0].name, 'B')
5437
5438 self.UpdateWithLines(['#ifdef MACRO',
5439 ' void Func(',
5440 ' struct X arg1'])
5441 self.assertEquals(len(self.nesting_state.stack), 1)
5442 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5443 self.UpdateWithLines(['#else'])
5444
5445 self.assertEquals(len(self.nesting_state.stack), 1)
5446 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5447 self.UpdateWithLines([' void Func(',
5448 ' struct X arg1'])
5449 self.assertEquals(len(self.nesting_state.stack), 1)
5450 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5451
5452 self.UpdateWithLines(['#endif'])
5453 self.assertEquals(len(self.nesting_state.stack), 1)
5454 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5455 self.UpdateWithLines([' struct X *arg2);'])
5456 self.assertEquals(len(self.nesting_state.stack), 1)
5457 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5458
5459 self.UpdateWithLines(['};'])
5460 self.assertEquals(len(self.nesting_state.stack), 0)
5461
5462 def testInlineAssembly(self):
5463 self.UpdateWithLines(['void CopyRow_SSE2(const uint8* src, uint8* dst,',
5464 ' int count) {'])
5465 self.assertEquals(len(self.nesting_state.stack), 1)
5466 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5467 self.assertEquals(self.nesting_state.stack[-1].inline_asm, cpplint._NO_ASM)
5468
5469 self.UpdateWithLines([' asm volatile ('])
5470 self.assertEquals(len(self.nesting_state.stack), 1)
5471 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5472 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5473 cpplint._INSIDE_ASM)
5474
5475 self.UpdateWithLines([' "sub %0,%1 \\n"',
5476 ' "1: \\n"',
5477 ' "movdqa (%0),%%xmm0 \\n"',
5478 ' "movdqa 0x10(%0),%%xmm1 \\n"',
5479 ' "movdqa %%xmm0,(%0,%1) \\n"',
5480 ' "movdqa %%xmm1,0x10(%0,%1) \\n"',
5481 ' "lea 0x20(%0),%0 \\n"',
5482 ' "sub $0x20,%2 \\n"',
5483 ' "jg 1b \\n"',
5484 ' : "+r"(src), // %0',
5485 ' "+r"(dst), // %1',
5486 ' "+r"(count) // %2',
5487 ' :',
5488 ' : "memory", "cc"'])
5489 self.assertEquals(len(self.nesting_state.stack), 1)
5490 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5491 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5492 cpplint._INSIDE_ASM)
5493
5494 self.UpdateWithLines(['#if defined(__SSE2__)',
5495 ' , "xmm0", "xmm1"'])
5496 self.assertEquals(len(self.nesting_state.stack), 1)
5497 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5498 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5499 cpplint._INSIDE_ASM)
5500
5501 self.UpdateWithLines(['#endif'])
5502 self.assertEquals(len(self.nesting_state.stack), 1)
5503 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5504 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5505 cpplint._INSIDE_ASM)
5506
5507 self.UpdateWithLines([' );'])
5508 self.assertEquals(len(self.nesting_state.stack), 1)
5509 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5510 self.assertEquals(self.nesting_state.stack[-1].inline_asm, cpplint._END_ASM)
5511
5512 self.UpdateWithLines(['__asm {'])
5513 self.assertEquals(len(self.nesting_state.stack), 2)
5514 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5515 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5516 cpplint._BLOCK_ASM)
5517
5518 self.UpdateWithLines(['}'])
5519 self.assertEquals(len(self.nesting_state.stack), 1)
5520
5521 self.UpdateWithLines(['}'])
5522 self.assertEquals(len(self.nesting_state.stack), 0)
5523
erg+personal@google.com05189642010-04-30 20:43:03 +00005524
erg@google.coma868d2d2009-10-09 21:18:45 +00005525# pylint: disable-msg=C6409
5526def setUp():
erg@google.com8a95ecc2011-09-08 00:45:54 +00005527 """Runs before all tests are executed.
erg@google.coma868d2d2009-10-09 21:18:45 +00005528 """
5529 # Enable all filters, so we don't miss anything that is off by default.
5530 cpplint._DEFAULT_FILTERS = []
5531 cpplint._cpplint_state.SetFilters('')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005532
erg@google.coma868d2d2009-10-09 21:18:45 +00005533
5534# pylint: disable-msg=C6409
erg@google.com4e00b9a2009-01-12 23:05:11 +00005535def tearDown():
5536 """A global check to make sure all error-categories have been tested.
5537
5538 The main tearDown() routine is the only code we can guarantee will be
5539 run after all other tests have been executed.
5540 """
5541 try:
5542 if _run_verifyallcategoriesseen:
5543 ErrorCollector(None).VerifyAllCategoriesAreSeen()
5544 except NameError:
5545 # If nobody set the global _run_verifyallcategoriesseen, then
avakulenko@google.com554223d2014-12-04 22:00:20 +00005546 # we assume we should silently not run the test
erg@google.com4e00b9a2009-01-12 23:05:11 +00005547 pass
5548
erg@google.coma868d2d2009-10-09 21:18:45 +00005549
erg@google.com4e00b9a2009-01-12 23:05:11 +00005550if __name__ == '__main__':
erg@google.com4e00b9a2009-01-12 23:05:11 +00005551 # We don't want to run the VerifyAllCategoriesAreSeen() test unless
5552 # we're running the full test suite: if we only run one test,
5553 # obviously we're not going to see all the error categories. So we
5554 # only run VerifyAllCategoriesAreSeen() when no commandline flags
5555 # are passed in.
5556 global _run_verifyallcategoriesseen
5557 _run_verifyallcategoriesseen = (len(sys.argv) == 1)
5558
erg@google.coma868d2d2009-10-09 21:18:45 +00005559 setUp()
erg@google.com4e00b9a2009-01-12 23:05:11 +00005560 unittest.main()
erg@google.coma868d2d2009-10-09 21:18:45 +00005561 tearDown()