blob: aaa3b24c67e06c417da3adfc8bb25e1394167605 [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
293 def testFalsePositivesNoError(self):
294 lines = ['namespace Test {',
295 'struct OuterClass {',
296 ' struct NoFalsePositivesHere;',
297 ' struct NoFalsePositivesHere member_variable;',
298 '};',
299 '} // namespace Test']
300
301 results = self.GetNamespaceResults(lines)
302 self.assertEquals(results, '')
303
304
erg@google.com4e00b9a2009-01-12 23:05:11 +0000305 # Test get line width.
306 def testGetLineWidth(self):
307 self.assertEquals(0, cpplint.GetLineWidth(''))
308 self.assertEquals(10, cpplint.GetLineWidth(u'x' * 10))
309 self.assertEquals(16, cpplint.GetLineWidth(u'都|道|府|県|支庁'))
310
erg@google.com8a95ecc2011-09-08 00:45:54 +0000311 def testGetTextInside(self):
312 self.assertEquals('', cpplint._GetTextInside('fun()', r'fun\('))
313 self.assertEquals('x, y', cpplint._GetTextInside('f(x, y)', r'f\('))
314 self.assertEquals('a(), b(c())', cpplint._GetTextInside(
315 'printf(a(), b(c()))', r'printf\('))
316 self.assertEquals('x, y{}', cpplint._GetTextInside('f[x, y{}]', r'f\['))
317 self.assertEquals(None, cpplint._GetTextInside('f[a, b(}]', r'f\['))
318 self.assertEquals(None, cpplint._GetTextInside('f[x, y]', r'f\('))
319 self.assertEquals('y, h(z, (a + b))', cpplint._GetTextInside(
320 'f(x, g(y, h(z, (a + b))))', r'g\('))
321 self.assertEquals('f(f(x))', cpplint._GetTextInside('f(f(f(x)))', r'f\('))
322 # Supports multiple lines.
323 self.assertEquals('\n return loop(x);\n',
324 cpplint._GetTextInside(
325 'int loop(int x) {\n return loop(x);\n}\n', r'\{'))
avakulenko@google.com02af6282014-06-04 18:53:25 +0000326 # '^' matches the beginning of each line.
erg@google.com8a95ecc2011-09-08 00:45:54 +0000327 self.assertEquals('x, y',
328 cpplint._GetTextInside(
329 '#include "inl.h" // skip #define\n'
330 '#define A2(x, y) a_inl_(x, y, __LINE__)\n'
331 '#define A(x) a_inl_(x, "", __LINE__)\n',
332 r'^\s*#define\s*\w+\('))
333
erg@google.com4e00b9a2009-01-12 23:05:11 +0000334 def testFindNextMultiLineCommentStart(self):
335 self.assertEquals(1, cpplint.FindNextMultiLineCommentStart([''], 0))
336
337 lines = ['a', 'b', '/* c']
338 self.assertEquals(2, cpplint.FindNextMultiLineCommentStart(lines, 0))
339
340 lines = ['char a[] = "/*";'] # not recognized as comment.
341 self.assertEquals(1, cpplint.FindNextMultiLineCommentStart(lines, 0))
342
343 def testFindNextMultiLineCommentEnd(self):
344 self.assertEquals(1, cpplint.FindNextMultiLineCommentEnd([''], 0))
345 lines = ['a', 'b', ' c */']
346 self.assertEquals(2, cpplint.FindNextMultiLineCommentEnd(lines, 0))
347
348 def testRemoveMultiLineCommentsFromRange(self):
349 lines = ['a', ' /* comment ', ' * still comment', ' comment */ ', 'b']
350 cpplint.RemoveMultiLineCommentsFromRange(lines, 1, 4)
avakulenko@google.com554223d2014-12-04 22:00:20 +0000351 self.assertEquals(['a', '/**/', '/**/', '/**/', 'b'], lines)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000352
353 def testSpacesAtEndOfLine(self):
354 self.TestLint(
355 '// Hello there ',
356 'Line ends in whitespace. Consider deleting these extra spaces.'
357 ' [whitespace/end_of_line] [4]')
358
359 # Test line length check.
360 def testLineLengthCheck(self):
361 self.TestLint(
362 '// Hello',
363 '')
364 self.TestLint(
365 '// ' + 'x' * 80,
366 'Lines should be <= 80 characters long'
367 ' [whitespace/line_length] [2]')
368 self.TestLint(
369 '// ' + 'x' * 100,
370 'Lines should very rarely be longer than 100 characters'
371 ' [whitespace/line_length] [4]')
erg@google.coma87abb82009-02-24 01:41:01 +0000372 self.TestLint(
373 '// http://g' + ('o' * 100) + 'gle.com/',
374 '')
375 self.TestLint(
376 '// https://g' + ('o' * 100) + 'gle.com/',
377 '')
378 self.TestLint(
379 '// https://g' + ('o' * 60) + 'gle.com/ and some comments',
380 'Lines should be <= 80 characters long'
381 ' [whitespace/line_length] [2]')
erg@google.com36649102009-03-25 21:18:36 +0000382 self.TestLint(
avakulenko@google.com554223d2014-12-04 22:00:20 +0000383 '// Read https://g' + ('o' * 60) + 'gle.com/',
erg@google.com36649102009-03-25 21:18:36 +0000384 '')
erg@google.comd7d27472011-09-07 17:36:35 +0000385 self.TestLint(
386 '// $Id: g' + ('o' * 80) + 'gle.cc#1 $',
387 '')
388 self.TestLint(
389 '// $Id: g' + ('o' * 80) + 'gle.cc#1',
390 'Lines should be <= 80 characters long'
391 ' [whitespace/line_length] [2]')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000392 self.TestMultiLineLint(
393 'static const char kCStr[] = "g' + ('o' * 50) + 'gle";\n',
394 'Lines should be <= 80 characters long'
395 ' [whitespace/line_length] [2]')
396 self.TestMultiLineLint(
397 'static const char kRawStr[] = R"(g' + ('o' * 50) + 'gle)";\n',
398 '') # no warning because raw string content is elided
399 self.TestMultiLineLint(
400 'static const char kMultiLineRawStr[] = R"(\n'
401 'g' + ('o' * 80) + 'gle\n'
402 ')";',
403 '')
404 self.TestMultiLineLint(
405 'static const char kL' + ('o' * 50) + 'ngIdentifier[] = R"()";\n',
406 'Lines should be <= 80 characters long'
407 ' [whitespace/line_length] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000408
erg+personal@google.com05189642010-04-30 20:43:03 +0000409 # Test error suppression annotations.
410 def testErrorSuppression(self):
411 # Two errors on same line:
412 self.TestLint(
413 'long a = (int64) 65;',
414 ['Using C-style cast. Use static_cast<int64>(...) instead'
415 ' [readability/casting] [4]',
416 'Use int16/int64/etc, rather than the C type long'
417 ' [runtime/int] [4]',
erg@google.com8a95ecc2011-09-08 00:45:54 +0000418 ])
erg+personal@google.com05189642010-04-30 20:43:03 +0000419 # One category of error suppressed:
420 self.TestLint(
421 'long a = (int64) 65; // NOLINT(runtime/int)',
422 'Using C-style cast. Use static_cast<int64>(...) instead'
423 ' [readability/casting] [4]')
424 # All categories suppressed: (two aliases)
425 self.TestLint('long a = (int64) 65; // NOLINT', '')
426 self.TestLint('long a = (int64) 65; // NOLINT(*)', '')
427 # Malformed NOLINT directive:
428 self.TestLint(
429 'long a = 65; // NOLINT(foo)',
erg@google.com8a95ecc2011-09-08 00:45:54 +0000430 ['Unknown NOLINT error category: foo'
431 ' [readability/nolint] [5]',
432 'Use int16/int64/etc, rather than the C type long [runtime/int] [4]',
433 ])
erg+personal@google.com05189642010-04-30 20:43:03 +0000434 # Irrelevant NOLINT directive has no effect:
435 self.TestLint(
436 'long a = 65; // NOLINT(readability/casting)',
erg@google.com8a95ecc2011-09-08 00:45:54 +0000437 'Use int16/int64/etc, rather than the C type long'
avakulenko@google.com02af6282014-06-04 18:53:25 +0000438 ' [runtime/int] [4]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000439 # NOLINTNEXTLINE silences warning for the next line instead of current line
440 error_collector = ErrorCollector(self.assert_)
441 cpplint.ProcessFileData('test.cc', 'cc',
442 ['// Copyright 2014 Your Company.',
443 '// NOLINTNEXTLINE(whitespace/line_length)',
444 '// ./command' + (' -verbose' * 80),
445 ''],
446 error_collector)
447 self.assertEquals('', error_collector.Results())
erg+personal@google.com05189642010-04-30 20:43:03 +0000448
erg@google.com4e00b9a2009-01-12 23:05:11 +0000449 # Test Variable Declarations.
450 def testVariableDeclarations(self):
451 self.TestLint(
452 'long a = 65;',
453 'Use int16/int64/etc, rather than the C type long'
454 ' [runtime/int] [4]')
455 self.TestLint(
456 'long double b = 65.0;',
457 '')
458 self.TestLint(
459 'long long aa = 6565;',
460 'Use int16/int64/etc, rather than the C type long'
461 ' [runtime/int] [4]')
462
463 # Test C-style cast cases.
464 def testCStyleCast(self):
465 self.TestLint(
466 'int a = (int)1.0;',
467 'Using C-style cast. Use static_cast<int>(...) instead'
468 ' [readability/casting] [4]')
469 self.TestLint(
avakulenko@google.com554223d2014-12-04 22:00:20 +0000470 'int a = (int)-1.0;',
471 'Using C-style cast. Use static_cast<int>(...) instead'
472 ' [readability/casting] [4]')
473 self.TestLint(
erg@google.com8f91ab22011-09-06 21:04:45 +0000474 'int *a = (int *)NULL;',
erg@google.com4e00b9a2009-01-12 23:05:11 +0000475 'Using C-style cast. Use reinterpret_cast<int *>(...) instead'
476 ' [readability/casting] [4]')
477
478 self.TestLint(
479 'uint16 a = (uint16)1.0;',
480 'Using C-style cast. Use static_cast<uint16>(...) instead'
481 ' [readability/casting] [4]')
482 self.TestLint(
483 'int32 a = (int32)1.0;',
484 'Using C-style cast. Use static_cast<int32>(...) instead'
485 ' [readability/casting] [4]')
486 self.TestLint(
487 'uint64 a = (uint64)1.0;',
488 'Using C-style cast. Use static_cast<uint64>(...) instead'
489 ' [readability/casting] [4]')
490
491 # These shouldn't be recognized casts.
492 self.TestLint('u a = (u)NULL;', '')
493 self.TestLint('uint a = (uint)NULL;', '')
erg@google.comc6671232013-10-25 21:44:03 +0000494 self.TestLint('typedef MockCallback<int(int)> CallbackType;', '')
495 self.TestLint('scoped_ptr< MockCallback<int(int)> > callback_value;', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000496 self.TestLint('std::function<int(bool)>', '')
497 self.TestLint('x = sizeof(int)', '')
498 self.TestLint('x = alignof(int)', '')
499 self.TestLint('alignas(int) char x[42]', '')
500 self.TestLint('alignas(alignof(x)) char y[42]', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +0000501 self.TestLint('void F(int (func)(int));', '')
502 self.TestLint('void F(int (func)(int*));', '')
503 self.TestLint('void F(int (Class::member)(int));', '')
504 self.TestLint('void F(int (Class::member)(int*));', '')
505 self.TestLint('void F(int (Class::member)(int), int param);', '')
506 self.TestLint('void F(int (Class::member)(int*), int param);', '')
507
508 # These should not be recognized (lambda functions without arg names).
509 self.TestLint('[](int/*unused*/) -> bool {', '')
510 self.TestLint('[](int /*unused*/) -> bool {', '')
511 self.TestLint('auto f = [](MyStruct* /*unused*/)->int {', '')
512 self.TestLint(
513 '[](int) -> bool {',
514 'All parameters should be named in a function'
515 ' [readability/function] [3]')
516 self.TestLint(
517 'auto f = [](MyStruct*)->int {',
518 'All parameters should be named in a function'
519 ' [readability/function] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000520
521 # Test taking address of casts (runtime/casting)
522 def testRuntimeCasting(self):
erg@google.comc6671232013-10-25 21:44:03 +0000523 error_msg = ('Are you taking an address of a cast? '
524 'This is dangerous: could be a temp var. '
525 'Take the address before doing the cast, rather than after'
526 ' [runtime/casting] [4]')
527 self.TestLint('int* x = &static_cast<int*>(foo);', error_msg)
528 self.TestLint('int* x = &reinterpret_cast<int *>(foo);', error_msg)
529 self.TestLint('int* x = &(int*)foo;',
530 ['Using C-style cast. Use reinterpret_cast<int*>(...) '
531 'instead [readability/casting] [4]',
532 error_msg])
avakulenko@google.com554223d2014-12-04 22:00:20 +0000533 self.TestLint('BudgetBuckets&(BudgetWinHistory::*BucketFn)(void) const;',
534 '')
535 self.TestLint('&(*func_ptr)(arg)', '')
536 self.TestLint('Compute(arg, &(*func_ptr)(i, j));', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000537
avakulenko@google.com02af6282014-06-04 18:53:25 +0000538 # Alternative error message
539 alt_error_msg = ('Are you taking an address of something dereferenced '
540 'from a cast? Wrapping the dereferenced expression in '
541 'parentheses will make the binding more obvious'
542 ' [readability/casting] [4]')
543 self.TestLint('int* x = &down_cast<Obj*>(obj)->member_;', alt_error_msg)
544 self.TestLint('int* x = &down_cast<Obj*>(obj)[index];', alt_error_msg)
545 self.TestLint('int* x = &(down_cast<Obj*>(obj)->member_);', '')
546 self.TestLint('int* x = &(down_cast<Obj*>(obj)[index]);', '')
547 self.TestLint('int* x = &down_cast<Obj*>(obj)\n->member_;', alt_error_msg)
548 self.TestLint('int* x = &(down_cast<Obj*>(obj)\n->member_);', '')
549
erg@google.com4e00b9a2009-01-12 23:05:11 +0000550 # It's OK to cast an address.
erg@google.comc6671232013-10-25 21:44:03 +0000551 self.TestLint('int* x = reinterpret_cast<int *>(&foo);', '')
552
553 # Function pointers returning references should not be confused
554 # with taking address of old-style casts.
555 self.TestLint('auto x = implicit_cast<string &(*)(int)>(&foo);', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000556
557 def testRuntimeSelfinit(self):
558 self.TestLint(
559 'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }',
560 'You seem to be initializing a member variable with itself.'
561 ' [runtime/init] [4]')
562 self.TestLint(
563 'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }',
564 '')
565 self.TestLint(
566 'Foo::Foo(Bar r) : r_(r), l_(r_), ll_(l_) { }',
567 '')
568
erg@google.com4e00b9a2009-01-12 23:05:11 +0000569 # Test for unnamed arguments in a method.
570 def testCheckForUnnamedParams(self):
571 message = ('All parameters should be named in a function'
572 ' [readability/function] [3]')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000573 self.TestLint('virtual void Func(int*) const;', message)
574 self.TestLint('virtual void Func(int*);', message)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000575 self.TestLint('void Method(char*) {', message)
576 self.TestLint('void Method(char*);', message)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000577 self.TestLint('static void operator delete[](void*) throw();', message)
avakulenko@google.com02af6282014-06-04 18:53:25 +0000578 self.TestLint('int Method(int);', message)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000579
avakulenko@google.com02af6282014-06-04 18:53:25 +0000580 self.TestLint('virtual void Func(int* p);', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000581 self.TestLint('void operator delete(void* x) throw();', '')
582 self.TestLint('void Method(char* x) {', '')
583 self.TestLint('void Method(char* /*x*/) {', '')
584 self.TestLint('void Method(char* x);', '')
585 self.TestLint('typedef void (*Method)(int32 x);', '')
586 self.TestLint('static void operator delete[](void* x) throw();', '')
587 self.TestLint('static void operator delete[](void* /*x*/) throw();', '')
588
erg@google.comd350fe52013-01-14 17:51:48 +0000589 self.TestLint('X operator++(int);', '')
590 self.TestLint('X operator++(int) {', '')
591 self.TestLint('X operator--(int);', '')
592 self.TestLint('X operator--(int /*unused*/) {', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000593 self.TestLint('MACRO(int);', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +0000594 self.TestLint('MACRO(func(int));', '')
595 self.TestLint('MACRO(arg, func(int));', '')
erg@google.comd350fe52013-01-14 17:51:48 +0000596
erg@google.comc6671232013-10-25 21:44:03 +0000597 self.TestLint('void (*func)(void*);', '')
598 self.TestLint('void Func((*func)(void*)) {}', '')
599 self.TestLint('template <void Func(void*)> void func();', '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000600 self.TestLint('virtual void f(int /*unused*/) {', '')
601 self.TestLint('void f(int /*unused*/) override {', '')
602 self.TestLint('void f(int /*unused*/) final {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000603
604 # Test deprecated casts such as int(d)
605 def testDeprecatedCast(self):
606 self.TestLint(
607 'int a = int(2.2);',
608 'Using deprecated casting style. '
609 'Use static_cast<int>(...) instead'
610 ' [readability/casting] [4]')
erg@google.com8a95ecc2011-09-08 00:45:54 +0000611
612 self.TestLint(
613 '(char *) "foo"',
614 'Using C-style cast. '
615 'Use const_cast<char *>(...) instead'
616 ' [readability/casting] [4]')
617
618 self.TestLint(
619 '(int*)foo',
620 'Using C-style cast. '
621 'Use reinterpret_cast<int*>(...) instead'
622 ' [readability/casting] [4]')
623
erg@google.com4e00b9a2009-01-12 23:05:11 +0000624 # Checks for false positives...
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000625 self.TestLint('int a = int();', '') # constructor
626 self.TestLint('X::X() : a(int()) {}', '') # default constructor
627 self.TestLint('operator bool();', '') # Conversion operator
628 self.TestLint('new int64(123);', '') # "new" operator on basic type
629 self.TestLint('new int64(123);', '') # "new" operator on basic type
630 self.TestLint('using a = bool(int arg);', '') # C++11 alias-declaration
631 self.TestLint('x = bit_cast<double(*)[3]>(y);', '') # array of array
632 self.TestLint('void F(const char(&src)[N]);', '') # array of references
633
634 # Placement new
avakulenko@google.com02af6282014-06-04 18:53:25 +0000635 self.TestLint(
636 'new(field_ptr) int(field->default_value_enum()->number());',
637 '')
638
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000639 # C++11 function wrappers
640 self.TestLint('std::function<int(bool)>', '')
641 self.TestLint('std::function<const int(bool)>', '')
642 self.TestLint('std::function< int(bool) >', '')
643 self.TestLint('mfunction<int(bool)>', '')
644
avakulenko@google.com02af6282014-06-04 18:53:25 +0000645 error_collector = ErrorCollector(self.assert_)
646 cpplint.ProcessFileData(
647 'test.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000648 ['// Copyright 2014 Your Company. All Rights Reserved.',
avakulenko@google.com02af6282014-06-04 18:53:25 +0000649 'typedef std::function<',
650 ' bool(int)> F;',
651 ''],
652 error_collector)
653 self.assertEquals('', error_collector.Results())
erg@google.comc6671232013-10-25 21:44:03 +0000654
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000655 # Return types for function pointers
656 self.TestLint('typedef bool(FunctionPointer)();', '')
657 self.TestLint('typedef bool(FunctionPointer)(int param);', '')
658 self.TestLint('typedef bool(MyClass::*MemberFunctionPointer)();', '')
659 self.TestLint('typedef bool(MyClass::* MemberFunctionPointer)();', '')
660 self.TestLint('typedef bool(MyClass::*MemberFunctionPointer)() const;', '')
661 self.TestLint('void Function(bool(FunctionPointerArg)());', '')
662 self.TestLint('void Function(bool(FunctionPointerArg)()) {}', '')
663 self.TestLint('typedef set<int64, bool(*)(int64, int64)> SortedIdSet', '')
erg@google.comc6671232013-10-25 21:44:03 +0000664 self.TestLint(
665 'bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *t)) {}',
666 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000667
668 # The second parameter to a gMock method definition is a function signature
669 # that often looks like a bad cast but should not picked up by lint.
670 def testMockMethod(self):
671 self.TestLint(
672 'MOCK_METHOD0(method, int());',
673 '')
674 self.TestLint(
675 'MOCK_CONST_METHOD1(method, float(string));',
676 '')
677 self.TestLint(
678 'MOCK_CONST_METHOD2_T(method, double(float, float));',
679 '')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000680 self.TestLint(
681 'MOCK_CONST_METHOD1(method, SomeType(int));',
682 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000683
erg@google.comd350fe52013-01-14 17:51:48 +0000684 error_collector = ErrorCollector(self.assert_)
685 cpplint.ProcessFileData('mock.cc', 'cc',
686 ['MOCK_METHOD1(method1,',
erg@google.comc6671232013-10-25 21:44:03 +0000687 ' bool(int));',
688 'MOCK_METHOD1(',
689 ' method2,',
690 ' bool(int));',
691 'MOCK_CONST_METHOD2(',
692 ' method3, bool(int,',
693 ' int));',
694 'MOCK_METHOD1(method4, int(bool));',
erg@google.comd350fe52013-01-14 17:51:48 +0000695 'const int kConstant = int(42);'], # true positive
696 error_collector)
697 self.assertEquals(
698 0,
699 error_collector.Results().count(
700 ('Using deprecated casting style. '
701 'Use static_cast<bool>(...) instead '
702 '[readability/casting] [4]')))
703 self.assertEquals(
704 1,
705 error_collector.Results().count(
706 ('Using deprecated casting style. '
707 'Use static_cast<int>(...) instead '
708 '[readability/casting] [4]')))
709
erg@google.comd7d27472011-09-07 17:36:35 +0000710 # Like gMock method definitions, MockCallback instantiations look very similar
711 # to bad casts.
712 def testMockCallback(self):
713 self.TestLint(
714 'MockCallback<bool(int)>',
715 '')
716 self.TestLint(
717 'MockCallback<int(float, char)>',
718 '')
719
erg@google.come35f7652009-06-19 20:52:09 +0000720 # Test false errors that happened with some include file names
721 def testIncludeFilenameFalseError(self):
722 self.TestLint(
723 '#include "foo/long-foo.h"',
724 '')
725 self.TestLint(
726 '#include "foo/sprintf.h"',
727 '')
728
erg@google.com4e00b9a2009-01-12 23:05:11 +0000729 # Test typedef cases. There was a bug that cpplint misidentified
730 # typedef for pointer to function as C-style cast and produced
731 # false-positive error messages.
732 def testTypedefForPointerToFunction(self):
733 self.TestLint(
734 'typedef void (*Func)(int x);',
735 '')
736 self.TestLint(
737 'typedef void (*Func)(int *x);',
738 '')
739 self.TestLint(
740 'typedef void Func(int x);',
741 '')
742 self.TestLint(
743 'typedef void Func(int *x);',
744 '')
745
746 def testIncludeWhatYouUseNoImplementationFiles(self):
747 code = 'std::vector<int> foo;'
748 self.assertEquals('Add #include <vector> for vector<>'
749 ' [build/include_what_you_use] [4]',
750 self.PerformIncludeWhatYouUse(code, 'foo.h'))
751 self.assertEquals('',
752 self.PerformIncludeWhatYouUse(code, 'foo.cc'))
753
754 def testIncludeWhatYouUse(self):
755 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000756 """#include <vector>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000757 std::vector<int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000758 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000759 '')
760 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000761 """#include <map>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000762 std::pair<int,int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000763 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000764 'Add #include <utility> for pair<>'
765 ' [build/include_what_you_use] [4]')
766 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000767 """#include <multimap>
768 std::pair<int,int> foo;
769 """,
770 'Add #include <utility> for pair<>'
771 ' [build/include_what_you_use] [4]')
772 self.TestIncludeWhatYouUse(
773 """#include <hash_map>
774 std::pair<int,int> foo;
775 """,
776 'Add #include <utility> for pair<>'
777 ' [build/include_what_you_use] [4]')
778 self.TestIncludeWhatYouUse(
779 """#include <utility>
780 std::pair<int,int> foo;
781 """,
782 '')
783 self.TestIncludeWhatYouUse(
784 """#include <vector>
785 DECLARE_string(foobar);
786 """,
787 '')
788 self.TestIncludeWhatYouUse(
789 """#include <vector>
790 DEFINE_string(foobar, "", "");
791 """,
792 '')
793 self.TestIncludeWhatYouUse(
794 """#include <vector>
795 std::pair<int,int> foo;
796 """,
797 'Add #include <utility> for pair<>'
798 ' [build/include_what_you_use] [4]')
799 self.TestIncludeWhatYouUse(
800 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000801 std::vector<int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000802 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000803 'Add #include <vector> for vector<>'
804 ' [build/include_what_you_use] [4]')
805 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000806 """#include <vector>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000807 std::set<int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000808 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000809 'Add #include <set> for set<>'
810 ' [build/include_what_you_use] [4]')
811 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000812 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000813 hash_map<int, int> foobar;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000814 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000815 'Add #include <hash_map> for hash_map<>'
816 ' [build/include_what_you_use] [4]')
817 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000818 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000819 bool foobar = std::less<int>(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000820 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000821 'Add #include <functional> for less<>'
822 ' [build/include_what_you_use] [4]')
823 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000824 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000825 bool foobar = min<int>(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000826 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000827 'Add #include <algorithm> for min [build/include_what_you_use] [4]')
828 self.TestIncludeWhatYouUse(
829 'void a(const string &foobar);',
830 'Add #include <string> for string [build/include_what_you_use] [4]')
831 self.TestIncludeWhatYouUse(
erg+personal@google.com05189642010-04-30 20:43:03 +0000832 'void a(const std::string &foobar);',
833 'Add #include <string> for string [build/include_what_you_use] [4]')
834 self.TestIncludeWhatYouUse(
835 'void a(const my::string &foobar);',
836 '') # Avoid false positives on strings in other namespaces.
837 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000838 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000839 bool foobar = swap(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000840 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000841 'Add #include <algorithm> for swap [build/include_what_you_use] [4]')
842 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000843 """#include "base/foobar.h"
erg@google.coma87abb82009-02-24 01:41:01 +0000844 bool foobar = transform(a.begin(), a.end(), b.start(), Foo);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000845 """,
erg@google.coma87abb82009-02-24 01:41:01 +0000846 'Add #include <algorithm> for transform '
847 '[build/include_what_you_use] [4]')
848 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000849 """#include "base/foobar.h"
erg@google.coma87abb82009-02-24 01:41:01 +0000850 bool foobar = min_element(a.begin(), a.end());
erg@google.com8a95ecc2011-09-08 00:45:54 +0000851 """,
erg@google.coma87abb82009-02-24 01:41:01 +0000852 'Add #include <algorithm> for min_element '
853 '[build/include_what_you_use] [4]')
854 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000855 """foo->swap(0,1);
erg@google.com4e00b9a2009-01-12 23:05:11 +0000856 foo.swap(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000857 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000858 '')
859 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000860 """#include <string>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000861 void a(const std::multimap<int,string> &foobar);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000862 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000863 'Add #include <map> for multimap<>'
864 ' [build/include_what_you_use] [4]')
865 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000866 """#include <queue>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000867 void a(const std::priority_queue<int> &foobar);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000868 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000869 '')
870 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000871 """#include <assert.h>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000872 #include <string>
873 #include <vector>
874 #include "base/basictypes.h"
875 #include "base/port.h"
erg@google.com8a95ecc2011-09-08 00:45:54 +0000876 vector<string> hajoa;""", '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000877 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000878 """#include <string>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000879 int i = numeric_limits<int>::max()
erg@google.com8a95ecc2011-09-08 00:45:54 +0000880 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000881 'Add #include <limits> for numeric_limits<>'
882 ' [build/include_what_you_use] [4]')
883 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000884 """#include <limits>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000885 int i = numeric_limits<int>::max()
erg@google.com8a95ecc2011-09-08 00:45:54 +0000886 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000887 '')
888
erg@google.come35f7652009-06-19 20:52:09 +0000889 # Test the UpdateIncludeState code path.
890 mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"']
891 message = self.PerformIncludeWhatYouUse(
892 '#include "blah/a.h"',
893 filename='blah/a.cc',
894 io=MockIo(mock_header_contents))
895 self.assertEquals(message, '')
896
897 mock_header_contents = ['#include <set>']
898 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000899 """#include "blah/a.h"
900 std::set<int> foo;""",
erg@google.come35f7652009-06-19 20:52:09 +0000901 filename='blah/a.cc',
902 io=MockIo(mock_header_contents))
903 self.assertEquals(message, '')
904
905 # Make sure we can find the correct header file if the cc file seems to be
906 # a temporary file generated by Emacs's flymake.
907 mock_header_contents = ['']
908 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000909 """#include "blah/a.h"
910 std::set<int> foo;""",
erg@google.come35f7652009-06-19 20:52:09 +0000911 filename='blah/a_flymake.cc',
912 io=MockIo(mock_header_contents))
913 self.assertEquals(message, 'Add #include <set> for set<> '
erg@google.com8a95ecc2011-09-08 00:45:54 +0000914 '[build/include_what_you_use] [4]')
erg@google.come35f7652009-06-19 20:52:09 +0000915
916 # If there's just a cc and the header can't be found then it's ok.
917 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000918 """#include "blah/a.h"
919 std::set<int> foo;""",
erg@google.come35f7652009-06-19 20:52:09 +0000920 filename='blah/a.cc')
921 self.assertEquals(message, '')
922
923 # Make sure we find the headers with relative paths.
924 mock_header_contents = ['']
925 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000926 """#include "%s/a.h"
927 std::set<int> foo;""" % os.path.basename(os.getcwd()),
erg@google.come35f7652009-06-19 20:52:09 +0000928 filename='a.cc',
929 io=MockIo(mock_header_contents))
930 self.assertEquals(message, 'Add #include <set> for set<> '
erg@google.com8a95ecc2011-09-08 00:45:54 +0000931 '[build/include_what_you_use] [4]')
erg@google.come35f7652009-06-19 20:52:09 +0000932
933 def testFilesBelongToSameModule(self):
934 f = cpplint.FilesBelongToSameModule
935 self.assertEquals((True, ''), f('a.cc', 'a.h'))
936 self.assertEquals((True, ''), f('base/google.cc', 'base/google.h'))
937 self.assertEquals((True, ''), f('base/google_test.cc', 'base/google.h'))
938 self.assertEquals((True, ''),
939 f('base/google_unittest.cc', 'base/google.h'))
940 self.assertEquals((True, ''),
941 f('base/internal/google_unittest.cc',
942 'base/public/google.h'))
943 self.assertEquals((True, 'xxx/yyy/'),
944 f('xxx/yyy/base/internal/google_unittest.cc',
945 'base/public/google.h'))
946 self.assertEquals((True, 'xxx/yyy/'),
947 f('xxx/yyy/base/google_unittest.cc',
948 'base/public/google.h'))
949 self.assertEquals((True, ''),
950 f('base/google_unittest.cc', 'base/google-inl.h'))
951 self.assertEquals((True, '/home/build/google3/'),
952 f('/home/build/google3/base/google.cc', 'base/google.h'))
953
954 self.assertEquals((False, ''),
955 f('/home/build/google3/base/google.cc', 'basu/google.h'))
956 self.assertEquals((False, ''), f('a.cc', 'b.h'))
957
erg@google.com4e00b9a2009-01-12 23:05:11 +0000958 def testCleanseLine(self):
erg@google.comd7d27472011-09-07 17:36:35 +0000959 self.assertEquals('int foo = 0;',
erg@google.com4e00b9a2009-01-12 23:05:11 +0000960 cpplint.CleanseComments('int foo = 0; // danger!'))
961 self.assertEquals('int o = 0;',
962 cpplint.CleanseComments('int /* foo */ o = 0;'))
963 self.assertEquals('foo(int a, int b);',
964 cpplint.CleanseComments('foo(int a /* abc */, int b);'))
965 self.assertEqual('f(a, b);',
966 cpplint.CleanseComments('f(a, /* name */ b);'))
967 self.assertEqual('f(a, b);',
erg@google.com2aa59982013-10-28 19:09:25 +0000968 cpplint.CleanseComments('f(a /* name */, b);'))
erg@google.com4e00b9a2009-01-12 23:05:11 +0000969 self.assertEqual('f(a, b);',
970 cpplint.CleanseComments('f(a, /* name */b);'))
avakulenko@google.com02af6282014-06-04 18:53:25 +0000971 self.assertEqual('f(a, b, c);',
972 cpplint.CleanseComments('f(a, /**/b, /**/c);'))
973 self.assertEqual('f(a, b, c);',
974 cpplint.CleanseComments('f(a, /**/b/**/, c);'))
erg@google.com4e00b9a2009-01-12 23:05:11 +0000975
erg@google.com2aa59982013-10-28 19:09:25 +0000976 def testRawStrings(self):
977 self.TestMultiLineLint(
978 """
979 void Func() {
980 static const char kString[] = R"(
981 #endif <- invalid preprocessor should be ignored
982 */ <- invalid comment should be ignored too
983 )";
984 }""",
985 '')
986 self.TestMultiLineLint(
987 """
988 void Func() {
989 string s = R"TrueDelimiter(
990 )"
991 )FalseDelimiter"
992 )TrueDelimiter";
993 }""",
994 '')
995 self.TestMultiLineLint(
996 """
997 void Func() {
998 char char kString[] = R"( ";" )";
999 }""",
1000 '')
1001 self.TestMultiLineLint(
1002 """
1003 static const char kRawString[] = R"(
1004 \tstatic const int kLineWithTab = 1;
1005 static const int kLineWithTrailingWhiteSpace = 1;\x20
1006
1007 void WeirdNumberOfSpacesAtLineStart() {
1008 string x;
1009 x += StrCat("Use StrAppend instead");
1010 }
1011
1012 void BlankLineAtEndOfBlock() {
1013 // TODO incorrectly formatted
1014 //Badly formatted comment
1015
1016 }
1017
1018 )";""",
1019 '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00001020 self.TestMultiLineLint(
1021 """
1022 void Func() {
1023 string s = StrCat(R"TrueDelimiter(
1024 )"
1025 )FalseDelimiter"
1026 )TrueDelimiter", R"TrueDelimiter2(
1027 )"
1028 )FalseDelimiter2"
1029 )TrueDelimiter2");
1030 }""",
1031 '')
1032 self.TestMultiLineLint(
1033 """
1034 static SomeStruct kData = {
1035 {0, R"(line1
1036 line2
1037 )"}
1038 };""",
1039 '')
erg@google.com2aa59982013-10-28 19:09:25 +00001040
erg@google.com4e00b9a2009-01-12 23:05:11 +00001041 def testMultiLineComments(self):
1042 # missing explicit is bad
1043 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001044 r"""int a = 0;
erg@google.com4e00b9a2009-01-12 23:05:11 +00001045 /* multi-liner
1046 class Foo {
1047 Foo(int f); // should cause a lint warning in code
1048 }
erg@google.com8a95ecc2011-09-08 00:45:54 +00001049 */ """,
erg@google.com4e00b9a2009-01-12 23:05:11 +00001050 '')
1051 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001052 r"""/* int a = 0; multi-liner
1053 static const int b = 0;""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001054 'Could not find end of multi-line comment'
1055 ' [readability/multiline_comment] [5]')
erg@google.com8a95ecc2011-09-08 00:45:54 +00001056 self.TestMultiLineLint(r""" /* multi-line comment""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001057 'Could not find end of multi-line comment'
1058 ' [readability/multiline_comment] [5]')
erg@google.com8a95ecc2011-09-08 00:45:54 +00001059 self.TestMultiLineLint(r""" // /* comment, but not multi-line""", '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001060 self.TestMultiLineLint(r"""/**********
1061 */""", '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00001062 self.TestMultiLineLint(r"""/**
1063 * Doxygen comment
1064 */""",
1065 '')
1066 self.TestMultiLineLint(r"""/*!
1067 * Doxygen comment
1068 */""",
1069 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001070
1071 def testMultilineStrings(self):
1072 multiline_string_error_message = (
1073 'Multi-line string ("...") found. This lint script doesn\'t '
erg@google.com2aa59982013-10-28 19:09:25 +00001074 'do well with such strings, and may give bogus warnings. '
1075 'Use C++11 raw strings or concatenation instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00001076 ' [readability/multiline_string] [5]')
1077
1078 file_path = 'mydir/foo.cc'
1079
1080 error_collector = ErrorCollector(self.assert_)
1081 cpplint.ProcessFileData(file_path, 'cc',
1082 ['const char* str = "This is a\\',
1083 ' multiline string.";'],
1084 error_collector)
1085 self.assertEquals(
1086 2, # One per line.
1087 error_collector.ResultList().count(multiline_string_error_message))
1088
1089 # Test non-explicit single-argument constructors
1090 def testExplicitSingleArgumentConstructors(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001091 old_verbose_level = cpplint._cpplint_state.verbose_level
1092 cpplint._cpplint_state.verbose_level = 0
1093
1094 try:
1095 # missing explicit is bad
1096 self.TestMultiLineLint(
1097 """
1098 class Foo {
1099 Foo(int f);
1100 };""",
1101 'Single-parameter constructors should be marked explicit.'
1102 ' [runtime/explicit] [5]')
1103 # missing explicit is bad, even with whitespace
1104 self.TestMultiLineLint(
1105 """
1106 class Foo {
1107 Foo (int f);
1108 };""",
1109 ['Extra space before ( in function call [whitespace/parens] [4]',
1110 'Single-parameter constructors should be marked explicit.'
1111 ' [runtime/explicit] [5]'])
1112 # missing explicit, with distracting comment, is still bad
1113 self.TestMultiLineLint(
1114 """
1115 class Foo {
1116 Foo(int f); // simpler than Foo(blargh, blarg)
1117 };""",
1118 'Single-parameter constructors should be marked explicit.'
1119 ' [runtime/explicit] [5]')
1120 # missing explicit, with qualified classname
1121 self.TestMultiLineLint(
1122 """
1123 class Qualifier::AnotherOne::Foo {
1124 Foo(int f);
1125 };""",
1126 'Single-parameter constructors should be marked explicit.'
1127 ' [runtime/explicit] [5]')
1128 # missing explicit for inline constructors is bad as well
1129 self.TestMultiLineLint(
1130 """
1131 class Foo {
1132 inline Foo(int f);
1133 };""",
1134 'Single-parameter constructors should be marked explicit.'
1135 ' [runtime/explicit] [5]')
1136 # structs are caught as well.
1137 self.TestMultiLineLint(
1138 """
1139 struct Foo {
1140 Foo(int f);
1141 };""",
1142 'Single-parameter constructors should be marked explicit.'
1143 ' [runtime/explicit] [5]')
1144 # Templatized classes are caught as well.
1145 self.TestMultiLineLint(
1146 """
1147 template<typename T> class Foo {
1148 Foo(int f);
1149 };""",
1150 'Single-parameter constructors should be marked explicit.'
1151 ' [runtime/explicit] [5]')
1152 # inline case for templatized classes.
1153 self.TestMultiLineLint(
1154 """
1155 template<typename T> class Foo {
1156 inline Foo(int f);
1157 };""",
1158 'Single-parameter constructors should be marked explicit.'
1159 ' [runtime/explicit] [5]')
1160 # constructors with a default argument should still be marked explicit
1161 self.TestMultiLineLint(
1162 """
1163 class Foo {
1164 Foo(int f = 0);
1165 };""",
1166 'Constructors callable with one argument should be marked explicit.'
1167 ' [runtime/explicit] [5]')
1168 # multi-argument constructors with all but one default argument should be
1169 # marked explicit
1170 self.TestMultiLineLint(
1171 """
1172 class Foo {
1173 Foo(int f, int g = 0);
1174 };""",
1175 'Constructors callable with one argument should be marked explicit.'
1176 ' [runtime/explicit] [5]')
1177 # multi-argument constructors with all default arguments should be marked
1178 # explicit
1179 self.TestMultiLineLint(
1180 """
1181 class Foo {
1182 Foo(int f = 0, int g = 0);
1183 };""",
1184 'Constructors callable with one argument should be marked explicit.'
1185 ' [runtime/explicit] [5]')
1186 # explicit no-argument constructors are bad
1187 self.TestMultiLineLint(
1188 """
1189 class Foo {
1190 explicit Foo();
1191 };""",
1192 'Zero-parameter constructors should not be marked explicit.'
1193 ' [runtime/explicit] [5]')
1194 # void constructors are considered no-argument
1195 self.TestMultiLineLint(
1196 """
1197 class Foo {
1198 explicit Foo(void);
1199 };""",
1200 'Zero-parameter constructors should not be marked explicit.'
1201 ' [runtime/explicit] [5]')
1202 # Warn explicit multi-argument constructors at lowest severity
1203 self.TestMultiLineLint(
1204 """
1205 class Foo {
1206 explicit Foo(int f, int g);
1207 };""",
1208 'Constructors that require multiple arguments '
1209 'should not be marked explicit. [runtime/explicit] [0]')
1210 # but explicit multi-argument constructors with only one non-default
1211 # argument are OK
1212 self.TestMultiLineLint(
1213 """
1214 class Foo {
1215 explicit Foo(int f, int g = 0);
1216 };""",
1217 '')
1218 # single-argument constructors that take a function that takes multiple
1219 # arguments should be explicit
1220 self.TestMultiLineLint(
1221 """
1222 class Foo {
1223 Foo(void (*f)(int f, int g));
1224 };""",
1225 'Single-parameter constructors should be marked explicit.'
1226 ' [runtime/explicit] [5]')
1227 # single-argument constructors that take a single template argument with
1228 # multiple parameters should be explicit
1229 self.TestMultiLineLint(
1230 """
1231 template <typename T, typename S>
1232 class Foo {
1233 Foo(Bar<T, S> b);
1234 };""",
1235 'Single-parameter constructors should be marked explicit.'
1236 ' [runtime/explicit] [5]')
1237 # but copy constructors that take multiple template parameters are OK
1238 self.TestMultiLineLint(
1239 """
1240 template <typename T, S>
1241 class Foo {
1242 Foo(Foo<T, S>& f);
1243 };""",
1244 '')
1245 # proper style is okay
1246 self.TestMultiLineLint(
1247 """
1248 class Foo {
1249 explicit Foo(int f);
1250 };""",
1251 '')
1252 # two argument constructor is okay
1253 self.TestMultiLineLint(
1254 """
1255 class Foo {
1256 Foo(int f, int b);
1257 };""",
1258 '')
1259 # two argument constructor, across two lines, is okay
1260 self.TestMultiLineLint(
1261 """
1262 class Foo {
1263 Foo(int f,
1264 int b);
1265 };""",
1266 '')
1267 # non-constructor (but similar name), is okay
1268 self.TestMultiLineLint(
1269 """
1270 class Foo {
1271 aFoo(int f);
1272 };""",
1273 '')
1274 # constructor with void argument is okay
1275 self.TestMultiLineLint(
1276 """
1277 class Foo {
1278 Foo(void);
1279 };""",
1280 '')
1281 # single argument method is okay
1282 self.TestMultiLineLint(
1283 """
1284 class Foo {
1285 Bar(int b);
1286 };""",
1287 '')
1288 # comments should be ignored
1289 self.TestMultiLineLint(
1290 """
1291 class Foo {
1292 // Foo(int f);
1293 };""",
1294 '')
1295 # single argument function following class definition is okay
1296 # (okay, it's not actually valid, but we don't want a false positive)
1297 self.TestMultiLineLint(
1298 """
1299 class Foo {
1300 Foo(int f, int b);
1301 };
1302 Foo(int f);""",
1303 '')
1304 # single argument function is okay
1305 self.TestMultiLineLint(
1306 """static Foo(int f);""",
1307 '')
1308 # single argument copy constructor is okay.
1309 self.TestMultiLineLint(
1310 """
1311 class Foo {
1312 Foo(const Foo&);
1313 };""",
1314 '')
1315 self.TestMultiLineLint(
1316 """
1317 class Foo {
1318 Foo(Foo const&);
1319 };""",
1320 '')
1321 self.TestMultiLineLint(
1322 """
1323 class Foo {
1324 Foo(Foo&);
1325 };""",
1326 '')
1327 # templatized copy constructor is okay.
1328 self.TestMultiLineLint(
1329 """
1330 template<typename T> class Foo {
1331 Foo(const Foo<T>&);
1332 };""",
1333 '')
1334 # Special case for std::initializer_list
1335 self.TestMultiLineLint(
1336 """
1337 class Foo {
1338 Foo(std::initializer_list<T> &arg) {}
1339 };""",
1340 '')
1341 # Anything goes inside an assembly block
1342 error_collector = ErrorCollector(self.assert_)
1343 cpplint.ProcessFileData('foo.cc', 'cc',
1344 ['void Func() {',
1345 ' __asm__ (',
1346 ' "hlt"',
1347 ' );',
1348 ' asm {',
1349 ' movdqa [edx + 32], xmm2',
1350 ' }',
1351 '}'],
1352 error_collector)
1353 self.assertEquals(
1354 0,
1355 error_collector.ResultList().count(
1356 'Extra space before ( in function call [whitespace/parens] [4]'))
1357 self.assertEquals(
1358 0,
1359 error_collector.ResultList().count(
1360 'Closing ) should be moved to the previous line '
1361 '[whitespace/parens] [2]'))
1362 self.assertEquals(
1363 0,
1364 error_collector.ResultList().count(
1365 'Extra space before [ [whitespace/braces] [5]'))
1366 finally:
1367 cpplint._cpplint_state.verbose_level = old_verbose_level
erg@google.com4e00b9a2009-01-12 23:05:11 +00001368
1369 def testSlashStarCommentOnSingleLine(self):
1370 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001371 """/* static */ Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001372 '')
1373 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001374 """/*/ static */ Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001375 '')
1376 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001377 """/*/ static Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001378 'Could not find end of multi-line comment'
1379 ' [readability/multiline_comment] [5]')
1380 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001381 """ /*/ static Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001382 'Could not find end of multi-line comment'
1383 ' [readability/multiline_comment] [5]')
1384 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001385 """ /**/ static Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001386 '')
1387
1388 # Test suspicious usage of "if" like this:
1389 # if (a == b) {
1390 # DoSomething();
1391 # } if (a == c) { // Should be "else if".
1392 # DoSomething(); // This gets called twice if a == b && a == c.
1393 # }
1394 def testSuspiciousUsageOfIf(self):
1395 self.TestLint(
1396 ' if (a == b) {',
1397 '')
1398 self.TestLint(
1399 ' } if (a == b) {',
1400 'Did you mean "else if"? If not, start a new line for "if".'
1401 ' [readability/braces] [4]')
1402
1403 # Test suspicious usage of memset. Specifically, a 0
1404 # as the final argument is almost certainly an error.
1405 def testSuspiciousUsageOfMemset(self):
1406 # Normal use is okay.
1407 self.TestLint(
1408 ' memset(buf, 0, sizeof(buf))',
1409 '')
1410
1411 # A 0 as the final argument is almost certainly an error.
1412 self.TestLint(
1413 ' memset(buf, sizeof(buf), 0)',
1414 'Did you mean "memset(buf, 0, sizeof(buf))"?'
1415 ' [runtime/memset] [4]')
1416 self.TestLint(
1417 ' memset(buf, xsize * ysize, 0)',
1418 'Did you mean "memset(buf, 0, xsize * ysize)"?'
1419 ' [runtime/memset] [4]')
1420
1421 # There is legitimate test code that uses this form.
1422 # This is okay since the second argument is a literal.
1423 self.TestLint(
1424 " memset(buf, 'y', 0)",
1425 '')
1426 self.TestLint(
1427 ' memset(buf, 4, 0)',
1428 '')
1429 self.TestLint(
1430 ' memset(buf, -1, 0)',
1431 '')
1432 self.TestLint(
1433 ' memset(buf, 0xF1, 0)',
1434 '')
1435 self.TestLint(
1436 ' memset(buf, 0xcd, 0)',
1437 '')
1438
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001439 def testRedundantVirtual(self):
1440 self.TestLint('virtual void F()', '')
1441 self.TestLint('virtual void F();', '')
1442 self.TestLint('virtual void F() {}', '')
1443
1444 message_template = ('"%s" is redundant since function is already '
1445 'declared as "%s" [readability/inheritance] [4]')
1446 for virt_specifier in ['override', 'final']:
1447 error_message = message_template % ('virtual', virt_specifier)
1448 self.TestLint('virtual int F() %s' % virt_specifier, error_message)
1449 self.TestLint('virtual int F() %s;' % virt_specifier, error_message)
1450 self.TestLint('virtual int F() %s {' % virt_specifier, error_message)
1451
1452 error_collector = ErrorCollector(self.assert_)
1453 cpplint.ProcessFileData(
1454 'foo.cc', 'cc',
1455 ['// Copyright 2014 Your Company.',
1456 'virtual void F(int a,',
1457 ' int b) ' + virt_specifier + ';',
1458 'virtual void F(int a,',
1459 ' int b) LOCKS_EXCLUDED(lock) ' + virt_specifier + ';',
1460 'virtual void F(int a,',
1461 ' int b)',
1462 ' LOCKS_EXCLUDED(lock) ' + virt_specifier + ';',
1463 ''],
1464 error_collector)
1465 self.assertEquals(
1466 [error_message, error_message, error_message],
1467 error_collector.Results())
1468
1469 error_message = message_template % ('override', 'final')
1470 self.TestLint('int F() override final', error_message)
1471 self.TestLint('int F() override final;', error_message)
1472 self.TestLint('int F() override final {}', error_message)
1473 self.TestLint('int F() final override', error_message)
1474 self.TestLint('int F() final override;', error_message)
1475 self.TestLint('int F() final override {}', error_message)
1476
avakulenko@google.com554223d2014-12-04 22:00:20 +00001477 error_collector = ErrorCollector(self.assert_)
1478 cpplint.ProcessFileData(
1479 'foo.cc', 'cc',
1480 ['// Copyright 2014 Your Company.',
1481 'struct A : virtual B {',
1482 ' ~A() override;'
1483 '};',
1484 'class C',
1485 ' : public D,',
1486 ' public virtual E {',
1487 ' void Func() override;',
1488 '}',
1489 ''],
1490 error_collector)
1491 self.assertEquals('', error_collector.Results())
1492
1493 self.TestLint('void Finalize(AnnotationProto *final) override;', '')
1494
erg@google.com4e00b9a2009-01-12 23:05:11 +00001495 def testCheckDeprecated(self):
erg@google.com4e00b9a2009-01-12 23:05:11 +00001496 self.TestLanguageRulesCheck('foo_test.cc', '#include <iostream>', '')
1497 self.TestLanguageRulesCheck('foo_unittest.cc', '#include <iostream>', '')
1498
1499 def testCheckPosixThreading(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00001500 self.TestLint('var = sctime_r()', '')
1501 self.TestLint('var = strtok_r()', '')
1502 self.TestLint('var = strtok_r(foo, ba, r)', '')
1503 self.TestLint('var = brand()', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001504 self.TestLint('_rand()', '')
1505 self.TestLint('.rand()', '')
erg@google.comd350fe52013-01-14 17:51:48 +00001506 self.TestLint('->rand()', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00001507 self.TestLint('ACMRandom rand(seed)', '')
1508 self.TestLint('ISAACRandom rand()', '')
1509 self.TestLint('var = rand()',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001510 'Consider using rand_r(...) instead of rand(...)'
1511 ' for improved thread safety.'
1512 ' [runtime/threadsafe_fn] [2]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00001513 self.TestLint('var = strtok(str, delim)',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001514 'Consider using strtok_r(...) '
1515 'instead of strtok(...)'
1516 ' for improved thread safety.'
1517 ' [runtime/threadsafe_fn] [2]')
1518
erg@google.com2aa59982013-10-28 19:09:25 +00001519 def testVlogMisuse(self):
1520 self.TestLint('VLOG(1)', '')
1521 self.TestLint('VLOG(99)', '')
1522 self.TestLint('LOG(ERROR)', '')
1523 self.TestLint('LOG(INFO)', '')
1524 self.TestLint('LOG(WARNING)', '')
1525 self.TestLint('LOG(FATAL)', '')
1526 self.TestLint('LOG(DFATAL)', '')
1527 self.TestLint('VLOG(SOMETHINGWEIRD)', '')
1528 self.TestLint('MYOWNVLOG(ERROR)', '')
1529 errmsg = ('VLOG() should be used with numeric verbosity level. '
1530 'Use LOG() if you want symbolic severity levels.'
1531 ' [runtime/vlog] [5]')
1532 self.TestLint('VLOG(ERROR)', errmsg)
1533 self.TestLint('VLOG(INFO)', errmsg)
1534 self.TestLint('VLOG(WARNING)', errmsg)
1535 self.TestLint('VLOG(FATAL)', errmsg)
1536 self.TestLint('VLOG(DFATAL)', errmsg)
1537 self.TestLint(' VLOG(ERROR)', errmsg)
1538 self.TestLint(' VLOG(INFO)', errmsg)
1539 self.TestLint(' VLOG(WARNING)', errmsg)
1540 self.TestLint(' VLOG(FATAL)', errmsg)
1541 self.TestLint(' VLOG(DFATAL)', errmsg)
1542
1543
erg@google.com4e00b9a2009-01-12 23:05:11 +00001544 # Test potential format string bugs like printf(foo).
1545 def testFormatStrings(self):
1546 self.TestLint('printf("foo")', '')
1547 self.TestLint('printf("foo: %s", foo)', '')
1548 self.TestLint('DocidForPrintf(docid)', '') # Should not trigger.
erg@google.com8a95ecc2011-09-08 00:45:54 +00001549 self.TestLint('printf(format, value)', '') # Should not trigger.
erg@google.comd350fe52013-01-14 17:51:48 +00001550 self.TestLint('printf(__VA_ARGS__)', '') # Should not trigger.
erg@google.com8a95ecc2011-09-08 00:45:54 +00001551 self.TestLint('printf(format.c_str(), value)', '') # Should not trigger.
1552 self.TestLint('printf(format(index).c_str(), value)', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001553 self.TestLint(
1554 'printf(foo)',
1555 'Potential format string bug. Do printf("%s", foo) instead.'
1556 ' [runtime/printf] [4]')
1557 self.TestLint(
1558 'printf(foo.c_str())',
1559 'Potential format string bug. '
1560 'Do printf("%s", foo.c_str()) instead.'
1561 ' [runtime/printf] [4]')
1562 self.TestLint(
1563 'printf(foo->c_str())',
1564 'Potential format string bug. '
1565 'Do printf("%s", foo->c_str()) instead.'
1566 ' [runtime/printf] [4]')
1567 self.TestLint(
1568 'StringPrintf(foo)',
1569 'Potential format string bug. Do StringPrintf("%s", foo) instead.'
1570 ''
1571 ' [runtime/printf] [4]')
1572
erg@google.coma868d2d2009-10-09 21:18:45 +00001573 # Test disallowed use of operator& and other operators.
1574 def testIllegalOperatorOverloading(self):
1575 errmsg = ('Unary operator& is dangerous. Do not use it.'
1576 ' [runtime/operator] [4]')
1577 self.TestLint('void operator=(const Myclass&)', '')
1578 self.TestLint('void operator&(int a, int b)', '') # binary operator& ok
1579 self.TestLint('void operator&() { }', errmsg)
1580 self.TestLint('void operator & ( ) { }',
avakulenko@google.com02af6282014-06-04 18:53:25 +00001581 ['Extra space after ( [whitespace/parens] [2]', errmsg])
erg@google.coma868d2d2009-10-09 21:18:45 +00001582
1583 # const string reference members are dangerous..
1584 def testConstStringReferenceMembers(self):
1585 errmsg = ('const string& members are dangerous. It is much better to use '
1586 'alternatives, such as pointers or simple constants.'
1587 ' [runtime/member_string_references] [2]')
1588
1589 members_declarations = ['const string& church',
1590 'const string &turing',
1591 'const string & godel']
1592 # TODO(unknown): Enable also these tests if and when we ever
1593 # decide to check for arbitrary member references.
1594 # "const Turing & a",
1595 # "const Church& a",
1596 # "const vector<int>& a",
1597 # "const Kurt::Godel & godel",
1598 # "const Kazimierz::Kuratowski& kk" ]
1599
1600 # The Good.
1601
1602 self.TestLint('void f(const string&)', '')
1603 self.TestLint('const string& f(const string& a, const string& b)', '')
1604 self.TestLint('typedef const string& A;', '')
1605
1606 for decl in members_declarations:
1607 self.TestLint(decl + ' = b;', '')
1608 self.TestLint(decl + ' =', '')
1609
1610 # The Bad.
1611
1612 for decl in members_declarations:
1613 self.TestLint(decl + ';', errmsg)
1614
erg@google.com4e00b9a2009-01-12 23:05:11 +00001615 # Variable-length arrays are not permitted.
1616 def testVariableLengthArrayDetection(self):
1617 errmsg = ('Do not use variable-length arrays. Use an appropriately named '
1618 "('k' followed by CamelCase) compile-time constant for the size."
1619 ' [runtime/arrays] [1]')
1620
1621 self.TestLint('int a[any_old_variable];', errmsg)
1622 self.TestLint('int doublesize[some_var * 2];', errmsg)
1623 self.TestLint('int a[afunction()];', errmsg)
1624 self.TestLint('int a[function(kMaxFooBars)];', errmsg)
1625 self.TestLint('bool a_list[items_->size()];', errmsg)
1626 self.TestLint('namespace::Type buffer[len+1];', errmsg)
1627
1628 self.TestLint('int a[64];', '')
1629 self.TestLint('int a[0xFF];', '')
1630 self.TestLint('int first[256], second[256];', '')
1631 self.TestLint('int array_name[kCompileTimeConstant];', '')
1632 self.TestLint('char buf[somenamespace::kBufSize];', '')
1633 self.TestLint('int array_name[ALL_CAPS];', '')
1634 self.TestLint('AClass array1[foo::bar::ALL_CAPS];', '')
1635 self.TestLint('int a[kMaxStrLen + 1];', '')
1636 self.TestLint('int a[sizeof(foo)];', '')
1637 self.TestLint('int a[sizeof(*foo)];', '')
1638 self.TestLint('int a[sizeof foo];', '')
1639 self.TestLint('int a[sizeof(struct Foo)];', '')
1640 self.TestLint('int a[128 - sizeof(const bar)];', '')
1641 self.TestLint('int a[(sizeof(foo) * 4)];', '')
1642 self.TestLint('int a[(arraysize(fixed_size_array)/2) << 1];', '')
1643 self.TestLint('delete a[some_var];', '')
1644 self.TestLint('return a[some_var];', '')
1645
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001646 # DISALLOW_COPY_AND_ASSIGN and DISALLOW_IMPLICIT_CONSTRUCTORS should be at
1647 # end of class if present.
1648 def testDisallowMacrosAtEnd(self):
erg@google.com4e00b9a2009-01-12 23:05:11 +00001649 for macro_name in (
erg@google.com4e00b9a2009-01-12 23:05:11 +00001650 'DISALLOW_COPY_AND_ASSIGN',
1651 'DISALLOW_IMPLICIT_CONSTRUCTORS'):
avakulenko@google.com554223d2014-12-04 22:00:20 +00001652 error_collector = ErrorCollector(self.assert_)
1653 cpplint.ProcessFileData(
1654 'foo.cc', 'cc',
1655 ['// Copyright 2014 Your Company.',
1656 'class SomeClass {',
1657 ' private:',
1658 ' %s(SomeClass);' % macro_name,
1659 ' int member_;',
1660 '};',
1661 ''],
1662 error_collector)
1663 self.assertEquals(
erg@google.com4e00b9a2009-01-12 23:05:11 +00001664 ('%s should be the last thing in the class' % macro_name) +
avakulenko@google.com554223d2014-12-04 22:00:20 +00001665 ' [readability/constructors] [3]',
1666 error_collector.Results())
1667
1668 error_collector = ErrorCollector(self.assert_)
1669 cpplint.ProcessFileData(
1670 'foo.cc', 'cc',
1671 ['// Copyright 2014 Your Company.',
1672 'class OuterClass {',
1673 ' private:',
1674 ' struct InnerClass {',
1675 ' private:',
1676 ' %s(InnerClass);' % macro_name,
1677 ' int member;',
1678 ' };',
1679 '};',
1680 ''],
1681 error_collector)
1682 self.assertEquals(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001683 ('%s should be the last thing in the class' % macro_name) +
avakulenko@google.com554223d2014-12-04 22:00:20 +00001684 ' [readability/constructors] [3]',
1685 error_collector.Results())
1686
1687 error_collector = ErrorCollector(self.assert_)
1688 cpplint.ProcessFileData(
1689 'foo.cc', 'cc',
1690 ['// Copyright 2014 Your Company.',
1691 'class OuterClass1 {',
1692 ' private:',
1693 ' struct InnerClass1 {',
1694 ' private:',
1695 ' %s(InnerClass1);' % macro_name,
1696 ' };',
1697 ' %s(OuterClass1);' % macro_name,
1698 '};',
1699 'struct OuterClass2 {',
1700 ' private:',
1701 ' class InnerClass2 {',
1702 ' private:',
1703 ' %s(InnerClass2);' % macro_name,
1704 ' // comment',
1705 ' };',
1706 '',
1707 ' %s(OuterClass2);' % macro_name,
1708 '',
1709 ' // comment',
1710 '};',
1711 'void Func() {',
1712 ' struct LocalClass {',
1713 ' private:',
1714 ' %s(LocalClass);' % macro_name,
1715 ' } variable;',
1716 '}',
1717 ''],
1718 error_collector)
1719 self.assertEquals('', error_collector.Results())
erg@google.com4e00b9a2009-01-12 23:05:11 +00001720
erg@google.comd350fe52013-01-14 17:51:48 +00001721 # DISALLOW* macros should be in the private: section.
1722 def testMisplacedDisallowMacros(self):
1723 for macro_name in (
erg@google.comd350fe52013-01-14 17:51:48 +00001724 'DISALLOW_COPY_AND_ASSIGN',
1725 'DISALLOW_IMPLICIT_CONSTRUCTORS'):
1726 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001727 """
1728 class A {'
erg@google.comd350fe52013-01-14 17:51:48 +00001729 public:
1730 %s(A);
1731 };""" % macro_name,
1732 ('%s must be in the private: section' % macro_name) +
1733 ' [readability/constructors] [3]')
1734
1735 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001736 """
1737 struct B {'
erg@google.comd350fe52013-01-14 17:51:48 +00001738 %s(B);
1739 };""" % macro_name,
1740 ('%s must be in the private: section' % macro_name) +
1741 ' [readability/constructors] [3]')
1742
1743 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001744 """
1745 class Outer1 {'
erg@google.comd350fe52013-01-14 17:51:48 +00001746 private:
1747 struct Inner1 {
1748 %s(Inner1);
1749 };
1750 %s(Outer1);
1751 };""" % (macro_name, macro_name),
1752 ('%s must be in the private: section' % macro_name) +
1753 ' [readability/constructors] [3]')
1754
1755 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001756 """
1757 class Outer2 {'
erg@google.comd350fe52013-01-14 17:51:48 +00001758 private:
1759 class Inner2 {
1760 %s(Inner2);
1761 };
1762 %s(Outer2);
1763 };""" % (macro_name, macro_name),
1764 '')
1765 # Extra checks to make sure that nested classes are handled
1766 # correctly. Use different macros for inner and outer classes so
1767 # that we can tell the error messages apart.
1768 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001769 """
1770 class Outer3 {
erg@google.comd350fe52013-01-14 17:51:48 +00001771 struct Inner3 {
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001772 DISALLOW_COPY_AND_ASSIGN(Inner3);
erg@google.comd350fe52013-01-14 17:51:48 +00001773 };
1774 DISALLOW_IMPLICIT_CONSTRUCTORS(Outer3);
1775 };""",
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001776 ('DISALLOW_COPY_AND_ASSIGN must be in the private: section'
erg@google.comd350fe52013-01-14 17:51:48 +00001777 ' [readability/constructors] [3]'))
1778 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001779 """
1780 struct Outer4 {
erg@google.comd350fe52013-01-14 17:51:48 +00001781 class Inner4 {
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001782 DISALLOW_COPY_AND_ASSIGN(Inner4);
erg@google.comd350fe52013-01-14 17:51:48 +00001783 };
1784 DISALLOW_IMPLICIT_CONSTRUCTORS(Outer4);
1785 };""",
1786 ('DISALLOW_IMPLICIT_CONSTRUCTORS must be in the private: section'
1787 ' [readability/constructors] [3]'))
1788
erg@google.com4e00b9a2009-01-12 23:05:11 +00001789 # Brace usage
1790 def testBraces(self):
1791 # Braces shouldn't be followed by a ; unless they're defining a struct
1792 # or initializing an array
1793 self.TestLint('int a[3] = { 1, 2, 3 };', '')
1794 self.TestLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001795 """const int foo[] =
1796 {1, 2, 3 };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001797 '')
1798 # For single line, unmatched '}' with a ';' is ignored (not enough context)
1799 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001800 """int a[3] = { 1,
erg@google.com4e00b9a2009-01-12 23:05:11 +00001801 2,
erg@google.com8a95ecc2011-09-08 00:45:54 +00001802 3 };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001803 '')
1804 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001805 """int a[2][3] = { { 1, 2 },
1806 { 3, 4 } };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001807 '')
1808 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001809 """int a[2][3] =
erg@google.com4e00b9a2009-01-12 23:05:11 +00001810 { { 1, 2 },
erg@google.com8a95ecc2011-09-08 00:45:54 +00001811 { 3, 4 } };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001812 '')
1813
1814 # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements
1815 def testCheckCheck(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001816 self.TestLint('CHECK(x == 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001817 'Consider using CHECK_EQ instead of CHECK(a == b)'
1818 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001819 self.TestLint('CHECK(x != 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001820 'Consider using CHECK_NE instead of CHECK(a != b)'
1821 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001822 self.TestLint('CHECK(x >= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001823 'Consider using CHECK_GE instead of CHECK(a >= b)'
1824 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001825 self.TestLint('CHECK(x > 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001826 'Consider using CHECK_GT instead of CHECK(a > b)'
1827 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001828 self.TestLint('CHECK(x <= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001829 'Consider using CHECK_LE instead of CHECK(a <= b)'
1830 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001831 self.TestLint('CHECK(x < 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001832 'Consider using CHECK_LT instead of CHECK(a < b)'
1833 ' [readability/check] [2]')
1834
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001835 self.TestLint('DCHECK(x == 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001836 'Consider using DCHECK_EQ instead of DCHECK(a == b)'
1837 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001838 self.TestLint('DCHECK(x != 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001839 'Consider using DCHECK_NE instead of DCHECK(a != b)'
1840 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001841 self.TestLint('DCHECK(x >= 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001842 'Consider using DCHECK_GE instead of DCHECK(a >= b)'
1843 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001844 self.TestLint('DCHECK(x > 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001845 'Consider using DCHECK_GT instead of DCHECK(a > b)'
1846 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001847 self.TestLint('DCHECK(x <= 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001848 'Consider using DCHECK_LE instead of DCHECK(a <= b)'
1849 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001850 self.TestLint('DCHECK(x < 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001851 'Consider using DCHECK_LT instead of DCHECK(a < b)'
1852 ' [readability/check] [2]')
1853
erg@google.com4e00b9a2009-01-12 23:05:11 +00001854 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001855 'EXPECT_TRUE("42" == x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001856 'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)'
1857 ' [readability/check] [2]')
1858 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001859 'EXPECT_TRUE("42" != x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001860 'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)'
1861 ' [readability/check] [2]')
1862 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001863 'EXPECT_TRUE(+42 >= x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001864 'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)'
1865 ' [readability/check] [2]')
1866 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001867 'EXPECT_TRUE_M(-42 > x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001868 'Consider using EXPECT_GT_M instead of EXPECT_TRUE_M(a > b)'
1869 ' [readability/check] [2]')
1870 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001871 'EXPECT_TRUE_M(42U <= x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001872 'Consider using EXPECT_LE_M instead of EXPECT_TRUE_M(a <= b)'
1873 ' [readability/check] [2]')
1874 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001875 'EXPECT_TRUE_M(42L < x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001876 'Consider using EXPECT_LT_M instead of EXPECT_TRUE_M(a < b)'
1877 ' [readability/check] [2]')
1878
1879 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001880 'EXPECT_FALSE(x == 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001881 'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)'
1882 ' [readability/check] [2]')
1883 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001884 'EXPECT_FALSE(x != 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001885 'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)'
1886 ' [readability/check] [2]')
1887 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001888 'EXPECT_FALSE(x >= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001889 'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)'
1890 ' [readability/check] [2]')
1891 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001892 'ASSERT_FALSE(x > 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001893 'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)'
1894 ' [readability/check] [2]')
1895 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001896 'ASSERT_FALSE(x <= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001897 'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)'
1898 ' [readability/check] [2]')
1899 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001900 'ASSERT_FALSE_M(x < 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001901 'Consider using ASSERT_GE_M instead of ASSERT_FALSE_M(a < b)'
1902 ' [readability/check] [2]')
1903
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001904 self.TestLint('CHECK(x<42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001905 ['Missing spaces around <'
1906 ' [whitespace/operators] [3]',
1907 'Consider using CHECK_LT instead of CHECK(a < b)'
1908 ' [readability/check] [2]'])
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001909 self.TestLint('CHECK(x>42);',
erg@google.comd350fe52013-01-14 17:51:48 +00001910 ['Missing spaces around >'
1911 ' [whitespace/operators] [3]',
1912 'Consider using CHECK_GT instead of CHECK(a > b)'
1913 ' [readability/check] [2]'])
erg@google.com4e00b9a2009-01-12 23:05:11 +00001914
erg@google.com0075d142013-11-05 22:28:07 +00001915 self.TestLint('using some::namespace::operator<<;', '')
1916 self.TestLint('using some::namespace::operator>>;', '')
erg@google.comc6671232013-10-25 21:44:03 +00001917
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001918 self.TestLint('CHECK(x->y == 42);',
erg@google.comc6671232013-10-25 21:44:03 +00001919 'Consider using CHECK_EQ instead of CHECK(a == b)'
1920 ' [readability/check] [2]')
1921
erg@google.com4e00b9a2009-01-12 23:05:11 +00001922 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001923 ' EXPECT_TRUE(42 < x); // Random comment.',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001924 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1925 ' [readability/check] [2]')
1926 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001927 'EXPECT_TRUE( 42 < x );',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001928 ['Extra space after ( in function call'
1929 ' [whitespace/parens] [4]',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001930 'Extra space before ) [whitespace/parens] [2]',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001931 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1932 ' [readability/check] [2]'])
erg@google.com4e00b9a2009-01-12 23:05:11 +00001933
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001934 self.TestLint('CHECK(4\'2 == x);',
avakulenko@google.com02af6282014-06-04 18:53:25 +00001935 'Consider using CHECK_EQ instead of CHECK(a == b)'
1936 ' [readability/check] [2]')
1937
1938 def testCheckCheckFalsePositives(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001939 self.TestLint('CHECK(some_iterator == obj.end());', '')
1940 self.TestLint('EXPECT_TRUE(some_iterator == obj.end());', '')
1941 self.TestLint('EXPECT_FALSE(some_iterator == obj.end());', '')
1942 self.TestLint('CHECK(some_pointer != NULL);', '')
1943 self.TestLint('EXPECT_TRUE(some_pointer != NULL);', '')
1944 self.TestLint('EXPECT_FALSE(some_pointer != NULL);', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00001945
1946 self.TestLint('CHECK(CreateTestFile(dir, (1 << 20)));', '')
1947 self.TestLint('CHECK(CreateTestFile(dir, (1 >> 20)));', '')
1948
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001949 self.TestLint('CHECK(x ^ (y < 42));', '')
1950 self.TestLint('CHECK((x > 42) ^ (x < 54));', '')
1951 self.TestLint('CHECK(a && b < 42);', '')
1952 self.TestLint('CHECK(42 < a && a < b);', '')
1953 self.TestLint('SOFT_CHECK(x > 42);', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00001954
1955 self.TestMultiLineLint(
1956 """_STLP_DEFINE_BINARY_OP_CHECK(==, _OP_EQUAL);
1957 _STLP_DEFINE_BINARY_OP_CHECK(!=, _OP_NOT_EQUAL);
1958 _STLP_DEFINE_BINARY_OP_CHECK(<, _OP_LESS_THAN);
1959 _STLP_DEFINE_BINARY_OP_CHECK(<=, _OP_LESS_EQUAL);
1960 _STLP_DEFINE_BINARY_OP_CHECK(>, _OP_GREATER_THAN);
1961 _STLP_DEFINE_BINARY_OP_CHECK(>=, _OP_GREATER_EQUAL);
1962 _STLP_DEFINE_BINARY_OP_CHECK(+, _OP_PLUS);
1963 _STLP_DEFINE_BINARY_OP_CHECK(*, _OP_TIMES);
1964 _STLP_DEFINE_BINARY_OP_CHECK(/, _OP_DIVIDE);
1965 _STLP_DEFINE_BINARY_OP_CHECK(-, _OP_SUBTRACT);
1966 _STLP_DEFINE_BINARY_OP_CHECK(%, _OP_MOD);""",
1967 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001968
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001969 self.TestLint('CHECK(x < 42) << "Custom error message";', '')
1970
erg@google.comd350fe52013-01-14 17:51:48 +00001971 # Alternative token to punctuation operator replacements
1972 def testCheckAltTokens(self):
1973 self.TestLint('true or true',
1974 'Use operator || instead of or'
1975 ' [readability/alt_tokens] [2]')
1976 self.TestLint('true and true',
1977 'Use operator && instead of and'
1978 ' [readability/alt_tokens] [2]')
1979 self.TestLint('if (not true)',
1980 'Use operator ! instead of not'
1981 ' [readability/alt_tokens] [2]')
1982 self.TestLint('1 bitor 1',
1983 'Use operator | instead of bitor'
1984 ' [readability/alt_tokens] [2]')
1985 self.TestLint('1 xor 1',
1986 'Use operator ^ instead of xor'
1987 ' [readability/alt_tokens] [2]')
1988 self.TestLint('1 bitand 1',
1989 'Use operator & instead of bitand'
1990 ' [readability/alt_tokens] [2]')
1991 self.TestLint('x = compl 1',
1992 'Use operator ~ instead of compl'
1993 ' [readability/alt_tokens] [2]')
1994 self.TestLint('x and_eq y',
1995 'Use operator &= instead of and_eq'
1996 ' [readability/alt_tokens] [2]')
1997 self.TestLint('x or_eq y',
1998 'Use operator |= instead of or_eq'
1999 ' [readability/alt_tokens] [2]')
2000 self.TestLint('x xor_eq y',
2001 'Use operator ^= instead of xor_eq'
2002 ' [readability/alt_tokens] [2]')
2003 self.TestLint('x not_eq y',
2004 'Use operator != instead of not_eq'
2005 ' [readability/alt_tokens] [2]')
2006 self.TestLint('line_continuation or',
2007 'Use operator || instead of or'
2008 ' [readability/alt_tokens] [2]')
2009 self.TestLint('if(true and(parentheses',
2010 'Use operator && instead of and'
2011 ' [readability/alt_tokens] [2]')
2012
2013 self.TestLint('#include "base/false-and-false.h"', '')
2014 self.TestLint('#error false or false', '')
2015 self.TestLint('false nor false', '')
2016 self.TestLint('false nand false', '')
2017
erg@google.com4e00b9a2009-01-12 23:05:11 +00002018 # Passing and returning non-const references
2019 def testNonConstReference(self):
2020 # Passing a non-const reference as function parameter is forbidden.
2021 operand_error_message = ('Is this a non-const reference? '
erg@google.comfd5da632013-10-25 17:39:45 +00002022 'If so, make const or use a pointer: %s'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002023 ' [runtime/references] [2]')
2024 # Warn of use of a non-const reference in operators and functions
erg@google.comfd5da632013-10-25 17:39:45 +00002025 self.TestLint('bool operator>(Foo& s, Foo& f);',
2026 [operand_error_message % 'Foo& s',
2027 operand_error_message % 'Foo& f'])
2028 self.TestLint('bool operator+(Foo& s, Foo& f);',
2029 [operand_error_message % 'Foo& s',
2030 operand_error_message % 'Foo& f'])
2031 self.TestLint('int len(Foo& s);', operand_error_message % 'Foo& s')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002032 # Allow use of non-const references in a few specific cases
2033 self.TestLint('stream& operator>>(stream& s, Foo& f);', '')
2034 self.TestLint('stream& operator<<(stream& s, Foo& f);', '')
2035 self.TestLint('void swap(Bar& a, Bar& b);', '')
2036 # Returning a non-const reference from a function is OK.
2037 self.TestLint('int& g();', '')
2038 # Passing a const reference to a struct (using the struct keyword) is OK.
2039 self.TestLint('void foo(const struct tm& tm);', '')
2040 # Passing a const reference to a typename is OK.
2041 self.TestLint('void foo(const typename tm& tm);', '')
erg@google.comfd5da632013-10-25 17:39:45 +00002042 # Const reference to a pointer type is OK.
2043 self.TestLint('void foo(const Bar* const& p) {', '')
2044 self.TestLint('void foo(Bar const* const& p) {', '')
2045 self.TestLint('void foo(Bar* const& p) {', '')
2046 # Const reference to a templated type is OK.
2047 self.TestLint('void foo(const std::vector<std::string>& v);', '')
2048 # Non-const reference to a pointer type is not OK.
2049 self.TestLint('void foo(Bar*& p);',
2050 operand_error_message % 'Bar*& p')
2051 self.TestLint('void foo(const Bar*& p);',
2052 operand_error_message % 'const Bar*& p')
2053 self.TestLint('void foo(Bar const*& p);',
2054 operand_error_message % 'Bar const*& p')
2055 self.TestLint('void foo(struct Bar*& p);',
2056 operand_error_message % 'struct Bar*& p')
2057 self.TestLint('void foo(const struct Bar*& p);',
2058 operand_error_message % 'const struct Bar*& p')
2059 self.TestLint('void foo(struct Bar const*& p);',
2060 operand_error_message % 'struct Bar const*& p')
2061 # Non-const reference to a templated type is not OK.
2062 self.TestLint('void foo(std::vector<int>& p);',
2063 operand_error_message % 'std::vector<int>& p')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002064 # Returning an address of something is not prohibited.
2065 self.TestLint('return &something;', '')
erg@google.comd7d27472011-09-07 17:36:35 +00002066 self.TestLint('if (condition) {return &something; }', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002067 self.TestLint('if (condition) return &something;', '')
2068 self.TestLint('if (condition) address = &something;', '')
2069 self.TestLint('if (condition) result = lhs&rhs;', '')
2070 self.TestLint('if (condition) result = lhs & rhs;', '')
2071 self.TestLint('a = (b+c) * sizeof &f;', '')
2072 self.TestLint('a = MySize(b) * sizeof &f;', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002073 # We don't get confused by C++11 range-based for loops.
2074 self.TestLint('for (const string& s : c)', '')
2075 self.TestLint('for (auto& r : c)', '')
2076 self.TestLint('for (typename Type& a : b)', '')
erg@google.comfd5da632013-10-25 17:39:45 +00002077 # We don't get confused by some other uses of '&'.
2078 self.TestLint('T& operator=(const T& t);', '')
2079 self.TestLint('int g() { return (a & b); }', '')
2080 self.TestLint('T& r = (T&)*(vp());', '')
2081 self.TestLint('T& r = v', '')
2082 self.TestLint('static_assert((kBits & kMask) == 0, "text");', '')
2083 self.TestLint('COMPILE_ASSERT((kBits & kMask) == 0, text);', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002084 # Spaces before template arguments. This is poor style, but
2085 # happens 0.15% of the time.
2086 self.TestLint('void Func(const vector <int> &const_x, '
2087 'vector <int> &nonconst_x) {',
2088 operand_error_message % 'vector<int> &nonconst_x')
erg@google.comfd5da632013-10-25 17:39:45 +00002089
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002090 # Derived member functions are spared from override check
2091 self.TestLint('void Func(X& x);', operand_error_message % 'X& x')
2092 self.TestLint('void Func(X& x) {}', operand_error_message % 'X& x')
2093 self.TestLint('void Func(X& x) override;', '')
2094 self.TestLint('void Func(X& x) override {', '')
2095 self.TestLint('void Func(X& x) const override;', '')
2096 self.TestLint('void Func(X& x) const override {', '')
2097
avakulenko@google.com554223d2014-12-04 22:00:20 +00002098 # Don't warn on out-of-line method definitions.
2099 self.TestLint('void NS::Func(X& x) {', '')
2100 error_collector = ErrorCollector(self.assert_)
2101 cpplint.ProcessFileData(
2102 'foo.cc', 'cc',
2103 ['// Copyright 2014 Your Company. All Rights Reserved.',
2104 'void a::b() {}',
2105 'void f(int& q) {}',
2106 ''],
2107 error_collector)
2108 self.assertEquals(
2109 operand_error_message % 'int& q',
2110 error_collector.Results())
2111
avakulenko@google.com02af6282014-06-04 18:53:25 +00002112 # Other potential false positives. These need full parser
erg@google.comfd5da632013-10-25 17:39:45 +00002113 # state to reproduce as opposed to just TestLint.
2114 error_collector = ErrorCollector(self.assert_)
2115 cpplint.ProcessFileData(
2116 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002117 ['// Copyright 2014 Your Company. All Rights Reserved.',
erg@google.comfd5da632013-10-25 17:39:45 +00002118 'void swap(int &x,',
2119 ' int &y) {',
2120 '}',
2121 'void swap(',
2122 ' sparsegroup<T, GROUP_SIZE, Alloc> &x,',
2123 ' sparsegroup<T, GROUP_SIZE, Alloc> &y) {',
2124 '}',
2125 'ostream& operator<<(',
2126 ' ostream& out',
2127 ' const dense_hash_set<Value, Hash, Equals, Alloc>& seq) {',
2128 '}',
avakulenko@google.com554223d2014-12-04 22:00:20 +00002129 'class A {',
2130 ' void Function(',
2131 ' string &x) override {',
2132 ' }',
2133 '};',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002134 'void Derived::Function(',
avakulenko@google.com554223d2014-12-04 22:00:20 +00002135 ' string &x) {',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002136 '}',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002137 '#define UNSUPPORTED_MASK(_mask) \\',
2138 ' if (flags & _mask) { \\',
2139 ' LOG(FATAL) << "Unsupported flag: " << #_mask; \\',
2140 ' }',
2141 'Constructor::Constructor()',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002142 ' : initializer1_(a1 & b1),',
2143 ' initializer2_(a2 & b2) {',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002144 '}',
2145 'Constructor::Constructor()',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002146 ' : initializer1_{a3 & b3},',
2147 ' initializer2_(a4 & b4) {',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002148 '}',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002149 'Constructor::Constructor()',
2150 ' : initializer1_{a5 & b5},',
2151 ' initializer2_(a6 & b6) {}',
erg@google.comfd5da632013-10-25 17:39:45 +00002152 ''],
2153 error_collector)
2154 self.assertEquals('', error_collector.Results())
erg@google.com4e00b9a2009-01-12 23:05:11 +00002155
erg@google.comc6671232013-10-25 21:44:03 +00002156 # Multi-line references
avakulenko@google.com02af6282014-06-04 18:53:25 +00002157 error_collector = ErrorCollector(self.assert_)
erg@google.comc6671232013-10-25 21:44:03 +00002158 cpplint.ProcessFileData(
2159 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002160 ['// Copyright 2014 Your Company. All Rights Reserved.',
erg@google.comc6671232013-10-25 21:44:03 +00002161 'void Func(const Outer::',
2162 ' Inner& const_x,',
2163 ' const Outer',
2164 ' ::Inner& const_y,',
erg@google.com2aa59982013-10-28 19:09:25 +00002165 ' const Outer<',
2166 ' int>::Inner& const_z,',
erg@google.comc6671232013-10-25 21:44:03 +00002167 ' Outer::',
2168 ' Inner& nonconst_x,',
2169 ' Outer',
erg@google.com2aa59982013-10-28 19:09:25 +00002170 ' ::Inner& nonconst_y,',
2171 ' Outer<',
2172 ' int>::Inner& nonconst_z) {',
erg@google.comc6671232013-10-25 21:44:03 +00002173 '}',
2174 ''],
2175 error_collector)
2176 self.assertEquals(
2177 [operand_error_message % 'Outer::Inner& nonconst_x',
erg@google.com2aa59982013-10-28 19:09:25 +00002178 operand_error_message % 'Outer::Inner& nonconst_y',
2179 operand_error_message % 'Outer<int>::Inner& nonconst_z'],
erg@google.comc6671232013-10-25 21:44:03 +00002180 error_collector.Results())
2181
avakulenko@google.com02af6282014-06-04 18:53:25 +00002182 # A peculiar false positive due to bad template argument parsing
2183 error_collector = ErrorCollector(self.assert_)
2184 cpplint.ProcessFileData(
2185 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002186 ['// Copyright 2014 Your Company. All Rights Reserved.',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002187 'inline RCULocked<X>::ReadPtr::ReadPtr(const RCULocked* rcu) {',
2188 ' DCHECK(!(data & kFlagMask)) << "Error";',
2189 '}',
2190 '',
2191 'RCULocked<X>::WritePtr::WritePtr(RCULocked* rcu)',
2192 ' : lock_(&rcu_->mutex_) {',
2193 '}',
2194 ''],
2195 error_collector.Results())
2196 self.assertEquals('', error_collector.Results())
2197
erg@google.com4e00b9a2009-01-12 23:05:11 +00002198 def testBraceAtBeginOfLine(self):
2199 self.TestLint('{',
2200 '{ should almost always be at the end of the previous line'
2201 ' [whitespace/braces] [4]')
2202
erg@google.comd350fe52013-01-14 17:51:48 +00002203 error_collector = ErrorCollector(self.assert_)
2204 cpplint.ProcessFileData('foo.cc', 'cc',
2205 ['int function()',
2206 '{', # warning here
2207 ' MutexLock l(&mu);',
2208 '}',
2209 'int variable;'
2210 '{', # no warning
2211 ' MutexLock l(&mu);',
2212 '}',
erg@google.comc6671232013-10-25 21:44:03 +00002213 'MyType m = {',
2214 ' {value1, value2},',
2215 ' {', # no warning
2216 ' loooong_value1, looooong_value2',
2217 ' }',
2218 '};',
erg@google.comd350fe52013-01-14 17:51:48 +00002219 '#if PREPROCESSOR',
2220 '{', # no warning
2221 ' MutexLock l(&mu);',
2222 '}',
2223 '#endif'],
2224 error_collector)
2225 self.assertEquals(1, error_collector.Results().count(
2226 '{ should almost always be at the end of the previous line'
2227 ' [whitespace/braces] [4]'))
2228
erg@google.com2aa59982013-10-28 19:09:25 +00002229 self.TestMultiLineLint(
2230 """
2231 foo(
2232 {
2233 loooooooooooooooong_value,
2234 });""",
2235 '')
2236
erg@google.com4e00b9a2009-01-12 23:05:11 +00002237 def testMismatchingSpacesInParens(self):
2238 self.TestLint('if (foo ) {', 'Mismatching spaces inside () in if'
2239 ' [whitespace/parens] [5]')
2240 self.TestLint('switch ( foo) {', 'Mismatching spaces inside () in switch'
2241 ' [whitespace/parens] [5]')
erg@google.come35f7652009-06-19 20:52:09 +00002242 self.TestLint('for (foo; ba; bar ) {', 'Mismatching spaces inside () in for'
2243 ' [whitespace/parens] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002244 self.TestLint('for (; foo; bar) {', '')
2245 self.TestLint('for ( ; foo; bar) {', '')
2246 self.TestLint('for ( ; foo; bar ) {', '')
erg@google.come35f7652009-06-19 20:52:09 +00002247 self.TestLint('for (foo; bar; ) {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002248 self.TestLint('while ( foo ) {', 'Should have zero or one spaces inside'
2249 ' ( and ) in while [whitespace/parens] [5]')
2250
2251 def testSpacingForFncall(self):
2252 self.TestLint('if (foo) {', '')
erg@google.comd7d27472011-09-07 17:36:35 +00002253 self.TestLint('for (foo; bar; baz) {', '')
2254 self.TestLint('for (;;) {', '')
erg@google.comc6671232013-10-25 21:44:03 +00002255 # Space should be allowed in placement new operators.
2256 self.TestLint('Something* p = new (place) Something();', '')
erg@google.comd7d27472011-09-07 17:36:35 +00002257 # Test that there is no warning when increment statement is empty.
2258 self.TestLint('for (foo; baz;) {', '')
2259 self.TestLint('for (foo;bar;baz) {', 'Missing space after ;'
2260 ' [whitespace/semicolon] [3]')
2261 # we don't warn about this semicolon, at least for now
2262 self.TestLint('if (condition) {return &something; }',
2263 '')
2264 # seen in some macros
2265 self.TestLint('DoSth();\\', '')
2266 # Test that there is no warning about semicolon here.
2267 self.TestLint('abc;// this is abc',
2268 'At least two spaces is best between code'
2269 ' and comments [whitespace/comments] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002270 self.TestLint('while (foo) {', '')
2271 self.TestLint('switch (foo) {', '')
2272 self.TestLint('foo( bar)', 'Extra space after ( in function call'
2273 ' [whitespace/parens] [4]')
erg@google.comd7d27472011-09-07 17:36:35 +00002274 self.TestLint('foo( // comment', '')
2275 self.TestLint('foo( // comment',
2276 'At least two spaces is best between code'
2277 ' and comments [whitespace/comments] [2]')
erg@google.com36649102009-03-25 21:18:36 +00002278 self.TestLint('foobar( \\', '')
2279 self.TestLint('foobar( \\', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002280 self.TestLint('( a + b)', 'Extra space after ('
2281 ' [whitespace/parens] [2]')
2282 self.TestLint('((a+b))', '')
2283 self.TestLint('foo (foo)', 'Extra space before ( in function call'
2284 ' [whitespace/parens] [4]')
erg@google.comfd5da632013-10-25 17:39:45 +00002285 self.TestLint('} catch (const Foo& ex) {', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00002286 self.TestLint('case (42):', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002287 self.TestLint('typedef foo (*foo)(foo)', '')
2288 self.TestLint('typedef foo (*foo12bar_)(foo)', '')
2289 self.TestLint('typedef foo (Foo::*bar)(foo)', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002290 self.TestLint('using foo = type (Foo::*bar)(foo)', '')
2291 self.TestLint('using foo = type (Foo::*bar)(', '')
2292 self.TestLint('using foo = type (Foo::*)(', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002293 self.TestLint('foo (Foo::*bar)(', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002294 self.TestLint('foo (x::y::*z)(', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002295 self.TestLint('foo (Foo::bar)(',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002296 'Extra space before ( in function call'
2297 ' [whitespace/parens] [4]')
erg@google.comd350fe52013-01-14 17:51:48 +00002298 self.TestLint('foo (*bar)(', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002299 self.TestLint('typedef foo (Foo::*bar)(', '')
2300 self.TestLint('(foo)(bar)', '')
2301 self.TestLint('Foo (*foo)(bar)', '')
2302 self.TestLint('Foo (*foo)(Bar bar,', '')
2303 self.TestLint('char (*p)[sizeof(foo)] = &foo', '')
2304 self.TestLint('char (&ref)[sizeof(foo)] = &foo', '')
2305 self.TestLint('const char32 (*table[])[6];', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002306 # The sizeof operator is often written as if it were a function call, with
2307 # an opening parenthesis directly following the operator name, but it can
2308 # also be written like any other operator, with a space following the
2309 # operator name, and the argument optionally in parentheses.
2310 self.TestLint('sizeof(foo)', '')
2311 self.TestLint('sizeof foo', '')
2312 self.TestLint('sizeof (foo)', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002313
2314 def testSpacingBeforeBraces(self):
2315 self.TestLint('if (foo){', 'Missing space before {'
2316 ' [whitespace/braces] [5]')
2317 self.TestLint('for{', 'Missing space before {'
2318 ' [whitespace/braces] [5]')
2319 self.TestLint('for {', '')
2320 self.TestLint('EXPECT_DEBUG_DEATH({', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00002321 self.TestLint('std::is_convertible<A, B>{}', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002322
erg@google.comfd5da632013-10-25 17:39:45 +00002323 def testSemiColonAfterBraces(self):
2324 self.TestLint('if (cond) {};',
2325 'You don\'t need a ; after a } [readability/braces] [4]')
erg@google.com2aa59982013-10-28 19:09:25 +00002326 self.TestLint('void Func() {};',
2327 'You don\'t need a ; after a } [readability/braces] [4]')
2328 self.TestLint('void Func() const {};',
2329 'You don\'t need a ; after a } [readability/braces] [4]')
erg@google.comfd5da632013-10-25 17:39:45 +00002330 self.TestLint('class X {};', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00002331 for keyword in ['struct', 'union']:
2332 for align in ['', ' alignas(16)']:
2333 for typename in ['', ' X']:
2334 for identifier in ['', ' x']:
2335 self.TestLint(keyword + align + typename + ' {}' + identifier + ';',
2336 '')
erg@google.com2aa59982013-10-28 19:09:25 +00002337
2338 self.TestLint('class X : public Y {};', '')
2339 self.TestLint('class X : public MACRO() {};', '')
2340 self.TestLint('DEFINE_FACADE(PCQueue::Watcher, PCQueue) {};', '')
2341 self.TestLint('VCLASS(XfaTest, XfaContextTest) {};', '')
2342 self.TestLint('TEST(TestCase, TestName) {};',
2343 'You don\'t need a ; after a } [readability/braces] [4]')
2344 self.TestLint('TEST_F(TestCase, TestName) {};',
2345 'You don\'t need a ; after a } [readability/braces] [4]')
2346
2347 self.TestLint('file_tocs_[i] = (FileToc) {a, b, c};', '')
2348 self.TestMultiLineLint('class X : public Y,\npublic Z {};', '')
2349
avakulenko@google.com02af6282014-06-04 18:53:25 +00002350 def testLambda(self):
2351 self.TestLint('auto x = []() {};', '')
2352 self.TestLint('return []() {};', '')
2353 self.TestMultiLineLint('auto x = []() {\n};\n', '')
2354 self.TestLint('int operator[](int x) {};',
2355 'You don\'t need a ; after a } [readability/braces] [4]')
2356
2357 self.TestMultiLineLint('auto x = [&a,\nb]() {};', '')
2358 self.TestMultiLineLint('auto x = [&a,\nb]\n() {};', '')
2359 self.TestMultiLineLint('auto x = [&a,\n'
2360 ' b](\n'
2361 ' int a,\n'
2362 ' int b) {\n'
2363 ' return a +\n'
2364 ' b;\n'
2365 '};\n',
2366 '')
2367
2368 for lambda_with_default_capture in ('void f() { [=]{}; }',
2369 'void f() { [=](int i) {}; }',
2370 'void f() { [=, &x]{}; }',
2371 'void f() { [&]{}; }',
2372 'void f() { [ & ]{}; }',
2373 'void f() { [&, y]{}; }'):
2374 self.TestLint(lambda_with_default_capture,
2375 'Default lambda captures are an unapproved C++ feature. '
2376 '[build/c++11] [4]')
2377
2378 # "[&...]" isn't necessarily a default capture, though "[=...]" always is.
2379 self.TestLint('void f() { [&variable]{}; }', '')
2380
2381 # Avoid false positives with operator[]
2382 self.TestLint('table_to_children[&*table].push_back(dependent);', '')
2383
erg@google.com2aa59982013-10-28 19:09:25 +00002384 def testBraceInitializerList(self):
2385 self.TestLint('MyStruct p = {1, 2};', '')
2386 self.TestLint('MyStruct p{1, 2};', '')
2387 self.TestLint('vector<int> p = {1, 2};', '')
2388 self.TestLint('vector<int> p{1, 2};', '')
2389 self.TestLint('x = vector<int>{1, 2};', '')
2390 self.TestLint('x = (struct in_addr){ 0 };', '')
2391 self.TestLint('Func(vector<int>{1, 2})', '')
2392 self.TestLint('Func((struct in_addr){ 0 })', '')
2393 self.TestLint('Func(vector<int>{1, 2}, 3)', '')
2394 self.TestLint('Func((struct in_addr){ 0 }, 3)', '')
2395 self.TestLint('LOG(INFO) << char{7};', '')
2396 self.TestLint('LOG(INFO) << char{7} << "!";', '')
2397 self.TestLint('int p[2] = {1, 2};', '')
2398 self.TestLint('return {1, 2};', '')
2399 self.TestLint('std::unique_ptr<Foo> foo{new Foo{}};', '')
2400 self.TestLint('auto foo = std::unique_ptr<Foo>{new Foo{}};', '')
2401 self.TestLint('static_assert(Max7String{}.IsValid(), "");', '')
2402 self.TestLint('map_of_pairs[{1, 2}] = 3;', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002403 self.TestLint('ItemView{has_offer() ? new Offer{offer()} : nullptr', '')
2404 self.TestLint('template <class T, EnableIf<::std::is_const<T>{}> = 0>', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002405
2406 self.TestMultiLineLint('std::unique_ptr<Foo> foo{\n'
2407 ' new Foo{}\n'
2408 '};\n', '')
2409 self.TestMultiLineLint('std::unique_ptr<Foo> foo{\n'
2410 ' new Foo{\n'
2411 ' new Bar{}\n'
2412 ' }\n'
2413 '};\n', '')
2414 self.TestMultiLineLint('if (true) {\n'
2415 ' if (false){}\n'
2416 '}\n',
2417 'Missing space before { [whitespace/braces] [5]')
2418 self.TestMultiLineLint('MyClass::MyClass()\n'
2419 ' : initializer_{\n'
2420 ' Func()} {\n'
2421 '}\n', '')
erg@google.comfd5da632013-10-25 17:39:45 +00002422
erg@google.com4e00b9a2009-01-12 23:05:11 +00002423 def testSpacingAroundElse(self):
2424 self.TestLint('}else {', 'Missing space before else'
2425 ' [whitespace/braces] [5]')
2426 self.TestLint('} else{', 'Missing space before {'
2427 ' [whitespace/braces] [5]')
2428 self.TestLint('} else {', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002429 self.TestLint('} else if (foo) {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002430
erg@google.com8a95ecc2011-09-08 00:45:54 +00002431 def testSpacingWithInitializerLists(self):
2432 self.TestLint('int v[1][3] = {{1, 2, 3}};', '')
2433 self.TestLint('int v[1][1] = {{0}};', '')
2434
erg@google.com4e00b9a2009-01-12 23:05:11 +00002435 def testSpacingForBinaryOps(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00002436 self.TestLint('if (foo||bar) {', 'Missing spaces around ||'
2437 ' [whitespace/operators] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002438 self.TestLint('if (foo<=bar) {', 'Missing spaces around <='
2439 ' [whitespace/operators] [3]')
2440 self.TestLint('if (foo<bar) {', 'Missing spaces around <'
2441 ' [whitespace/operators] [3]')
erg@google.comd350fe52013-01-14 17:51:48 +00002442 self.TestLint('if (foo>bar) {', 'Missing spaces around >'
2443 ' [whitespace/operators] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002444 self.TestLint('if (foo<bar->baz) {', 'Missing spaces around <'
2445 ' [whitespace/operators] [3]')
2446 self.TestLint('if (foo<bar->bar) {', 'Missing spaces around <'
2447 ' [whitespace/operators] [3]')
erg@google.comd350fe52013-01-14 17:51:48 +00002448 self.TestLint('template<typename T = double>', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002449 self.TestLint('std::unique_ptr<No<Spaces>>', '')
2450 self.TestLint('typedef hash_map<Foo, Bar>', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002451 self.TestLint('10<<20', '')
2452 self.TestLint('10<<a',
2453 'Missing spaces around << [whitespace/operators] [3]')
2454 self.TestLint('a<<20',
2455 'Missing spaces around << [whitespace/operators] [3]')
2456 self.TestLint('a<<b',
2457 'Missing spaces around << [whitespace/operators] [3]')
2458 self.TestLint('10ULL<<20', '')
2459 self.TestLint('a>>b',
2460 'Missing spaces around >> [whitespace/operators] [3]')
2461 self.TestLint('10>>b',
2462 'Missing spaces around >> [whitespace/operators] [3]')
2463 self.TestLint('LOG(ERROR)<<*foo',
2464 'Missing spaces around << [whitespace/operators] [3]')
2465 self.TestLint('LOG(ERROR)<<&foo',
2466 'Missing spaces around << [whitespace/operators] [3]')
2467 self.TestLint('StringCoder<vector<string>>::ToString()', '')
2468 self.TestLint('map<pair<int, int>, map<int, int>>::iterator', '')
2469 self.TestLint('func<int, pair<int, pair<int, int>>>()', '')
2470 self.TestLint('MACRO1(list<list<int>>)', '')
2471 self.TestLint('MACRO2(list<list<int>>, 42)', '')
2472 self.TestLint('void DoFoo(const set<vector<string>>& arg1);', '')
2473 self.TestLint('void SetFoo(set<vector<string>>* arg1);', '')
2474 self.TestLint('foo = new set<vector<string>>;', '')
2475 self.TestLint('reinterpret_cast<set<vector<string>>*>(a);', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002476 self.TestLint('MACRO(<<)', '')
2477 self.TestLint('MACRO(<<, arg)', '')
2478 self.TestLint('MACRO(<<=)', '')
2479 self.TestLint('MACRO(<<=, arg)', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002480
avakulenko@google.com02af6282014-06-04 18:53:25 +00002481 self.TestLint('using Vector3<T>::operator==;', '')
2482 self.TestLint('using Vector3<T>::operator!=;', '')
2483
2484 def testRvalueReference(self):
2485 space_error = 'Missing spaces around && [whitespace/operators] [3]'
2486 rvalue_error = ('RValue references are an unapproved C++ feature.'
2487 ' [build/c++11] [3]')
2488
2489 # Places where lack of space are allowed
2490 self.TestLint('DEFINE_BINARY_OPERATOR(&&)', '')
2491 self.TestLint('bool operator&&(A b) {}', '')
2492 self.TestLint('bool operator&&(A b) {', '')
2493 self.TestLint('bool operator&&(A b);', '')
2494
2495 # Assignment expressions
2496 self.TestLint('a = b && c;', '')
2497 self.TestLint('a = b&& c;', space_error)
2498 self.TestLint('a = b &&c;', space_error)
2499 self.TestLint('a = (b&& c);', space_error)
2500 self.TestLint('a = (b &&c);', space_error)
2501 self.TestLint('a&& b = c;', rvalue_error)
2502 self.TestLint('a<b>&& c = d;', rvalue_error)
2503 self.TestLint('auto&& a = b;', rvalue_error)
2504 self.TestLint('const a&& b = c;', rvalue_error)
2505 self.TestLint('struct a&& b = c;', rvalue_error)
2506 self.TestLint('decltype(a)&& b = c;', rvalue_error)
2507
2508 # Cast expressions
2509 self.TestLint('a = const_cast<b&&>(c);', rvalue_error)
2510 self.TestLint('a = const_cast<const b&&>(c);', rvalue_error)
2511 self.TestLint('a = static_cast<b&&>(c);', rvalue_error)
2512 self.TestLint('a = static_cast<const b&&>(c);', rvalue_error)
2513 self.TestLint('a = dynamic_cast<b&&>(c);', rvalue_error)
2514 self.TestLint('a = dynamic_cast<const b&&>(c);', rvalue_error)
2515 self.TestLint('a = reinterpret_cast<b&&>(c);', rvalue_error)
2516 self.TestLint('a = reinterpret_cast<const b&&>(c);', rvalue_error)
2517 self.TestLint('a = cast < b&& c;', space_error)
2518
2519 # Function parameters
avakulenko@google.com554223d2014-12-04 22:00:20 +00002520 for indent in ['', ' ']:
2521 for head in ['void Func', 'vector<int> Func', 'vector<int>\nFunc',
2522 'inline void Func',
2523 'Constructor', 'Constructor::Constructor',
2524 'operator=', 'operator =', 'operator = ']:
2525 for body in [' {}', ' {', ';']:
2526 self.TestMultiLineLint(indent + head + '(A&& b)' + body, rvalue_error)
2527 self.TestMultiLineLint(indent + head + '(A &&b)' + body, rvalue_error)
2528 self.TestMultiLineLint(indent + head + '(A&&... b)' + body,
2529 rvalue_error)
2530 self.TestMultiLineLint(indent + head + '(A<B>&& c)' + body,
2531 rvalue_error)
2532 self.TestMultiLineLint(indent + head + '(A<B> &&c)' + body,
2533 rvalue_error)
avakulenko@google.com02af6282014-06-04 18:53:25 +00002534
2535 # Function templates
2536 self.TestLint('std::conditional<A, B&, C&&>::type', rvalue_error)
2537 self.TestLint('std::conditional<A, B&&, C&>::type', rvalue_error)
2538
2539 # Template functions
2540 self.TestLint('template <typename T> R&& F()', rvalue_error)
2541 self.TestLint('template <typename T> R&& F() {', rvalue_error)
2542 self.TestMultiLineLint('template <typename T>\nR&& F()', rvalue_error)
2543 self.TestMultiLineLint('template <typename T>\nR&& F() {', rvalue_error)
avakulenko@google.com554223d2014-12-04 22:00:20 +00002544 self.TestLint('template <typename T> void F(T a, R&& b)', rvalue_error)
2545 self.TestLint('template <typename T> void F(T a, R &&b)', rvalue_error)
2546 self.TestLint('template <typename T> void F(T a, R&& b) {', rvalue_error)
avakulenko@google.com02af6282014-06-04 18:53:25 +00002547
2548 # For loops
2549 self.TestLint('for (a&& b;;)', rvalue_error)
2550 self.TestLint('for (a&& b;;) {', rvalue_error)
2551 self.TestLint('for (; a&& b;)', space_error)
2552 self.TestLint('for (; a&& b;) {', space_error)
2553
2554 # Constructors
2555 self.TestLint('A(a&& b)', rvalue_error)
2556 self.TestLint('explicit A(a&& b)', rvalue_error)
2557 self.TestLint('A(a b) : c(d&& e)', space_error)
2558 self.TestLint('A(a b) : c(), d(e&& f)', space_error)
2559
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002560 def testAllowedRvalueReference(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00002561 # Verify that RValue reference warnings for a line range can be silenced
2562 error_collector = ErrorCollector(self.assert_)
2563 cpplint.ProcessFileData('foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002564 ['// Copyright 2014 Your Company.',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002565 'GOOGLE_ALLOW_RVALUE_REFERENCES_PUSH',
2566 'void F(A&& b);',
2567 'GOOGLE_ALLOW_RVALUE_REFERENCES_POP',
2568 ''],
2569 error_collector)
2570 self.assertEquals(error_collector.Results(), '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002571
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002572 # RValue references for constructors and operator=
2573 error_collector = ErrorCollector(self.assert_)
2574 cpplint.ProcessFileData(
2575 'foo.cc', 'cc',
2576 ['// Copyright 2014 Your Company.',
2577 'class X {',
2578 ' X(X&& param) = delete; // NOLINT(runtime/explicit)',
2579 ' X(X &&param) = default; // NOLINT(runtime/explicit)',
avakulenko@google.com554223d2014-12-04 22:00:20 +00002580 ' inline X(X&& param) = default; // NOLINT(runtime/explicit)',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002581 '',
2582 ' X& operator=(X&& param) = delete;',
avakulenko@google.com554223d2014-12-04 22:00:20 +00002583 ' X& operator=(X&& param) = default;',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002584 '};',
avakulenko@google.com554223d2014-12-04 22:00:20 +00002585 'A::A(A&&) = default;',
2586 'Outer::Inner::Inner(Inner&&) = default;',
2587 ''],
2588 error_collector)
2589 self.assertEquals(error_collector.Results(), '')
2590
2591 # Assume templated function parameters are forwarded, and are allowed
2592 error_collector = ErrorCollector(self.assert_)
2593 cpplint.ProcessFileData(
2594 'foo.cc', 'cc',
2595 ['// Copyright 2014 Your Company.',
2596 'template <typename Allowed1>',
2597 'void Function1(Allowed1&& a);',
2598 '',
2599 'template <typename Allowed2, typename Allowed3>',
2600 'void Function2(Allowed2&& a, Allowed3 &&b) {',
2601 '}',
2602 '',
2603 'template <class Allowed4>',
2604 'void Function3(Ignored1 *a, Allowed4&& b) {',
2605 '}',
2606 '',
2607 'template <typename... Allowed5>',
2608 'void Function4(Allowed5&&... a) {',
2609 '}',
2610 '',
2611 'template <class... Allowed6>',
2612 'void Function5(',
2613 ' Allowed6 &&...a) {',
2614 '}',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002615 ''],
2616 error_collector)
2617 self.assertEquals(error_collector.Results(), '')
2618
erg@google.com4e00b9a2009-01-12 23:05:11 +00002619 def testSpacingBeforeLastSemicolon(self):
2620 self.TestLint('call_function() ;',
2621 'Extra space before last semicolon. If this should be an '
erg@google.comd350fe52013-01-14 17:51:48 +00002622 'empty statement, use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002623 ' [whitespace/semicolon] [5]')
2624 self.TestLint('while (true) ;',
2625 'Extra space before last semicolon. If this should be an '
erg@google.comd350fe52013-01-14 17:51:48 +00002626 'empty statement, use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002627 ' [whitespace/semicolon] [5]')
2628 self.TestLint('default:;',
erg@google.comd350fe52013-01-14 17:51:48 +00002629 'Semicolon defining empty statement. Use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002630 ' [whitespace/semicolon] [5]')
2631 self.TestLint(' ;',
2632 'Line contains only semicolon. If this should be an empty '
erg@google.comd350fe52013-01-14 17:51:48 +00002633 'statement, use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002634 ' [whitespace/semicolon] [5]')
2635 self.TestLint('for (int i = 0; ;', '')
2636
erg@google.comc6671232013-10-25 21:44:03 +00002637 def testEmptyBlockBody(self):
erg@google.comd350fe52013-01-14 17:51:48 +00002638 self.TestLint('while (true);',
2639 'Empty loop bodies should use {} or continue'
2640 ' [whitespace/empty_loop_body] [5]')
erg@google.comc6671232013-10-25 21:44:03 +00002641 self.TestLint('if (true);',
2642 'Empty conditional bodies should use {}'
2643 ' [whitespace/empty_conditional_body] [5]')
erg@google.comd350fe52013-01-14 17:51:48 +00002644 self.TestLint('while (true)', '')
2645 self.TestLint('while (true) continue;', '')
2646 self.TestLint('for (;;);',
2647 'Empty loop bodies should use {} or continue'
2648 ' [whitespace/empty_loop_body] [5]')
2649 self.TestLint('for (;;)', '')
2650 self.TestLint('for (;;) continue;', '')
2651 self.TestLint('for (;;) func();', '')
2652 self.TestMultiLineLint("""while (true &&
2653 false);""",
2654 'Empty loop bodies should use {} or continue'
2655 ' [whitespace/empty_loop_body] [5]')
2656 self.TestMultiLineLint("""do {
2657 } while (false);""",
2658 '')
2659 self.TestMultiLineLint("""#define MACRO \\
2660 do { \\
2661 } while (false);""",
2662 '')
2663 self.TestMultiLineLint("""do {
2664 } while (false); // next line gets a warning
2665 while (false);""",
2666 'Empty loop bodies should use {} or continue'
2667 ' [whitespace/empty_loop_body] [5]')
2668
2669 def testSpacingForRangeBasedFor(self):
2670 # Basic correctly formatted case:
2671 self.TestLint('for (int i : numbers) {', '')
2672
2673 # Missing space before colon:
2674 self.TestLint('for (int i: numbers) {',
2675 'Missing space around colon in range-based for loop'
2676 ' [whitespace/forcolon] [2]')
2677 # Missing space after colon:
2678 self.TestLint('for (int i :numbers) {',
2679 'Missing space around colon in range-based for loop'
2680 ' [whitespace/forcolon] [2]')
2681 # Missing spaces both before and after the colon.
2682 self.TestLint('for (int i:numbers) {',
2683 'Missing space around colon in range-based for loop'
2684 ' [whitespace/forcolon] [2]')
2685
2686 # The scope operator '::' shouldn't cause warnings...
2687 self.TestLint('for (std::size_t i : sizes) {}', '')
2688 # ...but it shouldn't suppress them either.
2689 self.TestLint('for (std::size_t i: sizes) {}',
2690 'Missing space around colon in range-based for loop'
2691 ' [whitespace/forcolon] [2]')
2692
2693
erg@google.com4e00b9a2009-01-12 23:05:11 +00002694 # Static or global STL strings.
2695 def testStaticOrGlobalSTLStrings(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002696 error_msg = ('For a static/global string constant, use a C style '
2697 'string instead: "%s[]". [runtime/string] [4]')
2698
erg@google.com4e00b9a2009-01-12 23:05:11 +00002699 self.TestLint('string foo;',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002700 error_msg % 'char foo')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002701 self.TestLint('string kFoo = "hello"; // English',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002702 error_msg % 'char kFoo')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002703 self.TestLint('static string foo;',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002704 error_msg % 'static char foo')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002705 self.TestLint('static const string foo;',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002706 error_msg % 'static const char foo')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002707 self.TestLint('string Foo::bar;',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002708 error_msg % 'char Foo::bar')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002709 self.TestLint('string* pointer', '')
2710 self.TestLint('string *pointer', '')
2711 self.TestLint('string* pointer = Func();', '')
2712 self.TestLint('string *pointer = Func();', '')
2713 self.TestLint('const string* pointer', '')
2714 self.TestLint('const string *pointer', '')
2715 self.TestLint('const string* pointer = Func();', '')
2716 self.TestLint('const string *pointer = Func();', '')
2717 self.TestLint('string const* pointer', '')
2718 self.TestLint('string const *pointer', '')
2719 self.TestLint('string const* pointer = Func();', '')
2720 self.TestLint('string const *pointer = Func();', '')
2721 self.TestLint('string* const pointer', '')
2722 self.TestLint('string *const pointer', '')
2723 self.TestLint('string* const pointer = Func();', '')
2724 self.TestLint('string *const pointer = Func();', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002725 self.TestLint('string Foo::bar() {}', '')
2726 self.TestLint('string Foo::operator*() {}', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002727 # Rare case.
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002728 self.TestLint('string foo("foobar");', error_msg % 'char foo')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002729 # Should not catch local or member variables.
2730 self.TestLint(' string foo', '')
2731 # Should not catch functions.
2732 self.TestLint('string EmptyString() { return ""; }', '')
2733 self.TestLint('string EmptyString () { return ""; }', '')
2734 self.TestLint('string VeryLongNameFunctionSometimesEndsWith(\n'
2735 ' VeryLongNameType very_long_name_variable) {}', '')
2736 self.TestLint('template<>\n'
2737 'string FunctionTemplateSpecialization<SomeType>(\n'
2738 ' int x) { return ""; }', '')
2739 self.TestLint('template<>\n'
2740 'string FunctionTemplateSpecialization<vector<A::B>* >(\n'
2741 ' int x) { return ""; }', '')
2742
2743 # should not catch methods of template classes.
2744 self.TestLint('string Class<Type>::Method() const {\n'
2745 ' return "";\n'
2746 '}\n', '')
2747 self.TestLint('string Class<Type>::Method(\n'
2748 ' int arg) const {\n'
2749 ' return "";\n'
2750 '}\n', '')
2751
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002752 # Check multiline cases.
2753 error_collector = ErrorCollector(self.assert_)
2754 cpplint.ProcessFileData('foo.cc', 'cc',
2755 ['// Copyright 2014 Your Company.',
2756 'string Class',
2757 '::MemberFunction1();',
2758 'string Class::',
2759 'MemberFunction2();',
2760 'string Class::',
2761 'NestedClass::MemberFunction3();',
2762 'string TemplateClass<T>::',
2763 'NestedClass::MemberFunction4();',
2764 'string Class',
2765 '::static_member_variable1;',
2766 'string Class::',
2767 'static_member_variable2;',
2768 'string Class',
2769 '::static_member_variable3 = "initial value";',
2770 'string Class::',
2771 'static_member_variable4 = "initial value";',
2772 ''],
2773 error_collector)
2774 self.assertEquals(error_collector.Results(),
2775 [error_msg % 'char Class::static_member_variable1',
2776 error_msg % 'char Class::static_member_variable2',
2777 error_msg % 'char Class::static_member_variable3',
2778 error_msg % 'char Class::static_member_variable4'])
2779
erg@google.com4e00b9a2009-01-12 23:05:11 +00002780 def testNoSpacesInFunctionCalls(self):
2781 self.TestLint('TellStory(1, 3);',
2782 '')
2783 self.TestLint('TellStory(1, 3 );',
2784 'Extra space before )'
2785 ' [whitespace/parens] [2]')
2786 self.TestLint('TellStory(1 /* wolf */, 3 /* pigs */);',
2787 '')
erg@google.com8a95ecc2011-09-08 00:45:54 +00002788 self.TestMultiLineLint("""TellStory(1, 3
2789 );""",
2790 'Closing ) should be moved to the previous line'
2791 ' [whitespace/parens] [2]')
2792 self.TestMultiLineLint("""TellStory(Wolves(1),
2793 Pigs(3
2794 ));""",
2795 'Closing ) should be moved to the previous line'
2796 ' [whitespace/parens] [2]')
2797 self.TestMultiLineLint("""TellStory(1,
2798 3 );""",
2799 'Extra space before )'
2800 ' [whitespace/parens] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002801
2802 def testToDoComments(self):
2803 start_space = ('Too many spaces before TODO'
2804 ' [whitespace/todo] [2]')
2805 missing_username = ('Missing username in TODO; it should look like '
2806 '"// TODO(my_username): Stuff."'
2807 ' [readability/todo] [2]')
2808 end_space = ('TODO(my_username) should be followed by a space'
2809 ' [whitespace/todo] [2]')
2810
2811 self.TestLint('// TODOfix this',
2812 [start_space, missing_username, end_space])
2813 self.TestLint('// TODO(ljenkins)fix this',
2814 [start_space, end_space])
2815 self.TestLint('// TODO fix this',
2816 [start_space, missing_username])
2817 self.TestLint('// TODO fix this', missing_username)
2818 self.TestLint('// TODO: fix this', missing_username)
2819 self.TestLint('//TODO(ljenkins): Fix this',
2820 'Should have a space between // and comment'
2821 ' [whitespace/comments] [4]')
2822 self.TestLint('// TODO(ljenkins):Fix this', end_space)
2823 self.TestLint('// TODO(ljenkins):', '')
2824 self.TestLint('// TODO(ljenkins): fix this', '')
2825 self.TestLint('// TODO(ljenkins): Fix this', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002826 self.TestLint('#if 1 // TEST_URLTODOCID_WHICH_HAS_THAT_WORD_IN_IT_H_', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002827 self.TestLint('// See also similar TODO above', '')
2828
2829 def testTwoSpacesBetweenCodeAndComments(self):
2830 self.TestLint('} // namespace foo',
2831 'At least two spaces is best between code and comments'
2832 ' [whitespace/comments] [2]')
2833 self.TestLint('}// namespace foo',
2834 'At least two spaces is best between code and comments'
2835 ' [whitespace/comments] [2]')
2836 self.TestLint('printf("foo"); // Outside quotes.',
2837 'At least two spaces is best between code and comments'
2838 ' [whitespace/comments] [2]')
2839 self.TestLint('int i = 0; // Having two spaces is fine.', '')
2840 self.TestLint('int i = 0; // Having three spaces is OK.', '')
2841 self.TestLint('// Top level comment', '')
2842 self.TestLint(' // Line starts with two spaces.', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002843 self.TestMultiLineLint('void foo() {\n'
2844 ' { // A scope is opening.\n'
2845 ' int a;', '')
2846 self.TestMultiLineLint('void foo() {\n'
2847 ' { // A scope is opening.\n'
2848 '#define A a',
2849 'At least two spaces is best between code and '
2850 'comments [whitespace/comments] [2]')
2851 self.TestMultiLineLint(' foo();\n'
2852 ' { // An indented scope is opening.\n'
2853 ' int a;', '')
2854 self.TestMultiLineLint('vector<int> my_elements = {// first\n'
2855 ' 1,', '')
2856 self.TestMultiLineLint('vector<int> my_elements = {// my_elements is ..\n'
2857 ' 1,',
2858 'At least two spaces is best between code and '
2859 'comments [whitespace/comments] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002860 self.TestLint('if (foo) { // not a pure scope; comment is too close!',
2861 'At least two spaces is best between code and comments'
2862 ' [whitespace/comments] [2]')
2863 self.TestLint('printf("// In quotes.")', '')
2864 self.TestLint('printf("\\"%s // In quotes.")', '')
2865 self.TestLint('printf("%s", "// In quotes.")', '')
2866
2867 def testSpaceAfterCommentMarker(self):
2868 self.TestLint('//', '')
2869 self.TestLint('//x', 'Should have a space between // and comment'
2870 ' [whitespace/comments] [4]')
2871 self.TestLint('// x', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00002872 self.TestLint('///', '')
2873 self.TestLint('/// x', '')
2874 self.TestLint('//!', '')
erg@google.come35f7652009-06-19 20:52:09 +00002875 self.TestLint('//----', '')
2876 self.TestLint('//====', '')
2877 self.TestLint('//////', '')
2878 self.TestLint('////// x', '')
erg@google.com6d8d9832013-10-31 19:46:18 +00002879 self.TestLint('///< x', '') # After-member Doxygen comment
2880 self.TestLint('//!< x', '') # After-member Doxygen comment
erg@google.come35f7652009-06-19 20:52:09 +00002881 self.TestLint('////x', 'Should have a space between // and comment'
2882 ' [whitespace/comments] [4]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002883 self.TestLint('//}', '')
2884 self.TestLint('//}x', 'Should have a space between // and comment'
2885 ' [whitespace/comments] [4]')
erg@google.com6d8d9832013-10-31 19:46:18 +00002886 self.TestLint('//!<x', 'Should have a space between // and comment'
2887 ' [whitespace/comments] [4]')
2888 self.TestLint('///<x', 'Should have a space between // and comment'
2889 ' [whitespace/comments] [4]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002890
2891 # Test a line preceded by empty or comment lines. There was a bug
2892 # that caused it to print the same warning N times if the erroneous
2893 # line was preceded by N lines of empty or comment lines. To be
2894 # precise, the '// marker so line numbers and indices both start at
2895 # 1' line was also causing the issue.
2896 def testLinePrecededByEmptyOrCommentLines(self):
2897 def DoTest(self, lines):
2898 error_collector = ErrorCollector(self.assert_)
2899 cpplint.ProcessFileData('foo.cc', 'cc', lines, error_collector)
2900 # The warning appears only once.
2901 self.assertEquals(
2902 1,
2903 error_collector.Results().count(
2904 'Do not use namespace using-directives. '
2905 'Use using-declarations instead.'
2906 ' [build/namespaces] [5]'))
2907 DoTest(self, ['using namespace foo;'])
2908 DoTest(self, ['', '', '', 'using namespace foo;'])
2909 DoTest(self, ['// hello', 'using namespace foo;'])
2910
2911 def testNewlineAtEOF(self):
2912 def DoTest(self, data, is_missing_eof):
2913 error_collector = ErrorCollector(self.assert_)
2914 cpplint.ProcessFileData('foo.cc', 'cc', data.split('\n'),
2915 error_collector)
2916 # The warning appears only once.
2917 self.assertEquals(
2918 int(is_missing_eof),
2919 error_collector.Results().count(
2920 'Could not find a newline character at the end of the file.'
2921 ' [whitespace/ending_newline] [5]'))
2922
2923 DoTest(self, '// Newline\n// at EOF\n', False)
2924 DoTest(self, '// No newline\n// at EOF', True)
2925
2926 def testInvalidUtf8(self):
2927 def DoTest(self, raw_bytes, has_invalid_utf8):
2928 error_collector = ErrorCollector(self.assert_)
2929 cpplint.ProcessFileData(
2930 'foo.cc', 'cc',
2931 unicode(raw_bytes, 'utf8', 'replace').split('\n'),
2932 error_collector)
2933 # The warning appears only once.
2934 self.assertEquals(
2935 int(has_invalid_utf8),
2936 error_collector.Results().count(
2937 'Line contains invalid UTF-8'
2938 ' (or Unicode replacement character).'
2939 ' [readability/utf8] [5]'))
2940
2941 DoTest(self, 'Hello world\n', False)
2942 DoTest(self, '\xe9\x8e\xbd\n', False)
2943 DoTest(self, '\xe9x\x8e\xbd\n', True)
2944 # This is the encoding of the replacement character itself (which
2945 # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')).
2946 DoTest(self, '\xef\xbf\xbd\n', True)
2947
erg@google.com2aa59982013-10-28 19:09:25 +00002948 def testBadCharacters(self):
2949 # Test for NUL bytes only
2950 error_collector = ErrorCollector(self.assert_)
2951 cpplint.ProcessFileData('nul.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002952 ['// Copyright 2014 Your Company.',
erg@google.com2aa59982013-10-28 19:09:25 +00002953 '\0', ''], error_collector)
2954 self.assertEquals(
2955 error_collector.Results(),
2956 'Line contains NUL byte. [readability/nul] [5]')
2957
2958 # Make sure both NUL bytes and UTF-8 are caught if they appear on
2959 # the same line.
2960 error_collector = ErrorCollector(self.assert_)
2961 cpplint.ProcessFileData(
2962 'nul_utf8.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002963 ['// Copyright 2014 Your Company.',
erg@google.com2aa59982013-10-28 19:09:25 +00002964 unicode('\xe9x\0', 'utf8', 'replace'), ''],
2965 error_collector)
2966 self.assertEquals(
2967 error_collector.Results(),
2968 ['Line contains invalid UTF-8 (or Unicode replacement character).'
2969 ' [readability/utf8] [5]',
2970 'Line contains NUL byte. [readability/nul] [5]'])
2971
erg@google.com4e00b9a2009-01-12 23:05:11 +00002972 def testIsBlankLine(self):
2973 self.assert_(cpplint.IsBlankLine(''))
2974 self.assert_(cpplint.IsBlankLine(' '))
2975 self.assert_(cpplint.IsBlankLine(' \t\r\n'))
2976 self.assert_(not cpplint.IsBlankLine('int a;'))
2977 self.assert_(not cpplint.IsBlankLine('{'))
2978
2979 def testBlankLinesCheck(self):
2980 self.TestBlankLinesCheck(['{\n', '\n', '\n', '}\n'], 1, 1)
2981 self.TestBlankLinesCheck([' if (foo) {\n', '\n', ' }\n'], 1, 1)
2982 self.TestBlankLinesCheck(
2983 ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0)
2984 self.TestBlankLinesCheck(['\n', 'run("{");\n', '\n'], 0, 0)
2985 self.TestBlankLinesCheck(['\n', ' if (foo) { return 0; }\n', '\n'], 0, 0)
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002986 self.TestBlankLinesCheck(
2987 ['int x(\n', ' int a) {\n', '\n', 'return 0;\n', '}'], 0, 0)
2988 self.TestBlankLinesCheck(
2989 ['int x(\n', ' int a) const {\n', '\n', 'return 0;\n', '}'], 0, 0)
2990 self.TestBlankLinesCheck(
2991 ['int x(\n', ' int a) {\n', '\n', 'return 0;\n', '}'], 1, 0)
2992 self.TestBlankLinesCheck(
2993 ['int x(\n', ' int a) {\n', '\n', 'return 0;\n', '}'], 1, 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00002994
2995 def testAllowBlankLineBeforeClosingNamespace(self):
2996 error_collector = ErrorCollector(self.assert_)
2997 cpplint.ProcessFileData('foo.cc', 'cc',
erg@google.comd350fe52013-01-14 17:51:48 +00002998 ['namespace {',
2999 '',
3000 '} // namespace',
3001 'namespace another_namespace {',
3002 '',
3003 '}',
3004 'namespace {',
3005 '',
3006 'template<class T, ',
3007 ' class A = hoge<T>, ',
3008 ' class B = piyo<T>, ',
3009 ' class C = fuga<T> >',
3010 'class D {',
3011 ' public:',
3012 '};',
3013 '', '', '', '',
3014 '}'],
erg@google.com4e00b9a2009-01-12 23:05:11 +00003015 error_collector)
3016 self.assertEquals(0, error_collector.Results().count(
erg@google.com2aa59982013-10-28 19:09:25 +00003017 'Redundant blank line at the end of a code block should be deleted.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00003018 ' [whitespace/blank_line] [3]'))
3019
3020 def testAllowBlankLineBeforeIfElseChain(self):
3021 error_collector = ErrorCollector(self.assert_)
3022 cpplint.ProcessFileData('foo.cc', 'cc',
3023 ['if (hoge) {',
3024 '', # No warning
3025 '} else if (piyo) {',
3026 '', # No warning
3027 '} else if (piyopiyo) {',
3028 ' hoge = true;', # No warning
3029 '} else {',
3030 '', # Warning on this line
3031 '}'],
3032 error_collector)
3033 self.assertEquals(1, error_collector.Results().count(
erg@google.com2aa59982013-10-28 19:09:25 +00003034 'Redundant blank line at the end of a code block should be deleted.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00003035 ' [whitespace/blank_line] [3]'))
3036
avakulenko@google.com02af6282014-06-04 18:53:25 +00003037 def testAllowBlankLineAfterExtern(self):
3038 error_collector = ErrorCollector(self.assert_)
3039 cpplint.ProcessFileData('foo.cc', 'cc',
3040 ['extern "C" {',
3041 '',
3042 'EXPORTAPI void APICALL Some_function() {}',
3043 '',
3044 '}'],
3045 error_collector)
3046 self.assertEquals(0, error_collector.Results().count(
3047 'Redundant blank line at the start of a code block should be deleted.'
3048 ' [whitespace/blank_line] [2]'))
3049 self.assertEquals(0, error_collector.Results().count(
3050 'Redundant blank line at the end of a code block should be deleted.'
3051 ' [whitespace/blank_line] [3]'))
3052
erg@google.com8a95ecc2011-09-08 00:45:54 +00003053 def testBlankLineBeforeSectionKeyword(self):
3054 error_collector = ErrorCollector(self.assert_)
3055 cpplint.ProcessFileData('foo.cc', 'cc',
3056 ['class A {',
3057 ' public:',
3058 ' protected:', # warning 1
3059 ' private:', # warning 2
3060 ' struct B {',
3061 ' public:',
3062 ' private:'] + # warning 3
3063 ([''] * 100) + # Make A and B longer than 100 lines
3064 [' };',
3065 ' struct C {',
3066 ' protected:',
3067 ' private:', # C is too short for warnings
3068 ' };',
3069 '};',
3070 'class D',
3071 ' : public {',
3072 ' public:', # no warning
erg@google.comd350fe52013-01-14 17:51:48 +00003073 '};',
3074 'class E {\\',
3075 ' public:\\'] +
3076 (['\\'] * 100) + # Makes E > 100 lines
3077 [' int non_empty_line;\\',
3078 ' private:\\', # no warning
3079 ' int a;\\',
erg@google.com8a95ecc2011-09-08 00:45:54 +00003080 '};'],
3081 error_collector)
3082 self.assertEquals(2, error_collector.Results().count(
3083 '"private:" should be preceded by a blank line'
3084 ' [whitespace/blank_line] [3]'))
3085 self.assertEquals(1, error_collector.Results().count(
3086 '"protected:" should be preceded by a blank line'
3087 ' [whitespace/blank_line] [3]'))
3088
3089 def testNoBlankLineAfterSectionKeyword(self):
3090 error_collector = ErrorCollector(self.assert_)
3091 cpplint.ProcessFileData('foo.cc', 'cc',
3092 ['class A {',
3093 ' public:',
3094 '', # warning 1
3095 ' private:',
3096 '', # warning 2
3097 ' struct B {',
3098 ' protected:',
3099 '', # warning 3
3100 ' };',
3101 '};'],
3102 error_collector)
3103 self.assertEquals(1, error_collector.Results().count(
3104 'Do not leave a blank line after "public:"'
3105 ' [whitespace/blank_line] [3]'))
3106 self.assertEquals(1, error_collector.Results().count(
3107 'Do not leave a blank line after "protected:"'
3108 ' [whitespace/blank_line] [3]'))
3109 self.assertEquals(1, error_collector.Results().count(
3110 'Do not leave a blank line after "private:"'
3111 ' [whitespace/blank_line] [3]'))
3112
avakulenko@google.com02af6282014-06-04 18:53:25 +00003113 def testAllowBlankLinesInRawStrings(self):
3114 error_collector = ErrorCollector(self.assert_)
3115 cpplint.ProcessFileData('foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003116 ['// Copyright 2014 Your Company.',
avakulenko@google.com02af6282014-06-04 18:53:25 +00003117 'static const char *kData[] = {R"(',
3118 '',
3119 ')", R"(',
3120 '',
3121 ')"};',
3122 ''],
3123 error_collector)
3124 self.assertEquals('', error_collector.Results())
3125
erg@google.com4e00b9a2009-01-12 23:05:11 +00003126 def testElseOnSameLineAsClosingBraces(self):
3127 error_collector = ErrorCollector(self.assert_)
3128 cpplint.ProcessFileData('foo.cc', 'cc',
3129 ['if (hoge) {',
avakulenko@google.com02af6282014-06-04 18:53:25 +00003130 '}',
3131 'else if (piyo) {', # Warning on this line
erg@google.com4e00b9a2009-01-12 23:05:11 +00003132 '}',
3133 ' else {' # Warning on this line
3134 '',
3135 '}'],
3136 error_collector)
avakulenko@google.com02af6282014-06-04 18:53:25 +00003137 self.assertEquals(2, error_collector.Results().count(
3138 'An else should appear on the same line as the preceding }'
3139 ' [whitespace/newline] [4]'))
3140
3141 error_collector = ErrorCollector(self.assert_)
3142 cpplint.ProcessFileData('foo.cc', 'cc',
3143 ['if (hoge) {',
3144 '',
3145 '}',
3146 'else', # Warning on this line
3147 '{',
3148 '',
3149 '}'],
3150 error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +00003151 self.assertEquals(1, error_collector.Results().count(
3152 'An else should appear on the same line as the preceding }'
3153 ' [whitespace/newline] [4]'))
3154
avakulenko@google.com02af6282014-06-04 18:53:25 +00003155 error_collector = ErrorCollector(self.assert_)
3156 cpplint.ProcessFileData('foo.cc', 'cc',
3157 ['if (hoge) {',
3158 '',
3159 '}',
3160 'else_function();'],
3161 error_collector)
3162 self.assertEquals(0, error_collector.Results().count(
3163 'An else should appear on the same line as the preceding }'
3164 ' [whitespace/newline] [4]'))
3165
erg@google.comd350fe52013-01-14 17:51:48 +00003166 def testMultipleStatementsOnSameLine(self):
3167 error_collector = ErrorCollector(self.assert_)
3168 cpplint.ProcessFileData('foo.cc', 'cc',
3169 ['for (int i = 0; i < 1; i++) {}',
3170 'switch (x) {',
3171 ' case 0: func(); break; ',
3172 '}',
3173 'sum += MathUtil::SafeIntRound(x); x += 0.1;'],
3174 error_collector)
3175 self.assertEquals(0, error_collector.Results().count(
3176 'More than one command on the same line [whitespace/newline] [0]'))
3177
3178 old_verbose_level = cpplint._cpplint_state.verbose_level
3179 cpplint._cpplint_state.verbose_level = 0
3180 cpplint.ProcessFileData('foo.cc', 'cc',
3181 ['sum += MathUtil::SafeIntRound(x); x += 0.1;'],
3182 error_collector)
3183 cpplint._cpplint_state.verbose_level = old_verbose_level
3184
3185 def testEndOfNamespaceComments(self):
3186 error_collector = ErrorCollector(self.assert_)
3187 cpplint.ProcessFileData('foo.cc', 'cc',
3188 ['namespace {',
3189 '',
3190 '}', # No warning (too short)
3191 'namespace expected {',
3192 '} // namespace mismatched', # Warning here
3193 'namespace {',
3194 '} // namespace mismatched', # Warning here
3195 'namespace outer { namespace nested {'] +
3196 ([''] * 10) +
3197 ['}', # Warning here
3198 '}', # Warning here
3199 'namespace {'] +
3200 ([''] * 10) +
3201 ['}', # Warning here
3202 'namespace {'] +
3203 ([''] * 10) +
avakulenko@google.com02af6282014-06-04 18:53:25 +00003204 ['} // namespace some description', # Anon warning
3205 'namespace {'] +
3206 ([''] * 10) +
3207 ['} // namespace anonymous', # Variant warning
3208 'namespace {'] +
3209 ([''] * 10) +
3210 ['} // anonymous namespace (utils)', # Variant
3211 'namespace {'] +
3212 ([''] * 10) +
3213 ['} // anonymous namespace', # No warning
erg@google.comd350fe52013-01-14 17:51:48 +00003214 'namespace missing_comment {'] +
3215 ([''] * 10) +
3216 ['}', # Warning here
3217 'namespace no_warning {'] +
3218 ([''] * 10) +
3219 ['} // namespace no_warning',
3220 'namespace no_warning {'] +
3221 ([''] * 10) +
3222 ['}; // end namespace no_warning',
3223 '#define MACRO \\',
3224 'namespace c_style { \\'] +
3225 (['\\'] * 10) +
3226 ['} /* namespace c_style. */ \\',
3227 ';'],
3228 error_collector)
3229 self.assertEquals(1, error_collector.Results().count(
3230 'Namespace should be terminated with "// namespace expected"'
3231 ' [readability/namespace] [5]'))
3232 self.assertEquals(1, error_collector.Results().count(
3233 'Namespace should be terminated with "// namespace outer"'
3234 ' [readability/namespace] [5]'))
3235 self.assertEquals(1, error_collector.Results().count(
3236 'Namespace should be terminated with "// namespace nested"'
3237 ' [readability/namespace] [5]'))
3238 self.assertEquals(3, error_collector.Results().count(
avakulenko@google.com02af6282014-06-04 18:53:25 +00003239 'Anonymous namespace should be terminated with "// namespace"'
3240 ' [readability/namespace] [5]'))
3241 self.assertEquals(2, error_collector.Results().count(
3242 'Anonymous namespace should be terminated with "// namespace" or'
3243 ' "// anonymous namespace"'
erg@google.comd350fe52013-01-14 17:51:48 +00003244 ' [readability/namespace] [5]'))
3245 self.assertEquals(1, error_collector.Results().count(
3246 'Namespace should be terminated with "// namespace missing_comment"'
3247 ' [readability/namespace] [5]'))
3248 self.assertEquals(0, error_collector.Results().count(
3249 'Namespace should be terminated with "// namespace no_warning"'
3250 ' [readability/namespace] [5]'))
3251
erg@google.com4e00b9a2009-01-12 23:05:11 +00003252 def testElseClauseNotOnSameLineAsElse(self):
3253 self.TestLint(' else DoSomethingElse();',
3254 'Else clause should never be on same line as else '
3255 '(use 2 lines) [whitespace/newline] [4]')
3256 self.TestLint(' else ifDoSomethingElse();',
3257 'Else clause should never be on same line as else '
3258 '(use 2 lines) [whitespace/newline] [4]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003259 self.TestLint(' } else if (blah) {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003260 self.TestLint(' variable_ends_in_else = true;', '')
3261
3262 def testComma(self):
3263 self.TestLint('a = f(1,2);',
3264 'Missing space after , [whitespace/comma] [3]')
3265 self.TestLint('int tmp=a,a=b,b=tmp;',
3266 ['Missing spaces around = [whitespace/operators] [4]',
3267 'Missing space after , [whitespace/comma] [3]'])
3268 self.TestLint('f(a, /* name */ b);', '')
3269 self.TestLint('f(a, /* name */b);', '')
erg@google.com2aa59982013-10-28 19:09:25 +00003270 self.TestLint('f(a, /* name */-1);', '')
3271 self.TestLint('f(a, /* name */"1");', '')
erg@google.comc6671232013-10-25 21:44:03 +00003272 self.TestLint('f(1, /* empty macro arg */, 2)', '')
3273 self.TestLint('f(1,, 2)', '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003274 self.TestLint('operator,()', '')
3275 self.TestLint('operator,(a,b)',
3276 'Missing space after , [whitespace/comma] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003277
avakulenko@google.com554223d2014-12-04 22:00:20 +00003278 def testEqualsOperatorSpacing(self):
3279 self.TestLint('int tmp= a;',
3280 'Missing spaces around = [whitespace/operators] [4]')
3281 self.TestLint('int tmp =a;',
3282 'Missing spaces around = [whitespace/operators] [4]')
3283 self.TestLint('int tmp=a;',
3284 'Missing spaces around = [whitespace/operators] [4]')
3285 self.TestLint('int tmp= 7;',
3286 'Missing spaces around = [whitespace/operators] [4]')
3287 self.TestLint('int tmp =7;',
3288 'Missing spaces around = [whitespace/operators] [4]')
3289 self.TestLint('int tmp=7;',
3290 'Missing spaces around = [whitespace/operators] [4]')
3291 self.TestLint('int* tmp=*p;',
3292 'Missing spaces around = [whitespace/operators] [4]')
3293 self.TestLint('int* tmp= *p;',
3294 'Missing spaces around = [whitespace/operators] [4]')
3295 self.TestMultiLineLint(
3296 TrimExtraIndent('''
3297 lookahead_services_=
3298 ::strings::Split(FLAGS_ls, ",", ::strings::SkipEmpty());'''),
3299 'Missing spaces around = [whitespace/operators] [4]')
3300 self.TestLint('bool result = a>=42;',
3301 'Missing spaces around >= [whitespace/operators] [3]')
3302 self.TestLint('bool result = a<=42;',
3303 'Missing spaces around <= [whitespace/operators] [3]')
3304 self.TestLint('bool result = a==42;',
3305 'Missing spaces around == [whitespace/operators] [3]')
3306 self.TestLint('auto result = a!=42;',
3307 'Missing spaces around != [whitespace/operators] [3]')
3308 self.TestLint('int a = b!=c;',
3309 'Missing spaces around != [whitespace/operators] [3]')
3310 self.TestLint('a&=42;', '')
3311 self.TestLint('a|=42;', '')
3312 self.TestLint('a^=42;', '')
3313 self.TestLint('a+=42;', '')
3314 self.TestLint('a*=42;', '')
3315 self.TestLint('a/=42;', '')
3316 self.TestLint('a%=42;', '')
3317 self.TestLint('a>>=5;', '')
3318 self.TestLint('a<<=5;', '')
3319
3320 def testShiftOperatorSpacing(self):
3321 self.TestLint('a<<b',
3322 'Missing spaces around << [whitespace/operators] [3]')
3323 self.TestLint('a>>b',
3324 'Missing spaces around >> [whitespace/operators] [3]')
3325 self.TestLint('1<<20', '')
3326 self.TestLint('1024>>10', '')
3327 self.TestLint('Kernel<<<1, 2>>>()', '')
3328
erg@google.com4e00b9a2009-01-12 23:05:11 +00003329 def testIndent(self):
3330 self.TestLint('static int noindent;', '')
3331 self.TestLint(' int two_space_indent;', '')
3332 self.TestLint(' int four_space_indent;', '')
3333 self.TestLint(' int one_space_indent;',
3334 'Weird number of spaces at line-start. '
3335 'Are you using a 2-space indent? [whitespace/indent] [3]')
3336 self.TestLint(' int three_space_indent;',
3337 'Weird number of spaces at line-start. '
3338 'Are you using a 2-space indent? [whitespace/indent] [3]')
3339 self.TestLint(' char* one_space_indent = "public:";',
3340 'Weird number of spaces at line-start. '
3341 'Are you using a 2-space indent? [whitespace/indent] [3]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003342 self.TestLint(' public:', '')
3343 self.TestLint(' protected:', '')
3344 self.TestLint(' private:', '')
3345 self.TestLint(' protected: \\', '')
3346 self.TestLint(' public: \\', '')
3347 self.TestLint(' private: \\', '')
3348 self.TestMultiLineLint(
3349 TrimExtraIndent("""
3350 class foo {
3351 public slots:
3352 void bar();
3353 };"""),
3354 'Weird number of spaces at line-start. '
3355 'Are you using a 2-space indent? [whitespace/indent] [3]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003356 self.TestMultiLineLint(
3357 TrimExtraIndent('''
3358 static const char kRawString[] = R"("
3359 ")";'''),
3360 '')
3361 self.TestMultiLineLint(
3362 TrimExtraIndent('''
3363 static const char kNotRawString[] = "("
3364 ")";'''),
3365 'Weird number of spaces at line-start. '
3366 'Are you using a 2-space indent? [whitespace/indent] [3]')
3367 self.TestMultiLineLint(
3368 ' static const char kSingleLineRawString[] = R"(...)";',
3369 'Weird number of spaces at line-start. '
3370 'Are you using a 2-space indent? [whitespace/indent] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003371
erg@google.comfd5da632013-10-25 17:39:45 +00003372 def testSectionIndent(self):
3373 self.TestMultiLineLint(
3374 """
3375 class A {
3376 public: // no warning
3377 private: // warning here
3378 };""",
3379 'private: should be indented +1 space inside class A'
3380 ' [whitespace/indent] [3]')
3381 self.TestMultiLineLint(
3382 """
3383 class B {
3384 public: // no warning
3385 template<> struct C {
3386 public: // warning here
3387 protected: // no warning
3388 };
3389 };""",
3390 'public: should be indented +1 space inside struct C'
3391 ' [whitespace/indent] [3]')
3392 self.TestMultiLineLint(
3393 """
3394 struct D {
3395 };""",
3396 'Closing brace should be aligned with beginning of struct D'
3397 ' [whitespace/indent] [3]')
3398 self.TestMultiLineLint(
3399 """
3400 template<typename E> class F {
3401 };""",
3402 'Closing brace should be aligned with beginning of class F'
3403 ' [whitespace/indent] [3]')
3404 self.TestMultiLineLint(
3405 """
3406 class G {
3407 Q_OBJECT
3408 public slots:
3409 signals:
3410 };""",
3411 ['public slots: should be indented +1 space inside class G'
3412 ' [whitespace/indent] [3]',
3413 'signals: should be indented +1 space inside class G'
3414 ' [whitespace/indent] [3]'])
3415 self.TestMultiLineLint(
3416 """
3417 class H {
3418 /* comments */ class I {
3419 public: // no warning
3420 private: // warning here
3421 };
3422 };""",
3423 'private: should be indented +1 space inside class I'
3424 ' [whitespace/indent] [3]')
3425 self.TestMultiLineLint(
3426 """
3427 class J
3428 : public ::K {
3429 public: // no warning
3430 protected: // warning here
3431 };""",
3432 'protected: should be indented +1 space inside class J'
3433 ' [whitespace/indent] [3]')
3434 self.TestMultiLineLint(
3435 """
3436 class L
3437 : public M,
3438 public ::N {
3439 };""",
3440 '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003441 self.TestMultiLineLint(
3442 """
3443 template <class O,
3444 class P,
3445 class Q,
3446 typename R>
3447 static void Func() {
3448 }""",
3449 '')
3450
3451 def testConditionals(self):
3452 self.TestMultiLineLint(
3453 """
3454 if (foo)
3455 goto fail;
3456 goto fail;""",
3457 'If/else bodies with multiple statements require braces'
3458 ' [readability/braces] [4]')
3459 self.TestMultiLineLint(
3460 """
3461 if (foo)
3462 goto fail; goto fail;""",
3463 'If/else bodies with multiple statements require braces'
3464 ' [readability/braces] [4]')
3465 self.TestMultiLineLint(
3466 """
3467 if (foo)
3468 foo;
3469 else
3470 goto fail;
3471 goto fail;""",
3472 'If/else bodies with multiple statements require braces'
3473 ' [readability/braces] [4]')
3474 self.TestMultiLineLint(
3475 """
3476 if (foo) goto fail;
3477 goto fail;""",
3478 'If/else bodies with multiple statements require braces'
3479 ' [readability/braces] [4]')
3480 self.TestMultiLineLint(
3481 """
3482 if (foo)
3483 if (bar)
3484 baz;
3485 else
3486 qux;""",
3487 'Else clause should be indented at the same level as if. Ambiguous'
3488 ' nested if/else chains require braces. [readability/braces] [4]')
3489 self.TestMultiLineLint(
3490 """
3491 if (foo)
3492 if (bar)
3493 baz;
3494 else
3495 qux;""",
3496 'Else clause should be indented at the same level as if. Ambiguous'
3497 ' nested if/else chains require braces. [readability/braces] [4]')
3498 self.TestMultiLineLint(
3499 """
3500 if (foo) {
3501 bar;
3502 baz;
3503 } else
3504 qux;""",
3505 'If an else has a brace on one side, it should have it on both'
3506 ' [readability/braces] [5]')
3507 self.TestMultiLineLint(
3508 """
3509 if (foo)
3510 bar;
3511 else {
3512 baz;
3513 }""",
3514 'If an else has a brace on one side, it should have it on both'
3515 ' [readability/braces] [5]')
3516 self.TestMultiLineLint(
3517 """
3518 if (foo)
3519 bar;
3520 else if (baz) {
3521 qux;
3522 }""",
3523 'If an else has a brace on one side, it should have it on both'
3524 ' [readability/braces] [5]')
3525 self.TestMultiLineLint(
3526 """
3527 if (foo) {
3528 bar;
3529 } else if (baz)
3530 qux;""",
3531 'If an else has a brace on one side, it should have it on both'
3532 ' [readability/braces] [5]')
3533 self.TestMultiLineLint(
3534 """
3535 if (foo)
3536 goto fail;
3537 bar;""",
3538 '')
3539 self.TestMultiLineLint(
3540 """
3541 if (foo
3542 && bar) {
3543 baz;
3544 qux;
3545 }""",
3546 '')
3547 self.TestMultiLineLint(
3548 """
3549 if (foo)
3550 goto
3551 fail;""",
3552 '')
3553 self.TestMultiLineLint(
3554 """
3555 if (foo)
3556 bar;
3557 else
3558 baz;
3559 qux;""",
3560 '')
3561 self.TestMultiLineLint(
3562 """
3563 for (;;) {
3564 if (foo)
3565 bar;
3566 else
3567 baz;
3568 }""",
3569 '')
3570 self.TestMultiLineLint(
3571 """
3572 if (foo)
3573 bar;
3574 else if (baz)
3575 baz;""",
3576 '')
3577 self.TestMultiLineLint(
3578 """
3579 if (foo)
3580 bar;
3581 else
3582 baz;""",
3583 '')
3584 self.TestMultiLineLint(
3585 """
3586 if (foo) {
3587 bar;
3588 } else {
3589 baz;
3590 }""",
3591 '')
3592 self.TestMultiLineLint(
3593 """
3594 if (foo) {
3595 bar;
3596 } else if (baz) {
3597 qux;
3598 }""",
3599 '')
3600 # Note: this is an error for a different reason, but should not trigger the
3601 # single-line if error.
3602 self.TestMultiLineLint(
3603 """
3604 if (foo)
3605 {
3606 bar;
3607 baz;
3608 }""",
3609 '{ should almost always be at the end of the previous line'
3610 ' [whitespace/braces] [4]')
3611 self.TestMultiLineLint(
3612 """
3613 if (foo) { \\
3614 bar; \\
3615 baz; \\
3616 }""",
3617 '')
3618 self.TestMultiLineLint(
3619 """
3620 void foo() { if (bar) baz; }""",
3621 '')
3622 self.TestMultiLineLint(
3623 """
3624 #if foo
3625 bar;
3626 #else
3627 baz;
3628 qux;
3629 #endif""",
3630 '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00003631 self.TestMultiLineLint(
3632 """void F() {
3633 variable = [] { if (true); };
3634 variable =
3635 [] { if (true); };
3636 Call(
3637 [] { if (true); },
3638 [] { if (true); });
3639 }""",
3640 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003641
3642 def testTab(self):
3643 self.TestLint('\tint a;',
3644 'Tab found; better to use spaces [whitespace/tab] [1]')
3645 self.TestLint('int a = 5;\t\t// set a to 5',
3646 'Tab found; better to use spaces [whitespace/tab] [1]')
3647
3648 def testParseArguments(self):
3649 old_usage = cpplint._USAGE
3650 old_error_categories = cpplint._ERROR_CATEGORIES
3651 old_output_format = cpplint._cpplint_state.output_format
3652 old_verbose_level = cpplint._cpplint_state.verbose_level
3653 old_filters = cpplint._cpplint_state.filters
erg@google.comab53edf2013-11-05 22:23:37 +00003654 old_line_length = cpplint._line_length
erg@google.com19680272013-12-16 22:48:54 +00003655 old_valid_extensions = cpplint._valid_extensions
erg@google.com4e00b9a2009-01-12 23:05:11 +00003656 try:
3657 # Don't print usage during the tests, or filter categories
3658 cpplint._USAGE = ''
3659 cpplint._ERROR_CATEGORIES = ''
3660
3661 self.assertRaises(SystemExit, cpplint.ParseArguments, [])
3662 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--badopt'])
3663 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--help'])
3664 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--v=0'])
3665 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter='])
3666 # This is illegal because all filters must start with + or -
3667 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter=foo'])
3668 self.assertRaises(SystemExit, cpplint.ParseArguments,
3669 ['--filter=+a,b,-c'])
3670
3671 self.assertEquals(['foo.cc'], cpplint.ParseArguments(['foo.cc']))
3672 self.assertEquals(old_output_format, cpplint._cpplint_state.output_format)
3673 self.assertEquals(old_verbose_level, cpplint._cpplint_state.verbose_level)
3674
3675 self.assertEquals(['foo.cc'],
3676 cpplint.ParseArguments(['--v=1', 'foo.cc']))
3677 self.assertEquals(1, cpplint._cpplint_state.verbose_level)
3678 self.assertEquals(['foo.h'],
3679 cpplint.ParseArguments(['--v=3', 'foo.h']))
3680 self.assertEquals(3, cpplint._cpplint_state.verbose_level)
3681 self.assertEquals(['foo.cpp'],
3682 cpplint.ParseArguments(['--verbose=5', 'foo.cpp']))
3683 self.assertEquals(5, cpplint._cpplint_state.verbose_level)
3684 self.assertRaises(ValueError,
3685 cpplint.ParseArguments, ['--v=f', 'foo.cc'])
3686
3687 self.assertEquals(['foo.cc'],
3688 cpplint.ParseArguments(['--output=emacs', 'foo.cc']))
3689 self.assertEquals('emacs', cpplint._cpplint_state.output_format)
3690 self.assertEquals(['foo.h'],
3691 cpplint.ParseArguments(['--output=vs7', 'foo.h']))
3692 self.assertEquals('vs7', cpplint._cpplint_state.output_format)
3693 self.assertRaises(SystemExit,
3694 cpplint.ParseArguments, ['--output=blah', 'foo.cc'])
3695
3696 filt = '-,+whitespace,-whitespace/indent'
3697 self.assertEquals(['foo.h'],
3698 cpplint.ParseArguments(['--filter='+filt, 'foo.h']))
3699 self.assertEquals(['-', '+whitespace', '-whitespace/indent'],
3700 cpplint._cpplint_state.filters)
3701
3702 self.assertEquals(['foo.cc', 'foo.h'],
3703 cpplint.ParseArguments(['foo.cc', 'foo.h']))
erg@google.comab53edf2013-11-05 22:23:37 +00003704
3705 self.assertEqual(['foo.h'],
3706 cpplint.ParseArguments(['--linelength=120', 'foo.h']))
3707 self.assertEqual(120, cpplint._line_length)
erg@google.com19680272013-12-16 22:48:54 +00003708
3709 self.assertEqual(['foo.h'],
3710 cpplint.ParseArguments(['--extensions=hpp,cpp,cpp', 'foo.h']))
3711 self.assertEqual(set(['hpp', 'cpp']), cpplint._valid_extensions)
erg@google.com4e00b9a2009-01-12 23:05:11 +00003712 finally:
3713 cpplint._USAGE = old_usage
3714 cpplint._ERROR_CATEGORIES = old_error_categories
3715 cpplint._cpplint_state.output_format = old_output_format
3716 cpplint._cpplint_state.verbose_level = old_verbose_level
3717 cpplint._cpplint_state.filters = old_filters
erg@google.comab53edf2013-11-05 22:23:37 +00003718 cpplint._line_length = old_line_length
erg@google.com19680272013-12-16 22:48:54 +00003719 cpplint._valid_extensions = old_valid_extensions
erg@google.comab53edf2013-11-05 22:23:37 +00003720
3721 def testLineLength(self):
3722 old_line_length = cpplint._line_length
3723 try:
3724 cpplint._line_length = 80
3725 self.TestLint(
3726 '// %s' % ('H' * 77),
3727 '')
3728 self.TestLint(
3729 '// %s' % ('H' * 78),
3730 'Lines should be <= 80 characters long'
3731 ' [whitespace/line_length] [2]')
3732 cpplint._line_length = 120
3733 self.TestLint(
3734 '// %s' % ('H' * 117),
3735 '')
3736 self.TestLint(
3737 '// %s' % ('H' * 118),
3738 'Lines should be <= 120 characters long'
3739 ' [whitespace/line_length] [2]')
3740 finally:
3741 cpplint._line_length = old_line_length
erg@google.com4e00b9a2009-01-12 23:05:11 +00003742
3743 def testFilter(self):
3744 old_filters = cpplint._cpplint_state.filters
3745 try:
3746 cpplint._cpplint_state.SetFilters('-,+whitespace,-whitespace/indent')
3747 self.TestLint(
3748 '// Hello there ',
3749 'Line ends in whitespace. Consider deleting these extra spaces.'
3750 ' [whitespace/end_of_line] [4]')
3751 self.TestLint('int a = (int)1.0;', '')
3752 self.TestLint(' weird opening space', '')
3753 finally:
3754 cpplint._cpplint_state.filters = old_filters
3755
erg@google.come35f7652009-06-19 20:52:09 +00003756 def testDefaultFilter(self):
3757 default_filters = cpplint._DEFAULT_FILTERS
3758 old_filters = cpplint._cpplint_state.filters
erg@google.com8a95ecc2011-09-08 00:45:54 +00003759 cpplint._DEFAULT_FILTERS = ['-whitespace']
erg@google.come35f7652009-06-19 20:52:09 +00003760 try:
3761 # Reset filters
3762 cpplint._cpplint_state.SetFilters('')
3763 self.TestLint('// Hello there ', '')
3764 cpplint._cpplint_state.SetFilters('+whitespace/end_of_line')
3765 self.TestLint(
3766 '// Hello there ',
3767 'Line ends in whitespace. Consider deleting these extra spaces.'
3768 ' [whitespace/end_of_line] [4]')
3769 self.TestLint(' weird opening space', '')
3770 finally:
3771 cpplint._cpplint_state.filters = old_filters
3772 cpplint._DEFAULT_FILTERS = default_filters
3773
avakulenko@google.com554223d2014-12-04 22:00:20 +00003774 def testDuplicateHeader(self):
3775 error_collector = ErrorCollector(self.assert_)
3776 cpplint.ProcessFileData('path/self.cc', 'cc',
3777 ['// Copyright 2014 Your Company. All Rights Reserved.',
3778 '#include "path/self.h"',
3779 '#include "path/duplicate.h"',
3780 '#include "path/duplicate.h"',
3781 '#ifdef MACRO',
3782 '#include "path/unique.h"',
3783 '#else',
3784 '#include "path/unique.h"',
3785 '#endif',
3786 ''],
3787 error_collector)
3788 self.assertEquals(
3789 ['"path/duplicate.h" already included at path/self.cc:3 '
3790 '[build/include] [4]'],
3791 error_collector.ResultList())
3792
erg@google.com4e00b9a2009-01-12 23:05:11 +00003793 def testUnnamedNamespacesInHeaders(self):
3794 self.TestLanguageRulesCheck(
3795 'foo.h', 'namespace {',
3796 'Do not use unnamed namespaces in header files. See'
3797 ' http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
3798 ' for more information. [build/namespaces] [4]')
3799 # namespace registration macros are OK.
3800 self.TestLanguageRulesCheck('foo.h', 'namespace { \\', '')
3801 # named namespaces are OK.
3802 self.TestLanguageRulesCheck('foo.h', 'namespace foo {', '')
3803 self.TestLanguageRulesCheck('foo.h', 'namespace foonamespace {', '')
3804 self.TestLanguageRulesCheck('foo.cc', 'namespace {', '')
3805 self.TestLanguageRulesCheck('foo.cc', 'namespace foo {', '')
3806
3807 def testBuildClass(self):
3808 # Test that the linter can parse to the end of class definitions,
3809 # and that it will report when it can't.
3810 # Use multi-line linter because it performs the ClassState check.
3811 self.TestMultiLineLint(
3812 'class Foo {',
3813 'Failed to find complete declaration of class Foo'
3814 ' [build/class] [5]')
erg@google.com2aa59982013-10-28 19:09:25 +00003815 # Do the same for namespaces
3816 self.TestMultiLineLint(
3817 'namespace Foo {',
3818 'Failed to find complete declaration of namespace Foo'
3819 ' [build/namespaces] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003820 # Don't warn on forward declarations of various types.
3821 self.TestMultiLineLint(
3822 'class Foo;',
3823 '')
3824 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00003825 """struct Foo*
3826 foo = NewFoo();""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00003827 '')
erg@google.comd350fe52013-01-14 17:51:48 +00003828 # Test preprocessor.
3829 self.TestMultiLineLint(
3830 """#ifdef DERIVE_FROM_GOO
3831 struct Foo : public Goo {
3832 #else
3833 struct Foo : public Hoo {
3834 #endif
3835 };""",
3836 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003837 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00003838 """
3839 class Foo
erg@google.com4e00b9a2009-01-12 23:05:11 +00003840 #ifdef DERIVE_FROM_GOO
3841 : public Goo {
3842 #else
3843 : public Hoo {
3844 #endif
erg@google.comfd5da632013-10-25 17:39:45 +00003845 };""",
erg@google.comd350fe52013-01-14 17:51:48 +00003846 '')
3847 # Test incomplete class
3848 self.TestMultiLineLint(
3849 'class Foo {',
erg@google.com4e00b9a2009-01-12 23:05:11 +00003850 'Failed to find complete declaration of class Foo'
3851 ' [build/class] [5]')
3852
3853 def testBuildEndComment(self):
3854 # The crosstool compiler we currently use will fail to compile the
3855 # code in this test, so we might consider removing the lint check.
erg@google.comd350fe52013-01-14 17:51:48 +00003856 self.TestMultiLineLint(
3857 """#if 0
3858 #endif Not a comment""",
3859 'Uncommented text after #endif is non-standard. Use a comment.'
3860 ' [build/endif_comment] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003861
3862 def testBuildForwardDecl(self):
3863 # The crosstool compiler we currently use will fail to compile the
3864 # code in this test, so we might consider removing the lint check.
3865 self.TestLint('class Foo::Goo;',
3866 'Inner-style forward declarations are invalid.'
3867 ' Remove this line.'
3868 ' [build/forward_decl] [5]')
3869
avakulenko@google.com554223d2014-12-04 22:00:20 +00003870 def GetBuildHeaderGuardPreprocessorSymbol(self, file_path):
3871 # Figure out the expected header guard by processing an empty file.
erg@google.com4e00b9a2009-01-12 23:05:11 +00003872 error_collector = ErrorCollector(self.assert_)
3873 cpplint.ProcessFileData(file_path, 'h', [], error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +00003874 for error in error_collector.ResultList():
avakulenko@google.com554223d2014-12-04 22:00:20 +00003875 matched = re.search(
3876 'No #ifndef header guard found, suggested CPP variable is: ([A-Z_]+)',
3877 error)
3878 if matched is not None:
3879 return matched.group(1)
erg@google.com4e00b9a2009-01-12 23:05:11 +00003880
avakulenko@google.com554223d2014-12-04 22:00:20 +00003881 def testBuildHeaderGuard(self):
3882 file_path = 'mydir/foo.h'
3883 expected_guard = self.GetBuildHeaderGuardPreprocessorSymbol(file_path)
3884 self.assertTrue(re.search('MYDIR_FOO_H_$', expected_guard))
3885
3886 # No guard at all: expect one error.
3887 error_collector = ErrorCollector(self.assert_)
3888 cpplint.ProcessFileData(file_path, 'h', [], error_collector)
3889 self.assertEquals(
3890 1,
3891 error_collector.ResultList().count(
3892 'No #ifndef header guard found, suggested CPP variable is: %s'
3893 ' [build/header_guard] [5]' % expected_guard),
3894 error_collector.ResultList())
erg@google.com4e00b9a2009-01-12 23:05:11 +00003895
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003896 # No header guard, but the error is suppressed.
3897 error_collector = ErrorCollector(self.assert_)
3898 cpplint.ProcessFileData(file_path, 'h',
3899 ['// Copyright 2014 Your Company.',
3900 '// NOLINT(build/header_guard)', ''],
3901 error_collector)
3902 self.assertEquals([], error_collector.ResultList())
3903
erg@google.com4e00b9a2009-01-12 23:05:11 +00003904 # Wrong guard
3905 error_collector = ErrorCollector(self.assert_)
3906 cpplint.ProcessFileData(file_path, 'h',
3907 ['#ifndef FOO_H', '#define FOO_H'], error_collector)
3908 self.assertEquals(
3909 1,
3910 error_collector.ResultList().count(
3911 '#ifndef header guard has wrong style, please use: %s'
3912 ' [build/header_guard] [5]' % expected_guard),
3913 error_collector.ResultList())
3914
3915 # No define
3916 error_collector = ErrorCollector(self.assert_)
3917 cpplint.ProcessFileData(file_path, 'h',
3918 ['#ifndef %s' % expected_guard], error_collector)
3919 self.assertEquals(
3920 1,
3921 error_collector.ResultList().count(
avakulenko@google.com554223d2014-12-04 22:00:20 +00003922 'No #ifndef header guard found, suggested CPP variable is: %s'
erg@google.com4e00b9a2009-01-12 23:05:11 +00003923 ' [build/header_guard] [5]' % expected_guard),
3924 error_collector.ResultList())
3925
3926 # Mismatched define
3927 error_collector = ErrorCollector(self.assert_)
3928 cpplint.ProcessFileData(file_path, 'h',
3929 ['#ifndef %s' % expected_guard,
3930 '#define FOO_H'],
3931 error_collector)
3932 self.assertEquals(
3933 1,
3934 error_collector.ResultList().count(
avakulenko@google.com554223d2014-12-04 22:00:20 +00003935 'No #ifndef header guard found, suggested CPP variable is: %s'
erg@google.com4e00b9a2009-01-12 23:05:11 +00003936 ' [build/header_guard] [5]' % expected_guard),
3937 error_collector.ResultList())
3938
3939 # No endif
3940 error_collector = ErrorCollector(self.assert_)
3941 cpplint.ProcessFileData(file_path, 'h',
3942 ['#ifndef %s' % expected_guard,
avakulenko@google.com554223d2014-12-04 22:00:20 +00003943 '#define %s' % expected_guard,
3944 ''],
erg@google.com4e00b9a2009-01-12 23:05:11 +00003945 error_collector)
3946 self.assertEquals(
3947 1,
3948 error_collector.ResultList().count(
3949 '#endif line should be "#endif // %s"'
3950 ' [build/header_guard] [5]' % expected_guard),
3951 error_collector.ResultList())
3952
3953 # Commentless endif
3954 error_collector = ErrorCollector(self.assert_)
3955 cpplint.ProcessFileData(file_path, 'h',
3956 ['#ifndef %s' % expected_guard,
3957 '#define %s' % expected_guard,
3958 '#endif'],
3959 error_collector)
3960 self.assertEquals(
3961 1,
3962 error_collector.ResultList().count(
3963 '#endif line should be "#endif // %s"'
3964 ' [build/header_guard] [5]' % expected_guard),
3965 error_collector.ResultList())
3966
3967 # Commentless endif for old-style guard
3968 error_collector = ErrorCollector(self.assert_)
3969 cpplint.ProcessFileData(file_path, 'h',
3970 ['#ifndef %s_' % expected_guard,
3971 '#define %s_' % expected_guard,
3972 '#endif'],
3973 error_collector)
3974 self.assertEquals(
3975 1,
3976 error_collector.ResultList().count(
3977 '#endif line should be "#endif // %s"'
3978 ' [build/header_guard] [5]' % expected_guard),
3979 error_collector.ResultList())
3980
3981 # No header guard errors
3982 error_collector = ErrorCollector(self.assert_)
3983 cpplint.ProcessFileData(file_path, 'h',
3984 ['#ifndef %s' % expected_guard,
3985 '#define %s' % expected_guard,
3986 '#endif // %s' % expected_guard],
3987 error_collector)
3988 for line in error_collector.ResultList():
3989 if line.find('build/header_guard') != -1:
3990 self.fail('Unexpected error: %s' % line)
3991
3992 # No header guard errors for old-style guard
3993 error_collector = ErrorCollector(self.assert_)
3994 cpplint.ProcessFileData(file_path, 'h',
3995 ['#ifndef %s_' % expected_guard,
3996 '#define %s_' % expected_guard,
3997 '#endif // %s_' % expected_guard],
3998 error_collector)
3999 for line in error_collector.ResultList():
4000 if line.find('build/header_guard') != -1:
4001 self.fail('Unexpected error: %s' % line)
4002
4003 old_verbose_level = cpplint._cpplint_state.verbose_level
4004 try:
4005 cpplint._cpplint_state.verbose_level = 0
4006 # Warn on old-style guard if verbosity is 0.
4007 error_collector = ErrorCollector(self.assert_)
4008 cpplint.ProcessFileData(file_path, 'h',
4009 ['#ifndef %s_' % expected_guard,
4010 '#define %s_' % expected_guard,
4011 '#endif // %s_' % expected_guard],
4012 error_collector)
4013 self.assertEquals(
4014 1,
4015 error_collector.ResultList().count(
4016 '#ifndef header guard has wrong style, please use: %s'
4017 ' [build/header_guard] [0]' % expected_guard),
4018 error_collector.ResultList())
4019 finally:
4020 cpplint._cpplint_state.verbose_level = old_verbose_level
4021
4022 # Completely incorrect header guard
4023 error_collector = ErrorCollector(self.assert_)
4024 cpplint.ProcessFileData(file_path, 'h',
4025 ['#ifndef FOO',
4026 '#define FOO',
4027 '#endif // FOO'],
4028 error_collector)
4029 self.assertEquals(
4030 1,
4031 error_collector.ResultList().count(
4032 '#ifndef header guard has wrong style, please use: %s'
4033 ' [build/header_guard] [5]' % expected_guard),
4034 error_collector.ResultList())
4035 self.assertEquals(
4036 1,
4037 error_collector.ResultList().count(
4038 '#endif line should be "#endif // %s"'
4039 ' [build/header_guard] [5]' % expected_guard),
4040 error_collector.ResultList())
4041
erg@google.coma868d2d2009-10-09 21:18:45 +00004042 # incorrect header guard with nolint
4043 error_collector = ErrorCollector(self.assert_)
4044 cpplint.ProcessFileData(file_path, 'h',
4045 ['#ifndef FOO // NOLINT',
4046 '#define FOO',
4047 '#endif // FOO NOLINT'],
4048 error_collector)
4049 self.assertEquals(
4050 0,
4051 error_collector.ResultList().count(
4052 '#ifndef header guard has wrong style, please use: %s'
4053 ' [build/header_guard] [5]' % expected_guard),
4054 error_collector.ResultList())
4055 self.assertEquals(
4056 0,
4057 error_collector.ResultList().count(
4058 '#endif line should be "#endif // %s"'
4059 ' [build/header_guard] [5]' % expected_guard),
4060 error_collector.ResultList())
4061
erg+personal@google.com05189642010-04-30 20:43:03 +00004062 # Special case for flymake
erg@google.comd350fe52013-01-14 17:51:48 +00004063 for test_file in ['mydir/foo_flymake.h', 'mydir/.flymake/foo.h']:
4064 error_collector = ErrorCollector(self.assert_)
avakulenko@google.com554223d2014-12-04 22:00:20 +00004065 cpplint.ProcessFileData(test_file, 'h',
4066 ['// Copyright 2014 Your Company.', ''],
4067 error_collector)
erg@google.comd350fe52013-01-14 17:51:48 +00004068 self.assertEquals(
4069 1,
4070 error_collector.ResultList().count(
4071 'No #ifndef header guard found, suggested CPP variable is: %s'
4072 ' [build/header_guard] [5]' % expected_guard),
4073 error_collector.ResultList())
erg@google.coma868d2d2009-10-09 21:18:45 +00004074
erg@google.com4d70a882013-04-16 21:06:32 +00004075 def testBuildHeaderGuardWithRoot(self):
4076 file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
4077 'cpplint_test_header.h')
4078 file_info = cpplint.FileInfo(file_path)
4079 if file_info.FullName() == file_info.RepositoryName():
4080 # When FileInfo cannot deduce the root directory of the repository,
4081 # FileInfo.RepositoryName returns the same value as FileInfo.FullName.
4082 # This can happen when this source file was obtained without .svn or
4083 # .git directory. (e.g. using 'svn export' or 'git archive').
4084 # Skip this test in such a case because --root flag makes sense only
4085 # when the root directory of the repository is properly deduced.
4086 return
4087
4088 self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_',
4089 cpplint.GetHeaderGuardCPPVariable(file_path))
4090 cpplint._root = 'cpplint'
4091 self.assertEquals('CPPLINT_TEST_HEADER_H_',
4092 cpplint.GetHeaderGuardCPPVariable(file_path))
4093 # --root flag is ignored if an non-existent directory is specified.
4094 cpplint._root = 'NON_EXISTENT_DIR'
4095 self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_',
4096 cpplint.GetHeaderGuardCPPVariable(file_path))
4097
erg@google.com4e00b9a2009-01-12 23:05:11 +00004098 def testBuildInclude(self):
4099 # Test that include statements have slashes in them.
4100 self.TestLint('#include "foo.h"',
4101 'Include the directory when naming .h files'
4102 ' [build/include] [4]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004103 self.TestLint('#include "Python.h"', '')
4104 self.TestLint('#include "lua.h"', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004105
4106 def testBuildPrintfFormat(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004107 error_collector = ErrorCollector(self.assert_)
4108 cpplint.ProcessFileData(
4109 'foo.cc', 'cc',
4110 [r'printf("\%%d", value);',
4111 r'snprintf(buffer, sizeof(buffer), "\[%d", value);',
4112 r'fprintf(file, "\(%d", value);',
4113 r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);'],
4114 error_collector)
4115 self.assertEquals(
4116 4,
4117 error_collector.Results().count(
4118 '%, [, (, and { are undefined character escapes. Unescape them.'
4119 ' [build/printf_format] [3]'))
erg@google.com4e00b9a2009-01-12 23:05:11 +00004120
avakulenko@google.com02af6282014-06-04 18:53:25 +00004121 error_collector = ErrorCollector(self.assert_)
4122 cpplint.ProcessFileData(
4123 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004124 ['// Copyright 2014 Your Company.',
avakulenko@google.com02af6282014-06-04 18:53:25 +00004125 r'printf("\\%%%d", value);',
4126 r'printf(R"(\[)");',
4127 r'printf(R"(\[%s)", R"(\])");',
4128 ''],
4129 error_collector)
4130 self.assertEquals('', error_collector.Results())
erg@google.com4e00b9a2009-01-12 23:05:11 +00004131
4132 def testRuntimePrintfFormat(self):
4133 self.TestLint(
4134 r'fprintf(file, "%q", value);',
4135 '%q in format strings is deprecated. Use %ll instead.'
4136 ' [runtime/printf_format] [3]')
4137
4138 self.TestLint(
4139 r'aprintf(file, "The number is %12q", value);',
4140 '%q in format strings is deprecated. Use %ll instead.'
4141 ' [runtime/printf_format] [3]')
4142
4143 self.TestLint(
4144 r'printf(file, "The number is" "%-12q", value);',
4145 '%q in format strings is deprecated. Use %ll instead.'
4146 ' [runtime/printf_format] [3]')
4147
4148 self.TestLint(
4149 r'printf(file, "The number is" "%+12q", value);',
4150 '%q in format strings is deprecated. Use %ll instead.'
4151 ' [runtime/printf_format] [3]')
4152
4153 self.TestLint(
4154 r'printf(file, "The number is" "% 12q", value);',
4155 '%q in format strings is deprecated. Use %ll instead.'
4156 ' [runtime/printf_format] [3]')
4157
4158 self.TestLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00004159 r'snprintf(file, "Never mix %d and %1$d parameters!", value);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00004160 '%N$ formats are unconventional. Try rewriting to avoid them.'
4161 ' [runtime/printf_format] [2]')
4162
4163 def TestLintLogCodeOnError(self, code, expected_message):
4164 # Special TestLint which logs the input code on error.
4165 result = self.PerformSingleLineLint(code)
4166 if result != expected_message:
4167 self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"'
4168 % (code, result, expected_message))
4169
4170 def testBuildStorageClass(self):
4171 qualifiers = [None, 'const', 'volatile']
4172 signs = [None, 'signed', 'unsigned']
4173 types = ['void', 'char', 'int', 'float', 'double',
4174 'schar', 'int8', 'uint8', 'int16', 'uint16',
4175 'int32', 'uint32', 'int64', 'uint64']
erg@google.comd350fe52013-01-14 17:51:48 +00004176 storage_classes = ['extern', 'register', 'static', 'typedef']
erg@google.com4e00b9a2009-01-12 23:05:11 +00004177
4178 build_storage_class_error_message = (
4179 'Storage class (static, extern, typedef, etc) should be first.'
4180 ' [build/storage_class] [5]')
4181
4182 # Some explicit cases. Legal in C++, deprecated in C99.
4183 self.TestLint('const int static foo = 5;',
4184 build_storage_class_error_message)
4185
4186 self.TestLint('char static foo;',
4187 build_storage_class_error_message)
4188
4189 self.TestLint('double const static foo = 2.0;',
4190 build_storage_class_error_message)
4191
4192 self.TestLint('uint64 typedef unsigned_long_long;',
4193 build_storage_class_error_message)
4194
4195 self.TestLint('int register foo = 0;',
4196 build_storage_class_error_message)
4197
4198 # Since there are a very large number of possibilities, randomly
4199 # construct declarations.
4200 # Make sure that the declaration is logged if there's an error.
4201 # Seed generator with an integer for absolute reproducibility.
4202 random.seed(25)
4203 for unused_i in range(10):
4204 # Build up random list of non-storage-class declaration specs.
4205 other_decl_specs = [random.choice(qualifiers), random.choice(signs),
4206 random.choice(types)]
4207 # remove None
erg@google.comc6671232013-10-25 21:44:03 +00004208 other_decl_specs = [x for x in other_decl_specs if x is not None]
erg@google.com4e00b9a2009-01-12 23:05:11 +00004209
4210 # shuffle
4211 random.shuffle(other_decl_specs)
4212
4213 # insert storage class after the first
4214 storage_class = random.choice(storage_classes)
4215 insertion_point = random.randint(1, len(other_decl_specs))
4216 decl_specs = (other_decl_specs[0:insertion_point]
4217 + [storage_class]
4218 + other_decl_specs[insertion_point:])
4219
4220 self.TestLintLogCodeOnError(
4221 ' '.join(decl_specs) + ';',
4222 build_storage_class_error_message)
4223
4224 # but no error if storage class is first
4225 self.TestLintLogCodeOnError(
4226 storage_class + ' ' + ' '.join(other_decl_specs),
4227 '')
4228
4229 def testLegalCopyright(self):
4230 legal_copyright_message = (
4231 'No copyright message found. '
4232 'You should have a line: "Copyright [year] <Copyright Owner>"'
4233 ' [legal/copyright] [5]')
4234
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004235 copyright_line = '// Copyright 2014 Google Inc. All Rights Reserved.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00004236
4237 file_path = 'mydir/googleclient/foo.cc'
4238
4239 # There should be a copyright message in the first 10 lines
4240 error_collector = ErrorCollector(self.assert_)
4241 cpplint.ProcessFileData(file_path, 'cc', [], error_collector)
4242 self.assertEquals(
4243 1,
4244 error_collector.ResultList().count(legal_copyright_message))
4245
4246 error_collector = ErrorCollector(self.assert_)
4247 cpplint.ProcessFileData(
4248 file_path, 'cc',
4249 ['' for unused_i in range(10)] + [copyright_line],
4250 error_collector)
4251 self.assertEquals(
4252 1,
4253 error_collector.ResultList().count(legal_copyright_message))
4254
4255 # Test that warning isn't issued if Copyright line appears early enough.
4256 error_collector = ErrorCollector(self.assert_)
4257 cpplint.ProcessFileData(file_path, 'cc', [copyright_line], error_collector)
4258 for message in error_collector.ResultList():
4259 if message.find('legal/copyright') != -1:
4260 self.fail('Unexpected error: %s' % message)
4261
4262 error_collector = ErrorCollector(self.assert_)
4263 cpplint.ProcessFileData(
4264 file_path, 'cc',
4265 ['' for unused_i in range(9)] + [copyright_line],
4266 error_collector)
4267 for message in error_collector.ResultList():
4268 if message.find('legal/copyright') != -1:
4269 self.fail('Unexpected error: %s' % message)
4270
erg@google.com36649102009-03-25 21:18:36 +00004271 def testInvalidIncrement(self):
4272 self.TestLint('*count++;',
4273 'Changing pointer instead of value (or unused value of '
4274 'operator*). [runtime/invalid_increment] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004275
erg@google.comd350fe52013-01-14 17:51:48 +00004276 def testSnprintfSize(self):
4277 self.TestLint('vsnprintf(NULL, 0, format)', '')
4278 self.TestLint('snprintf(fisk, 1, format)',
4279 'If you can, use sizeof(fisk) instead of 1 as the 2nd arg '
4280 'to snprintf. [runtime/printf] [3]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00004281class Cxx11Test(CpplintTestBase):
4282
4283 def Helper(self, package, extension, lines, count):
4284 filename = package + '/foo.' + extension
4285 lines = lines[:]
4286
4287 # Header files need to have an ifdef guard wrapped around their code.
4288 if extension == 'h':
4289 guard = filename.upper().replace('/', '_').replace('.', '_') + '_'
4290 lines.insert(0, '#ifndef ' + guard)
4291 lines.insert(1, '#define ' + guard)
4292 lines.append('#endif // ' + guard)
4293
4294 # All files need a final blank line.
4295 lines.append('')
4296
4297 # Process the file and check resulting error count.
4298 collector = ErrorCollector(self.assert_)
4299 cpplint.ProcessFileData(filename, extension, lines, collector)
4300 error_list = collector.ResultList()
4301 self.assertEquals(count, len(error_list), error_list)
4302
4303 def TestCxx11Feature(self, code, expected_error):
4304 lines = code.split('\n')
4305 collector = ErrorCollector(self.assert_)
4306 cpplint.RemoveMultiLineComments('foo.h', lines, collector)
4307 clean_lines = cpplint.CleansedLines(lines)
4308 cpplint.FlagCxx11Features('foo.cc', clean_lines, 0, collector)
4309 self.assertEquals(expected_error, collector.Results())
4310
4311 def testBlockedHeaders(self):
4312 self.TestCxx11Feature('#include <mutex>',
4313 '<mutex> is an unapproved C++11 header.'
4314 ' [build/c++11] [5]')
4315
4316 def testBlockedClasses(self):
4317 self.TestCxx11Feature('std::alignment_of<T>',
4318 'std::alignment_of is an unapproved '
4319 'C++11 class or function. Send c-style an example '
4320 'of where it would make your code more readable, '
4321 'and they may let you use it.'
4322 ' [build/c++11] [5]')
4323 self.TestCxx11Feature('std::alignment_offer', '')
4324 self.TestCxx11Feature('mystd::alignment_of', '')
4325 self.TestCxx11Feature('std::binomial_distribution', '')
4326
4327 def testBlockedFunctions(self):
4328 self.TestCxx11Feature('std::alignment_of<int>',
4329 'std::alignment_of is an unapproved '
4330 'C++11 class or function. Send c-style an example '
4331 'of where it would make your code more readable, '
4332 'and they may let you use it.'
4333 ' [build/c++11] [5]')
4334 # Missed because of the lack of "std::". Compiles because ADL
4335 # looks in the namespace of my_shared_ptr, which (presumably) is
4336 # std::. But there will be a lint error somewhere in this file
4337 # since my_shared_ptr had to be defined.
4338 self.TestCxx11Feature('static_pointer_cast<Base>(my_shared_ptr)', '')
4339 self.TestCxx11Feature('std::declval<T>()', '')
erg@google.comd350fe52013-01-14 17:51:48 +00004340
4341 def testExplicitMakePair(self):
4342 self.TestLint('make_pair', '')
4343 self.TestLint('make_pair(42, 42)', '')
4344 self.TestLint('make_pair<',
4345 'For C++11-compatibility, omit template arguments from'
4346 ' make_pair OR use pair directly OR if appropriate,'
4347 ' construct a pair directly'
4348 ' [build/explicit_make_pair] [4]')
4349 self.TestLint('make_pair <',
4350 'For C++11-compatibility, omit template arguments from'
4351 ' make_pair OR use pair directly OR if appropriate,'
4352 ' construct a pair directly'
4353 ' [build/explicit_make_pair] [4]')
4354 self.TestLint('my_make_pair<int, int>', '')
4355
erg@google.com4e00b9a2009-01-12 23:05:11 +00004356class CleansedLinesTest(unittest.TestCase):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004357
erg@google.com4e00b9a2009-01-12 23:05:11 +00004358 def testInit(self):
4359 lines = ['Line 1',
4360 'Line 2',
4361 'Line 3 // Comment test',
erg@google.comd7d27472011-09-07 17:36:35 +00004362 'Line 4 /* Comment test */',
4363 'Line 5 "foo"']
4364
erg@google.com4e00b9a2009-01-12 23:05:11 +00004365 clean_lines = cpplint.CleansedLines(lines)
4366 self.assertEquals(lines, clean_lines.raw_lines)
erg@google.comd7d27472011-09-07 17:36:35 +00004367 self.assertEquals(5, clean_lines.NumLines())
erg@google.com4e00b9a2009-01-12 23:05:11 +00004368
4369 self.assertEquals(['Line 1',
4370 'Line 2',
erg@google.comd7d27472011-09-07 17:36:35 +00004371 'Line 3',
4372 'Line 4',
4373 'Line 5 "foo"'],
erg@google.com4e00b9a2009-01-12 23:05:11 +00004374 clean_lines.lines)
4375
4376 self.assertEquals(['Line 1',
4377 'Line 2',
erg@google.comd7d27472011-09-07 17:36:35 +00004378 'Line 3',
4379 'Line 4',
4380 'Line 5 ""'],
erg@google.com4e00b9a2009-01-12 23:05:11 +00004381 clean_lines.elided)
4382
4383 def testInitEmpty(self):
4384 clean_lines = cpplint.CleansedLines([])
4385 self.assertEquals([], clean_lines.raw_lines)
4386 self.assertEquals(0, clean_lines.NumLines())
4387
4388 def testCollapseStrings(self):
4389 collapse = cpplint.CleansedLines._CollapseStrings
4390 self.assertEquals('""', collapse('""')) # "" (empty)
4391 self.assertEquals('"""', collapse('"""')) # """ (bad)
4392 self.assertEquals('""', collapse('"xyz"')) # "xyz" (string)
4393 self.assertEquals('""', collapse('"\\\""')) # "\"" (string)
4394 self.assertEquals('""', collapse('"\'"')) # "'" (string)
4395 self.assertEquals('"\"', collapse('"\"')) # "\" (bad)
4396 self.assertEquals('""', collapse('"\\\\"')) # "\\" (string)
4397 self.assertEquals('"', collapse('"\\\\\\"')) # "\\\" (bad)
4398 self.assertEquals('""', collapse('"\\\\\\\\"')) # "\\\\" (string)
4399
4400 self.assertEquals('\'\'', collapse('\'\'')) # '' (empty)
4401 self.assertEquals('\'\'', collapse('\'a\'')) # 'a' (char)
4402 self.assertEquals('\'\'', collapse('\'\\\'\'')) # '\'' (char)
4403 self.assertEquals('\'', collapse('\'\\\'')) # '\' (bad)
4404 self.assertEquals('', collapse('\\012')) # '\012' (char)
4405 self.assertEquals('', collapse('\\xfF0')) # '\xfF0' (char)
4406 self.assertEquals('', collapse('\\n')) # '\n' (char)
avakulenko@google.com02af6282014-06-04 18:53:25 +00004407 self.assertEquals(r'\#', collapse('\\#')) # '\#' (bad)
4408
4409 self.assertEquals('"" + ""', collapse('"\'" + "\'"'))
4410 self.assertEquals("'', ''", collapse("'\"', '\"'"))
4411 self.assertEquals('""[0b10]', collapse('"a\'b"[0b1\'0]'))
4412
4413 self.assertEquals('42', collapse("4'2"))
4414 self.assertEquals('0b0101', collapse("0b0'1'0'1"))
4415 self.assertEquals('1048576', collapse("1'048'576"))
4416 self.assertEquals('0X100000', collapse("0X10'0000"))
4417 self.assertEquals('0004000000', collapse("0'004'000'000"))
4418 self.assertEquals('1.602176565e-19', collapse("1.602'176'565e-19"))
4419 self.assertEquals('\'\' + 0xffff', collapse("'i' + 0xf'f'f'f"))
4420 self.assertEquals('sizeof\'\' == 1', collapse("sizeof'x' == 1"))
4421 self.assertEquals('0x.03p100', collapse('0x.0\'3p1\'0\'0'))
4422 self.assertEquals('123.45', collapse('1\'23.4\'5'))
erg@google.com4e00b9a2009-01-12 23:05:11 +00004423
4424 self.assertEquals('StringReplace(body, "", "");',
4425 collapse('StringReplace(body, "\\\\", "\\\\\\\\");'))
4426 self.assertEquals('\'\' ""',
4427 collapse('\'"\' "foo"'))
4428
4429
4430class OrderOfIncludesTest(CpplintTestBase):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004431
erg@google.com4e00b9a2009-01-12 23:05:11 +00004432 def setUp(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004433 CpplintTestBase.setUp(self)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004434 self.include_state = cpplint._IncludeState()
erg@google.com4e00b9a2009-01-12 23:05:11 +00004435 os.path.abspath = lambda value: value
4436
erg@google.com4e00b9a2009-01-12 23:05:11 +00004437 def testCheckNextIncludeOrder_OtherThenCpp(self):
4438 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4439 cpplint._OTHER_HEADER))
4440 self.assertEqual('Found C++ system header after other header',
4441 self.include_state.CheckNextIncludeOrder(
4442 cpplint._CPP_SYS_HEADER))
4443
4444 def testCheckNextIncludeOrder_CppThenC(self):
4445 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4446 cpplint._CPP_SYS_HEADER))
4447 self.assertEqual('Found C system header after C++ system header',
4448 self.include_state.CheckNextIncludeOrder(
4449 cpplint._C_SYS_HEADER))
4450
4451 def testCheckNextIncludeOrder_LikelyThenCpp(self):
4452 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4453 cpplint._LIKELY_MY_HEADER))
4454 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4455 cpplint._CPP_SYS_HEADER))
4456
4457 def testCheckNextIncludeOrder_PossibleThenCpp(self):
4458 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4459 cpplint._POSSIBLE_MY_HEADER))
4460 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4461 cpplint._CPP_SYS_HEADER))
4462
4463 def testCheckNextIncludeOrder_CppThenLikely(self):
4464 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4465 cpplint._CPP_SYS_HEADER))
4466 # This will eventually fail.
4467 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4468 cpplint._LIKELY_MY_HEADER))
4469
4470 def testCheckNextIncludeOrder_CppThenPossible(self):
4471 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4472 cpplint._CPP_SYS_HEADER))
4473 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4474 cpplint._POSSIBLE_MY_HEADER))
4475
4476 def testClassifyInclude(self):
4477 file_info = cpplint.FileInfo
4478 classify_include = cpplint._ClassifyInclude
4479 self.assertEqual(cpplint._C_SYS_HEADER,
4480 classify_include(file_info('foo/foo.cc'),
4481 'stdio.h',
4482 True))
4483 self.assertEqual(cpplint._CPP_SYS_HEADER,
4484 classify_include(file_info('foo/foo.cc'),
4485 'string',
4486 True))
4487 self.assertEqual(cpplint._CPP_SYS_HEADER,
4488 classify_include(file_info('foo/foo.cc'),
4489 'typeinfo',
4490 True))
4491 self.assertEqual(cpplint._OTHER_HEADER,
4492 classify_include(file_info('foo/foo.cc'),
4493 'string',
4494 False))
4495
4496 self.assertEqual(cpplint._LIKELY_MY_HEADER,
4497 classify_include(file_info('foo/foo.cc'),
4498 'foo/foo-inl.h',
4499 False))
4500 self.assertEqual(cpplint._LIKELY_MY_HEADER,
4501 classify_include(file_info('foo/internal/foo.cc'),
4502 'foo/public/foo.h',
4503 False))
4504 self.assertEqual(cpplint._POSSIBLE_MY_HEADER,
4505 classify_include(file_info('foo/internal/foo.cc'),
4506 'foo/other/public/foo.h',
4507 False))
4508 self.assertEqual(cpplint._OTHER_HEADER,
4509 classify_include(file_info('foo/internal/foo.cc'),
4510 'foo/other/public/foop.h',
4511 False))
4512
4513 def testTryDropCommonSuffixes(self):
4514 self.assertEqual('foo/foo', cpplint._DropCommonSuffixes('foo/foo-inl.h'))
4515 self.assertEqual('foo/bar/foo',
4516 cpplint._DropCommonSuffixes('foo/bar/foo_inl.h'))
4517 self.assertEqual('foo/foo', cpplint._DropCommonSuffixes('foo/foo.cc'))
4518 self.assertEqual('foo/foo_unusualinternal',
4519 cpplint._DropCommonSuffixes('foo/foo_unusualinternal.h'))
4520 self.assertEqual('',
4521 cpplint._DropCommonSuffixes('_test.cc'))
4522 self.assertEqual('test',
4523 cpplint._DropCommonSuffixes('test.cc'))
4524
4525 def testRegression(self):
4526 def Format(includes):
erg@google.comfd5da632013-10-25 17:39:45 +00004527 include_list = []
avakulenko@google.com554223d2014-12-04 22:00:20 +00004528 for item in includes:
4529 if item.startswith('"') or item.startswith('<'):
4530 include_list.append('#include %s\n' % item)
erg@google.comfd5da632013-10-25 17:39:45 +00004531 else:
avakulenko@google.com554223d2014-12-04 22:00:20 +00004532 include_list.append(item + '\n')
erg@google.comfd5da632013-10-25 17:39:45 +00004533 return ''.join(include_list)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004534
4535 # Test singleton cases first.
4536 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"foo/foo.h"']), '')
4537 self.TestLanguageRulesCheck('foo/foo.cc', Format(['<stdio.h>']), '')
4538 self.TestLanguageRulesCheck('foo/foo.cc', Format(['<string>']), '')
4539 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"foo/foo-inl.h"']), '')
4540 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"bar/bar-inl.h"']), '')
4541 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"bar/bar.h"']), '')
4542
4543 # Test everything in a good and new order.
4544 self.TestLanguageRulesCheck('foo/foo.cc',
4545 Format(['"foo/foo.h"',
4546 '"foo/foo-inl.h"',
4547 '<stdio.h>',
4548 '<string>',
avakulenko@google.com02af6282014-06-04 18:53:25 +00004549 '<unordered_map>',
erg@google.com4e00b9a2009-01-12 23:05:11 +00004550 '"bar/bar-inl.h"',
4551 '"bar/bar.h"']),
4552 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004553
4554 # Test bad orders.
4555 self.TestLanguageRulesCheck(
4556 'foo/foo.cc',
4557 Format(['<string>', '<stdio.h>']),
4558 'Found C system header after C++ system header.'
4559 ' Should be: foo.h, c system, c++ system, other.'
4560 ' [build/include_order] [4]')
4561 self.TestLanguageRulesCheck(
4562 'foo/foo.cc',
4563 Format(['"foo/bar-inl.h"',
4564 '"foo/foo-inl.h"']),
4565 '')
erg@google.comfd5da632013-10-25 17:39:45 +00004566 self.TestLanguageRulesCheck(
4567 'foo/foo.cc',
4568 Format(['"foo/e.h"',
4569 '"foo/b.h"', # warning here (e>b)
4570 '"foo/c.h"',
4571 '"foo/d.h"',
4572 '"foo/a.h"']), # warning here (d>a)
4573 ['Include "foo/b.h" not in alphabetical order'
4574 ' [build/include_alpha] [4]',
4575 'Include "foo/a.h" not in alphabetical order'
4576 ' [build/include_alpha] [4]'])
erg@google.com4e00b9a2009-01-12 23:05:11 +00004577 # -inl.h headers are no longer special.
4578 self.TestLanguageRulesCheck('foo/foo.cc',
4579 Format(['"foo/foo-inl.h"', '<string>']),
4580 '')
4581 self.TestLanguageRulesCheck('foo/foo.cc',
4582 Format(['"foo/bar.h"', '"foo/bar-inl.h"']),
4583 '')
4584 # Test componentized header. OK to have my header in ../public dir.
4585 self.TestLanguageRulesCheck('foo/internal/foo.cc',
4586 Format(['"foo/public/foo.h"', '<string>']),
4587 '')
4588 # OK to have my header in other dir (not stylistically, but
4589 # cpplint isn't as good as a human).
4590 self.TestLanguageRulesCheck('foo/internal/foo.cc',
4591 Format(['"foo/other/public/foo.h"',
4592 '<string>']),
4593 '')
erg@google.coma868d2d2009-10-09 21:18:45 +00004594 self.TestLanguageRulesCheck('foo/foo.cc',
4595 Format(['"foo/foo.h"',
4596 '<string>',
4597 '"base/google.h"',
4598 '"base/flags.h"']),
4599 'Include "base/flags.h" not in alphabetical '
4600 'order [build/include_alpha] [4]')
4601 # According to the style, -inl.h should come before .h, but we don't
4602 # complain about that.
4603 self.TestLanguageRulesCheck('foo/foo.cc',
4604 Format(['"foo/foo-inl.h"',
4605 '"foo/foo.h"',
4606 '"base/google.h"',
4607 '"base/google-inl.h"']),
4608 '')
erg@google.comfd5da632013-10-25 17:39:45 +00004609 # Allow project includes to be separated by blank lines
4610 self.TestLanguageRulesCheck('a/a.cc',
4611 Format(['"a/a.h"',
4612 '<string>',
4613 '"base/google.h"',
4614 '',
avakulenko@google.com554223d2014-12-04 22:00:20 +00004615 '"b/c.h"',
4616 '',
4617 'MACRO',
erg@google.comfd5da632013-10-25 17:39:45 +00004618 '"a/b.h"']),
4619 '')
4620 self.TestLanguageRulesCheck('a/a.cc',
4621 Format(['"a/a.h"',
4622 '<string>',
4623 '"base/google.h"',
4624 '"a/b.h"']),
4625 'Include "a/b.h" not in alphabetical '
4626 'order [build/include_alpha] [4]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004627
erg@google.com2aa59982013-10-28 19:09:25 +00004628 # Test conditional includes
4629 self.TestLanguageRulesCheck(
4630 'a/a.cc',
4631 ''.join(['#include <string.h>\n',
4632 '#include "base/port.h"\n',
4633 '#include <initializer_list>\n']),
4634 ('Found C++ system header after other header. '
4635 'Should be: a.h, c system, c++ system, other. '
4636 '[build/include_order] [4]'))
4637 self.TestLanguageRulesCheck(
4638 'a/a.cc',
4639 ''.join(['#include <string.h>\n',
4640 '#include "base/port.h"\n',
4641 '#ifdef LANG_CXX11\n',
4642 '#include <initializer_list>\n',
4643 '#endif // LANG_CXX11\n']),
4644 '')
4645 self.TestLanguageRulesCheck(
4646 'a/a.cc',
4647 ''.join(['#include <string.h>\n',
4648 '#ifdef LANG_CXX11\n',
4649 '#include "base/port.h"\n',
4650 '#include <initializer_list>\n',
4651 '#endif // LANG_CXX11\n']),
4652 ('Found C++ system header after other header. '
4653 'Should be: a.h, c system, c++ system, other. '
4654 '[build/include_order] [4]'))
4655
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004656 # Third party headers are exempt from order checks
4657 self.TestLanguageRulesCheck('foo/foo.cc',
4658 Format(['<string>', '"Python.h"', '<vector>']),
4659 '')
4660
erg@google.com4e00b9a2009-01-12 23:05:11 +00004661
4662class CheckForFunctionLengthsTest(CpplintTestBase):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004663
erg@google.com4e00b9a2009-01-12 23:05:11 +00004664 def setUp(self):
4665 # Reducing these thresholds for the tests speeds up tests significantly.
4666 self.old_normal_trigger = cpplint._FunctionState._NORMAL_TRIGGER
4667 self.old_test_trigger = cpplint._FunctionState._TEST_TRIGGER
4668
4669 cpplint._FunctionState._NORMAL_TRIGGER = 10
4670 cpplint._FunctionState._TEST_TRIGGER = 25
4671
4672 def tearDown(self):
4673 cpplint._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger
4674 cpplint._FunctionState._TEST_TRIGGER = self.old_test_trigger
4675
4676 def TestFunctionLengthsCheck(self, code, expected_message):
4677 """Check warnings for long function bodies are as expected.
4678
4679 Args:
4680 code: C++ source code expected to generate a warning message.
4681 expected_message: Message expected to be generated by the C++ code.
4682 """
4683 self.assertEquals(expected_message,
4684 self.PerformFunctionLengthsCheck(code))
4685
4686 def TriggerLines(self, error_level):
4687 """Return number of lines needed to trigger a function length warning.
4688
4689 Args:
4690 error_level: --v setting for cpplint.
4691
4692 Returns:
4693 Number of lines needed to trigger a function length warning.
4694 """
4695 return cpplint._FunctionState._NORMAL_TRIGGER * 2**error_level
4696
4697 def TestLines(self, error_level):
4698 """Return number of lines needed to trigger a test function length warning.
4699
4700 Args:
4701 error_level: --v setting for cpplint.
4702
4703 Returns:
4704 Number of lines needed to trigger a test function length warning.
4705 """
4706 return cpplint._FunctionState._TEST_TRIGGER * 2**error_level
4707
4708 def TestFunctionLengthCheckDefinition(self, lines, error_level):
4709 """Generate long function definition and check warnings are as expected.
4710
4711 Args:
4712 lines: Number of lines to generate.
4713 error_level: --v setting for cpplint.
4714 """
4715 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4716 self.TestFunctionLengthsCheck(
4717 'void test(int x)' + self.FunctionBody(lines),
4718 ('Small and focused functions are preferred: '
4719 'test() has %d non-comment lines '
4720 '(error triggered by exceeding %d lines).'
4721 ' [readability/fn_size] [%d]'
4722 % (lines, trigger_level, error_level)))
4723
4724 def TestFunctionLengthCheckDefinitionOK(self, lines):
4725 """Generate shorter function definition and check no warning is produced.
4726
4727 Args:
4728 lines: Number of lines to generate.
4729 """
4730 self.TestFunctionLengthsCheck(
4731 'void test(int x)' + self.FunctionBody(lines),
4732 '')
4733
4734 def TestFunctionLengthCheckAtErrorLevel(self, error_level):
4735 """Generate and check function at the trigger level for --v setting.
4736
4737 Args:
4738 error_level: --v setting for cpplint.
4739 """
4740 self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level),
4741 error_level)
4742
4743 def TestFunctionLengthCheckBelowErrorLevel(self, error_level):
4744 """Generate and check function just below the trigger level for --v setting.
4745
4746 Args:
4747 error_level: --v setting for cpplint.
4748 """
4749 self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level)-1,
4750 error_level-1)
4751
4752 def TestFunctionLengthCheckAboveErrorLevel(self, error_level):
4753 """Generate and check function just above the trigger level for --v setting.
4754
4755 Args:
4756 error_level: --v setting for cpplint.
4757 """
4758 self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level)+1,
4759 error_level)
4760
4761 def FunctionBody(self, number_of_lines):
4762 return ' {\n' + ' this_is_just_a_test();\n'*number_of_lines + '}'
4763
4764 def FunctionBodyWithBlankLines(self, number_of_lines):
4765 return ' {\n' + ' this_is_just_a_test();\n\n'*number_of_lines + '}'
4766
4767 def FunctionBodyWithNoLints(self, number_of_lines):
4768 return (' {\n' +
4769 ' this_is_just_a_test(); // NOLINT\n'*number_of_lines + '}')
4770
4771 # Test line length checks.
4772 def testFunctionLengthCheckDeclaration(self):
4773 self.TestFunctionLengthsCheck(
4774 'void test();', # Not a function definition
4775 '')
4776
4777 def testFunctionLengthCheckDeclarationWithBlockFollowing(self):
4778 self.TestFunctionLengthsCheck(
4779 ('void test();\n'
4780 + self.FunctionBody(66)), # Not a function definition
4781 '')
4782
4783 def testFunctionLengthCheckClassDefinition(self):
4784 self.TestFunctionLengthsCheck( # Not a function definition
4785 'class Test' + self.FunctionBody(66) + ';',
4786 '')
4787
4788 def testFunctionLengthCheckTrivial(self):
4789 self.TestFunctionLengthsCheck(
4790 'void test() {}', # Not counted
4791 '')
4792
4793 def testFunctionLengthCheckEmpty(self):
4794 self.TestFunctionLengthsCheck(
4795 'void test() {\n}',
4796 '')
4797
4798 def testFunctionLengthCheckDefinitionBelowSeverity0(self):
4799 old_verbosity = cpplint._SetVerboseLevel(0)
4800 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(0)-1)
4801 cpplint._SetVerboseLevel(old_verbosity)
4802
4803 def testFunctionLengthCheckDefinitionAtSeverity0(self):
4804 old_verbosity = cpplint._SetVerboseLevel(0)
4805 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(0))
4806 cpplint._SetVerboseLevel(old_verbosity)
4807
4808 def testFunctionLengthCheckDefinitionAboveSeverity0(self):
4809 old_verbosity = cpplint._SetVerboseLevel(0)
4810 self.TestFunctionLengthCheckAboveErrorLevel(0)
4811 cpplint._SetVerboseLevel(old_verbosity)
4812
4813 def testFunctionLengthCheckDefinitionBelowSeverity1v0(self):
4814 old_verbosity = cpplint._SetVerboseLevel(0)
4815 self.TestFunctionLengthCheckBelowErrorLevel(1)
4816 cpplint._SetVerboseLevel(old_verbosity)
4817
4818 def testFunctionLengthCheckDefinitionAtSeverity1v0(self):
4819 old_verbosity = cpplint._SetVerboseLevel(0)
4820 self.TestFunctionLengthCheckAtErrorLevel(1)
4821 cpplint._SetVerboseLevel(old_verbosity)
4822
4823 def testFunctionLengthCheckDefinitionBelowSeverity1(self):
4824 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(1)-1)
4825
4826 def testFunctionLengthCheckDefinitionAtSeverity1(self):
4827 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(1))
4828
4829 def testFunctionLengthCheckDefinitionAboveSeverity1(self):
4830 self.TestFunctionLengthCheckAboveErrorLevel(1)
4831
4832 def testFunctionLengthCheckDefinitionSeverity1PlusBlanks(self):
4833 error_level = 1
4834 error_lines = self.TriggerLines(error_level) + 1
4835 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4836 self.TestFunctionLengthsCheck(
4837 'void test_blanks(int x)' + self.FunctionBody(error_lines),
4838 ('Small and focused functions are preferred: '
4839 'test_blanks() has %d non-comment lines '
4840 '(error triggered by exceeding %d lines).'
4841 ' [readability/fn_size] [%d]')
4842 % (error_lines, trigger_level, error_level))
4843
4844 def testFunctionLengthCheckComplexDefinitionSeverity1(self):
4845 error_level = 1
4846 error_lines = self.TriggerLines(error_level) + 1
4847 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4848 self.TestFunctionLengthsCheck(
4849 ('my_namespace::my_other_namespace::MyVeryLongTypeName*\n'
4850 'my_namespace::my_other_namespace::MyFunction(int arg1, char* arg2)'
4851 + self.FunctionBody(error_lines)),
4852 ('Small and focused functions are preferred: '
4853 'my_namespace::my_other_namespace::MyFunction()'
4854 ' has %d non-comment lines '
4855 '(error triggered by exceeding %d lines).'
4856 ' [readability/fn_size] [%d]')
4857 % (error_lines, trigger_level, error_level))
4858
4859 def testFunctionLengthCheckDefinitionSeverity1ForTest(self):
4860 error_level = 1
4861 error_lines = self.TestLines(error_level) + 1
4862 trigger_level = self.TestLines(cpplint._VerboseLevel())
4863 self.TestFunctionLengthsCheck(
4864 'TEST_F(Test, Mutator)' + self.FunctionBody(error_lines),
4865 ('Small and focused functions are preferred: '
4866 'TEST_F(Test, Mutator) has %d non-comment lines '
4867 '(error triggered by exceeding %d lines).'
4868 ' [readability/fn_size] [%d]')
4869 % (error_lines, trigger_level, error_level))
4870
4871 def testFunctionLengthCheckDefinitionSeverity1ForSplitLineTest(self):
4872 error_level = 1
4873 error_lines = self.TestLines(error_level) + 1
4874 trigger_level = self.TestLines(cpplint._VerboseLevel())
4875 self.TestFunctionLengthsCheck(
4876 ('TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,\n'
4877 ' FixGoogleUpdate_AllValues_MachineApp)' # note: 4 spaces
4878 + self.FunctionBody(error_lines)),
4879 ('Small and focused functions are preferred: '
4880 'TEST_F(GoogleUpdateRecoveryRegistryProtectedTest, ' # 1 space
4881 'FixGoogleUpdate_AllValues_MachineApp) has %d non-comment lines '
4882 '(error triggered by exceeding %d lines).'
4883 ' [readability/fn_size] [%d]')
4884 % (error_lines+1, trigger_level, error_level))
4885
4886 def testFunctionLengthCheckDefinitionSeverity1ForBadTestDoesntBreak(self):
4887 error_level = 1
4888 error_lines = self.TestLines(error_level) + 1
4889 trigger_level = self.TestLines(cpplint._VerboseLevel())
4890 self.TestFunctionLengthsCheck(
4891 ('TEST_F('
4892 + self.FunctionBody(error_lines)),
4893 ('Small and focused functions are preferred: '
4894 'TEST_F has %d non-comment lines '
4895 '(error triggered by exceeding %d lines).'
4896 ' [readability/fn_size] [%d]')
4897 % (error_lines, trigger_level, error_level))
4898
4899 def testFunctionLengthCheckDefinitionSeverity1WithEmbeddedNoLints(self):
4900 error_level = 1
4901 error_lines = self.TriggerLines(error_level)+1
4902 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4903 self.TestFunctionLengthsCheck(
4904 'void test(int x)' + self.FunctionBodyWithNoLints(error_lines),
4905 ('Small and focused functions are preferred: '
4906 'test() has %d non-comment lines '
4907 '(error triggered by exceeding %d lines).'
4908 ' [readability/fn_size] [%d]')
4909 % (error_lines, trigger_level, error_level))
4910
4911 def testFunctionLengthCheckDefinitionSeverity1WithNoLint(self):
4912 self.TestFunctionLengthsCheck(
4913 ('void test(int x)' + self.FunctionBody(self.TriggerLines(1))
4914 + ' // NOLINT -- long function'),
4915 '')
4916
4917 def testFunctionLengthCheckDefinitionBelowSeverity2(self):
4918 self.TestFunctionLengthCheckBelowErrorLevel(2)
4919
4920 def testFunctionLengthCheckDefinitionSeverity2(self):
4921 self.TestFunctionLengthCheckAtErrorLevel(2)
4922
4923 def testFunctionLengthCheckDefinitionAboveSeverity2(self):
4924 self.TestFunctionLengthCheckAboveErrorLevel(2)
4925
4926 def testFunctionLengthCheckDefinitionBelowSeverity3(self):
4927 self.TestFunctionLengthCheckBelowErrorLevel(3)
4928
4929 def testFunctionLengthCheckDefinitionSeverity3(self):
4930 self.TestFunctionLengthCheckAtErrorLevel(3)
4931
4932 def testFunctionLengthCheckDefinitionAboveSeverity3(self):
4933 self.TestFunctionLengthCheckAboveErrorLevel(3)
4934
4935 def testFunctionLengthCheckDefinitionBelowSeverity4(self):
4936 self.TestFunctionLengthCheckBelowErrorLevel(4)
4937
4938 def testFunctionLengthCheckDefinitionSeverity4(self):
4939 self.TestFunctionLengthCheckAtErrorLevel(4)
4940
4941 def testFunctionLengthCheckDefinitionAboveSeverity4(self):
4942 self.TestFunctionLengthCheckAboveErrorLevel(4)
4943
4944 def testFunctionLengthCheckDefinitionBelowSeverity5(self):
4945 self.TestFunctionLengthCheckBelowErrorLevel(5)
4946
4947 def testFunctionLengthCheckDefinitionAtSeverity5(self):
4948 self.TestFunctionLengthCheckAtErrorLevel(5)
4949
4950 def testFunctionLengthCheckDefinitionAboveSeverity5(self):
4951 self.TestFunctionLengthCheckAboveErrorLevel(5)
4952
4953 def testFunctionLengthCheckDefinitionHugeLines(self):
4954 # 5 is the limit
4955 self.TestFunctionLengthCheckDefinition(self.TriggerLines(10), 5)
4956
4957 def testFunctionLengthNotDeterminable(self):
erg@google.com4e00b9a2009-01-12 23:05:11 +00004958 # Macro invocation without terminating semicolon.
4959 self.TestFunctionLengthsCheck(
4960 'MACRO(arg)',
4961 '')
4962
4963 # Macro with underscores
4964 self.TestFunctionLengthsCheck(
4965 'MACRO_WITH_UNDERSCORES(arg1, arg2, arg3)',
4966 '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004967
erg@google.com4e00b9a2009-01-12 23:05:11 +00004968 self.TestFunctionLengthsCheck(
4969 'NonMacro(arg)',
4970 'Lint failed to find start of function body.'
4971 ' [readability/fn_size] [5]')
4972
avakulenko@google.com02af6282014-06-04 18:53:25 +00004973
4974def TrimExtraIndent(text_block):
4975 """Trim a uniform amount of whitespace off of each line in a string.
4976
4977 Compute the minimum indent on all non blank lines and trim that from each, so
4978 that the block of text has no extra indentation.
4979
4980 Args:
4981 text_block: a multiline string
4982
4983 Returns:
4984 text_block with the common whitespace indent of each line removed.
4985 """
4986
4987 def CountLeadingWhitespace(s):
4988 count = 0
4989 for c in s:
4990 if not c.isspace():
4991 break
4992 count += 1
4993 return count
4994 # find the minimum indent (except for blank lines)
4995 min_indent = min([CountLeadingWhitespace(line)
4996 for line in text_block.split('\n') if line])
4997 return '\n'.join([line[min_indent:] for line in text_block.split('\n')])
4998
4999
5000class CloseExpressionTest(unittest.TestCase):
5001
erg@google.comd350fe52013-01-14 17:51:48 +00005002 def setUp(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00005003 self.lines = cpplint.CleansedLines(
5004 # 1 2 3 4 5
5005 # 0123456789012345678901234567890123456789012345678901234567890
5006 ['// Line 0',
5007 'inline RCULocked<X>::ReadPtr::ReadPtr(const RCULocked* rcu) {',
5008 ' DCHECK(!(data & kFlagMask)) << "Error";',
5009 '}',
5010 '// Line 4',
5011 'RCULocked<X>::WritePtr::WritePtr(RCULocked* rcu)',
5012 ' : lock_(&rcu_->mutex_) {',
5013 '}',
5014 '// Line 8',
5015 'template <typename T, typename... A>',
5016 'typename std::enable_if<',
5017 ' std::is_array<T>::value && (std::extent<T>::value > 0)>::type',
5018 'MakeUnique(A&&... a) = delete;',
5019 '// Line 13',
5020 'auto x = []() {};',
5021 '// Line 15',
5022 'template <typename U>',
5023 'friend bool operator==(const reffed_ptr& a,',
5024 ' const reffed_ptr<U>& b) {',
5025 ' return a.get() == b.get();',
5026 '}',
5027 '// Line 21'])
5028
5029 def testCloseExpression(self):
5030 # List of positions to test:
5031 # (start line, start position, end line, end position + 1)
5032 positions = [(1, 16, 1, 19),
5033 (1, 37, 1, 59),
5034 (1, 60, 3, 1),
5035 (2, 8, 2, 29),
5036 (2, 30, 22, -1), # Left shift operator
5037 (9, 9, 9, 36),
5038 (10, 23, 11, 59),
5039 (11, 54, 22, -1), # Greater than operator
5040 (14, 9, 14, 11),
5041 (14, 11, 14, 13),
5042 (14, 14, 14, 16),
5043 (17, 22, 18, 46),
5044 (18, 47, 20, 1)]
5045 for p in positions:
5046 (_, line, column) = cpplint.CloseExpression(self.lines, p[0], p[1])
5047 self.assertEquals((p[2], p[3]), (line, column))
5048
5049 def testReverseCloseExpression(self):
5050 # List of positions to test:
5051 # (end line, end position, start line, start position)
5052 positions = [(1, 18, 1, 16),
5053 (1, 58, 1, 37),
5054 (2, 27, 2, 10),
5055 (2, 28, 2, 8),
5056 (6, 18, 0, -1), # -> operator
5057 (9, 35, 9, 9),
5058 (11, 54, 0, -1), # Greater than operator
5059 (11, 57, 11, 31),
5060 (14, 10, 14, 9),
5061 (14, 12, 14, 11),
5062 (14, 15, 14, 14),
5063 (18, 45, 17, 22),
5064 (20, 0, 18, 47)]
5065 for p in positions:
5066 (_, line, column) = cpplint.ReverseCloseExpression(self.lines, p[0], p[1])
5067 self.assertEquals((p[2], p[3]), (line, column))
5068
5069
5070class NestingStateTest(unittest.TestCase):
5071
5072 def setUp(self):
5073 self.nesting_state = cpplint.NestingState()
erg@google.comd350fe52013-01-14 17:51:48 +00005074 self.error_collector = ErrorCollector(self.assert_)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005075
erg@google.comd350fe52013-01-14 17:51:48 +00005076 def UpdateWithLines(self, lines):
5077 clean_lines = cpplint.CleansedLines(lines)
5078 for line in xrange(clean_lines.NumLines()):
5079 self.nesting_state.Update('test.cc',
5080 clean_lines, line, self.error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005081
erg@google.comd350fe52013-01-14 17:51:48 +00005082 def testEmpty(self):
5083 self.UpdateWithLines([])
5084 self.assertEquals(self.nesting_state.stack, [])
erg@google.com4e00b9a2009-01-12 23:05:11 +00005085
erg@google.comd350fe52013-01-14 17:51:48 +00005086 def testNamespace(self):
5087 self.UpdateWithLines(['namespace {'])
5088 self.assertEquals(len(self.nesting_state.stack), 1)
5089 self.assertTrue(isinstance(self.nesting_state.stack[0],
5090 cpplint._NamespaceInfo))
5091 self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
5092 self.assertEquals(self.nesting_state.stack[0].name, '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005093
erg@google.comd350fe52013-01-14 17:51:48 +00005094 self.UpdateWithLines(['namespace outer { namespace inner'])
5095 self.assertEquals(len(self.nesting_state.stack), 3)
5096 self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
5097 self.assertTrue(self.nesting_state.stack[1].seen_open_brace)
5098 self.assertFalse(self.nesting_state.stack[2].seen_open_brace)
5099 self.assertEquals(self.nesting_state.stack[0].name, '')
5100 self.assertEquals(self.nesting_state.stack[1].name, 'outer')
5101 self.assertEquals(self.nesting_state.stack[2].name, 'inner')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005102
erg@google.comd350fe52013-01-14 17:51:48 +00005103 self.UpdateWithLines(['{'])
5104 self.assertTrue(self.nesting_state.stack[2].seen_open_brace)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005105
erg@google.comd350fe52013-01-14 17:51:48 +00005106 self.UpdateWithLines(['}', '}}'])
5107 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005108
erg@google.comd350fe52013-01-14 17:51:48 +00005109 def testClass(self):
5110 self.UpdateWithLines(['class A {'])
5111 self.assertEquals(len(self.nesting_state.stack), 1)
5112 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5113 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5114 self.assertFalse(self.nesting_state.stack[0].is_derived)
erg@google.comfd5da632013-10-25 17:39:45 +00005115 self.assertEquals(self.nesting_state.stack[0].class_indent, 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005116
erg@google.comd350fe52013-01-14 17:51:48 +00005117 self.UpdateWithLines(['};',
5118 'struct B : public A {'])
5119 self.assertEquals(len(self.nesting_state.stack), 1)
5120 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5121 self.assertEquals(self.nesting_state.stack[0].name, 'B')
5122 self.assertTrue(self.nesting_state.stack[0].is_derived)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005123
erg@google.comd350fe52013-01-14 17:51:48 +00005124 self.UpdateWithLines(['};',
5125 'class C',
5126 ': public A {'])
5127 self.assertEquals(len(self.nesting_state.stack), 1)
5128 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5129 self.assertEquals(self.nesting_state.stack[0].name, 'C')
5130 self.assertTrue(self.nesting_state.stack[0].is_derived)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005131
erg@google.comd350fe52013-01-14 17:51:48 +00005132 self.UpdateWithLines(['};',
5133 'template<T>'])
5134 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005135
erg@google.comfd5da632013-10-25 17:39:45 +00005136 self.UpdateWithLines(['class D {', ' class E {'])
erg@google.comd350fe52013-01-14 17:51:48 +00005137 self.assertEquals(len(self.nesting_state.stack), 2)
5138 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5139 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5140 self.assertFalse(self.nesting_state.stack[0].is_derived)
5141 self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5142 self.assertEquals(self.nesting_state.stack[1].name, 'E')
5143 self.assertFalse(self.nesting_state.stack[1].is_derived)
erg@google.comfd5da632013-10-25 17:39:45 +00005144 self.assertEquals(self.nesting_state.stack[1].class_indent, 2)
erg@google.comd350fe52013-01-14 17:51:48 +00005145 self.assertEquals(self.nesting_state.InnermostClass().name, 'E')
erg@google.comd7d27472011-09-07 17:36:35 +00005146
erg@google.comd350fe52013-01-14 17:51:48 +00005147 self.UpdateWithLines(['}', '}'])
5148 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.comd7d27472011-09-07 17:36:35 +00005149
erg@google.comd350fe52013-01-14 17:51:48 +00005150 def testClassAccess(self):
5151 self.UpdateWithLines(['class A {'])
5152 self.assertEquals(len(self.nesting_state.stack), 1)
5153 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5154 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.comd7d27472011-09-07 17:36:35 +00005155
erg@google.comd350fe52013-01-14 17:51:48 +00005156 self.UpdateWithLines([' public:'])
5157 self.assertEquals(self.nesting_state.stack[0].access, 'public')
5158 self.UpdateWithLines([' protracted:'])
5159 self.assertEquals(self.nesting_state.stack[0].access, 'public')
5160 self.UpdateWithLines([' protected:'])
5161 self.assertEquals(self.nesting_state.stack[0].access, 'protected')
5162 self.UpdateWithLines([' private:'])
5163 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005164
erg@google.comd350fe52013-01-14 17:51:48 +00005165 self.UpdateWithLines([' struct B {'])
5166 self.assertEquals(len(self.nesting_state.stack), 2)
5167 self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5168 self.assertEquals(self.nesting_state.stack[1].access, 'public')
5169 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005170
erg@google.comd350fe52013-01-14 17:51:48 +00005171 self.UpdateWithLines([' protected :'])
5172 self.assertEquals(self.nesting_state.stack[1].access, 'protected')
5173 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005174
erg@google.comd350fe52013-01-14 17:51:48 +00005175 self.UpdateWithLines([' }', '}'])
5176 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005177
erg@google.comd350fe52013-01-14 17:51:48 +00005178 def testStruct(self):
5179 self.UpdateWithLines(['struct A {'])
5180 self.assertEquals(len(self.nesting_state.stack), 1)
5181 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5182 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5183 self.assertFalse(self.nesting_state.stack[0].is_derived)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005184
erg@google.comd350fe52013-01-14 17:51:48 +00005185 self.UpdateWithLines(['}',
5186 'void Func(struct B arg) {'])
5187 self.assertEquals(len(self.nesting_state.stack), 1)
5188 self.assertFalse(isinstance(self.nesting_state.stack[0],
5189 cpplint._ClassInfo))
erg@google.com4e00b9a2009-01-12 23:05:11 +00005190
erg@google.comd350fe52013-01-14 17:51:48 +00005191 self.UpdateWithLines(['}'])
5192 self.assertEquals(len(self.nesting_state.stack), 0)
erg+personal@google.com05189642010-04-30 20:43:03 +00005193
erg@google.comd350fe52013-01-14 17:51:48 +00005194 def testPreprocessor(self):
5195 self.assertEquals(len(self.nesting_state.pp_stack), 0)
5196 self.UpdateWithLines(['#if MACRO1'])
5197 self.assertEquals(len(self.nesting_state.pp_stack), 1)
5198 self.UpdateWithLines(['#endif'])
5199 self.assertEquals(len(self.nesting_state.pp_stack), 0)
5200
5201 self.UpdateWithLines(['#ifdef MACRO2'])
5202 self.assertEquals(len(self.nesting_state.pp_stack), 1)
5203 self.UpdateWithLines(['#else'])
5204 self.assertEquals(len(self.nesting_state.pp_stack), 1)
5205 self.UpdateWithLines(['#ifdef MACRO3'])
5206 self.assertEquals(len(self.nesting_state.pp_stack), 2)
5207 self.UpdateWithLines(['#elif MACRO4'])
5208 self.assertEquals(len(self.nesting_state.pp_stack), 2)
5209 self.UpdateWithLines(['#endif'])
5210 self.assertEquals(len(self.nesting_state.pp_stack), 1)
5211 self.UpdateWithLines(['#endif'])
5212 self.assertEquals(len(self.nesting_state.pp_stack), 0)
5213
5214 self.UpdateWithLines(['#ifdef MACRO5',
5215 'class A {',
5216 '#elif MACRO6',
5217 'class B {',
5218 '#else',
5219 'class C {',
5220 '#endif'])
5221 self.assertEquals(len(self.nesting_state.pp_stack), 0)
5222 self.assertEquals(len(self.nesting_state.stack), 1)
5223 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5224 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5225 self.UpdateWithLines(['};'])
5226 self.assertEquals(len(self.nesting_state.stack), 0)
5227
5228 self.UpdateWithLines(['class D',
5229 '#ifdef MACRO7'])
5230 self.assertEquals(len(self.nesting_state.pp_stack), 1)
5231 self.assertEquals(len(self.nesting_state.stack), 1)
5232 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5233 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5234 self.assertFalse(self.nesting_state.stack[0].is_derived)
5235
5236 self.UpdateWithLines(['#elif MACRO8',
5237 ': public E'])
5238 self.assertEquals(len(self.nesting_state.stack), 1)
5239 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5240 self.assertTrue(self.nesting_state.stack[0].is_derived)
5241 self.assertFalse(self.nesting_state.stack[0].seen_open_brace)
5242
5243 self.UpdateWithLines(['#else',
5244 '{'])
5245 self.assertEquals(len(self.nesting_state.stack), 1)
5246 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5247 self.assertFalse(self.nesting_state.stack[0].is_derived)
5248 self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
5249
5250 self.UpdateWithLines(['#endif'])
5251 self.assertEquals(len(self.nesting_state.pp_stack), 0)
5252 self.assertEquals(len(self.nesting_state.stack), 1)
5253 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5254 self.assertFalse(self.nesting_state.stack[0].is_derived)
5255 self.assertFalse(self.nesting_state.stack[0].seen_open_brace)
5256
5257 self.UpdateWithLines([';'])
5258 self.assertEquals(len(self.nesting_state.stack), 0)
5259
5260 def testTemplate(self):
5261 self.UpdateWithLines(['template <T,',
5262 ' class Arg1 = tmpl<T> >'])
5263 self.assertEquals(len(self.nesting_state.stack), 0)
5264 self.UpdateWithLines(['class A {'])
5265 self.assertEquals(len(self.nesting_state.stack), 1)
5266 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5267 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5268
5269 self.UpdateWithLines(['};',
5270 'template <T,',
5271 ' template <typename, typename> class B>',
5272 'class C'])
5273 self.assertEquals(len(self.nesting_state.stack), 1)
5274 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5275 self.assertEquals(self.nesting_state.stack[0].name, 'C')
5276 self.UpdateWithLines([';'])
5277 self.assertEquals(len(self.nesting_state.stack), 0)
5278
5279 self.UpdateWithLines(['class D : public Tmpl<E>'])
5280 self.assertEquals(len(self.nesting_state.stack), 1)
5281 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5282 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5283
avakulenko@google.com02af6282014-06-04 18:53:25 +00005284 self.UpdateWithLines(['{', '};'])
5285 self.assertEquals(len(self.nesting_state.stack), 0)
5286
5287 self.UpdateWithLines(['template <class F,',
5288 ' class G,',
5289 ' class H,',
5290 ' typename I>',
5291 'static void Func() {'])
5292 self.assertEquals(len(self.nesting_state.stack), 1)
5293 self.assertFalse(isinstance(self.nesting_state.stack[0],
5294 cpplint._ClassInfo))
5295 self.UpdateWithLines(['}',
5296 'template <class J> class K {'])
5297 self.assertEquals(len(self.nesting_state.stack), 1)
5298 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5299 self.assertEquals(self.nesting_state.stack[0].name, 'K')
5300
erg@google.comfd5da632013-10-25 17:39:45 +00005301 def testTemplateInnerClass(self):
5302 self.UpdateWithLines(['class A {',
5303 ' public:'])
5304 self.assertEquals(len(self.nesting_state.stack), 1)
5305 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5306
5307 self.UpdateWithLines([' template <class B>',
5308 ' class C<alloc<B> >',
5309 ' : public A {'])
5310 self.assertEquals(len(self.nesting_state.stack), 2)
5311 self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5312
erg@google.comd350fe52013-01-14 17:51:48 +00005313 def testArguments(self):
5314 self.UpdateWithLines(['class A {'])
5315 self.assertEquals(len(self.nesting_state.stack), 1)
5316 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5317 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5318 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5319
5320 self.UpdateWithLines([' void Func(',
5321 ' struct X arg1,'])
5322 self.assertEquals(len(self.nesting_state.stack), 1)
5323 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5324 self.UpdateWithLines([' struct X *arg2);'])
5325 self.assertEquals(len(self.nesting_state.stack), 1)
5326 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5327
5328 self.UpdateWithLines(['};'])
5329 self.assertEquals(len(self.nesting_state.stack), 0)
5330
5331 self.UpdateWithLines(['struct B {'])
5332 self.assertEquals(len(self.nesting_state.stack), 1)
5333 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5334 self.assertEquals(self.nesting_state.stack[0].name, 'B')
5335
5336 self.UpdateWithLines(['#ifdef MACRO',
5337 ' void Func(',
5338 ' struct X arg1'])
5339 self.assertEquals(len(self.nesting_state.stack), 1)
5340 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5341 self.UpdateWithLines(['#else'])
5342
5343 self.assertEquals(len(self.nesting_state.stack), 1)
5344 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5345 self.UpdateWithLines([' void Func(',
5346 ' struct X arg1'])
5347 self.assertEquals(len(self.nesting_state.stack), 1)
5348 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5349
5350 self.UpdateWithLines(['#endif'])
5351 self.assertEquals(len(self.nesting_state.stack), 1)
5352 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5353 self.UpdateWithLines([' struct X *arg2);'])
5354 self.assertEquals(len(self.nesting_state.stack), 1)
5355 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5356
5357 self.UpdateWithLines(['};'])
5358 self.assertEquals(len(self.nesting_state.stack), 0)
5359
5360 def testInlineAssembly(self):
5361 self.UpdateWithLines(['void CopyRow_SSE2(const uint8* src, uint8* dst,',
5362 ' int count) {'])
5363 self.assertEquals(len(self.nesting_state.stack), 1)
5364 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5365 self.assertEquals(self.nesting_state.stack[-1].inline_asm, cpplint._NO_ASM)
5366
5367 self.UpdateWithLines([' asm volatile ('])
5368 self.assertEquals(len(self.nesting_state.stack), 1)
5369 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5370 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5371 cpplint._INSIDE_ASM)
5372
5373 self.UpdateWithLines([' "sub %0,%1 \\n"',
5374 ' "1: \\n"',
5375 ' "movdqa (%0),%%xmm0 \\n"',
5376 ' "movdqa 0x10(%0),%%xmm1 \\n"',
5377 ' "movdqa %%xmm0,(%0,%1) \\n"',
5378 ' "movdqa %%xmm1,0x10(%0,%1) \\n"',
5379 ' "lea 0x20(%0),%0 \\n"',
5380 ' "sub $0x20,%2 \\n"',
5381 ' "jg 1b \\n"',
5382 ' : "+r"(src), // %0',
5383 ' "+r"(dst), // %1',
5384 ' "+r"(count) // %2',
5385 ' :',
5386 ' : "memory", "cc"'])
5387 self.assertEquals(len(self.nesting_state.stack), 1)
5388 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5389 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5390 cpplint._INSIDE_ASM)
5391
5392 self.UpdateWithLines(['#if defined(__SSE2__)',
5393 ' , "xmm0", "xmm1"'])
5394 self.assertEquals(len(self.nesting_state.stack), 1)
5395 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5396 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5397 cpplint._INSIDE_ASM)
5398
5399 self.UpdateWithLines(['#endif'])
5400 self.assertEquals(len(self.nesting_state.stack), 1)
5401 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5402 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5403 cpplint._INSIDE_ASM)
5404
5405 self.UpdateWithLines([' );'])
5406 self.assertEquals(len(self.nesting_state.stack), 1)
5407 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5408 self.assertEquals(self.nesting_state.stack[-1].inline_asm, cpplint._END_ASM)
5409
5410 self.UpdateWithLines(['__asm {'])
5411 self.assertEquals(len(self.nesting_state.stack), 2)
5412 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5413 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5414 cpplint._BLOCK_ASM)
5415
5416 self.UpdateWithLines(['}'])
5417 self.assertEquals(len(self.nesting_state.stack), 1)
5418
5419 self.UpdateWithLines(['}'])
5420 self.assertEquals(len(self.nesting_state.stack), 0)
5421
erg+personal@google.com05189642010-04-30 20:43:03 +00005422
erg@google.coma868d2d2009-10-09 21:18:45 +00005423# pylint: disable-msg=C6409
5424def setUp():
erg@google.com8a95ecc2011-09-08 00:45:54 +00005425 """Runs before all tests are executed.
erg@google.coma868d2d2009-10-09 21:18:45 +00005426 """
5427 # Enable all filters, so we don't miss anything that is off by default.
5428 cpplint._DEFAULT_FILTERS = []
5429 cpplint._cpplint_state.SetFilters('')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005430
erg@google.coma868d2d2009-10-09 21:18:45 +00005431
5432# pylint: disable-msg=C6409
erg@google.com4e00b9a2009-01-12 23:05:11 +00005433def tearDown():
5434 """A global check to make sure all error-categories have been tested.
5435
5436 The main tearDown() routine is the only code we can guarantee will be
5437 run after all other tests have been executed.
5438 """
5439 try:
5440 if _run_verifyallcategoriesseen:
5441 ErrorCollector(None).VerifyAllCategoriesAreSeen()
5442 except NameError:
5443 # If nobody set the global _run_verifyallcategoriesseen, then
avakulenko@google.com554223d2014-12-04 22:00:20 +00005444 # we assume we should silently not run the test
erg@google.com4e00b9a2009-01-12 23:05:11 +00005445 pass
5446
erg@google.coma868d2d2009-10-09 21:18:45 +00005447
erg@google.com4e00b9a2009-01-12 23:05:11 +00005448if __name__ == '__main__':
erg@google.com4e00b9a2009-01-12 23:05:11 +00005449 # We don't want to run the VerifyAllCategoriesAreSeen() test unless
5450 # we're running the full test suite: if we only run one test,
5451 # obviously we're not going to see all the error categories. So we
5452 # only run VerifyAllCategoriesAreSeen() when no commandline flags
5453 # are passed in.
5454 global _run_verifyallcategoriesseen
5455 _run_verifyallcategoriesseen = (len(sys.argv) == 1)
5456
erg@google.coma868d2d2009-10-09 21:18:45 +00005457 setUp()
erg@google.com4e00b9a2009-01-12 23:05:11 +00005458 unittest.main()
erg@google.coma868d2d2009-10-09 21:18:45 +00005459 tearDown()