blob: 308626910e6e6008100f682fe7a01eef617f0e78 [file] [log] [blame]
erg@google.comd350fe52013-01-14 17:51:48 +00001#!/usr/bin/python
erg@google.com4e00b9a2009-01-12 23:05:11 +00002# -*- coding: utf-8; -*-
3#
erg@google.com8f91ab22011-09-06 21:04:45 +00004# Copyright (c) 2009 Google Inc. All rights reserved.
erg@google.com4e00b9a2009-01-12 23:05:11 +00005#
erg@google.com969161c2009-06-26 22:06:46 +00006# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are
8# met:
erg@google.com4e00b9a2009-01-12 23:05:11 +00009#
erg@google.com969161c2009-06-26 22:06:46 +000010# * Redistributions of source code must retain the above copyright
11# notice, this list of conditions and the following disclaimer.
12# * Redistributions in binary form must reproduce the above
13# copyright notice, this list of conditions and the following disclaimer
14# in the documentation and/or other materials provided with the
15# distribution.
16# * Neither the name of Google Inc. nor the names of its
17# contributors may be used to endorse or promote products derived from
18# this software without specific prior written permission.
erg@google.com4e00b9a2009-01-12 23:05:11 +000019#
erg@google.com969161c2009-06-26 22:06:46 +000020# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
erg@google.com4e00b9a2009-01-12 23:05:11 +000031
32"""Unit test for cpplint.py."""
33
erg@google.come35f7652009-06-19 20:52:09 +000034# TODO(unknown): Add a good test that tests UpdateIncludeState.
35
36import codecs
erg@google.com4e00b9a2009-01-12 23:05:11 +000037import os
38import random
39import re
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +000040import sys
erg@google.com4e00b9a2009-01-12 23:05:11 +000041import unittest
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +000042
erg@google.com4e00b9a2009-01-12 23:05:11 +000043import cpplint
44
45
46# This class works as an error collector and replaces cpplint.Error
47# function for the unit tests. We also verify each category we see
48# is in cpplint._ERROR_CATEGORIES, to help keep that list up to date.
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +000049class ErrorCollector(object):
erg@google.com4e00b9a2009-01-12 23:05:11 +000050 # These are a global list, covering all categories seen ever.
erg+personal@google.com05189642010-04-30 20:43:03 +000051 _ERROR_CATEGORIES = cpplint._ERROR_CATEGORIES
erg@google.com4e00b9a2009-01-12 23:05:11 +000052 _SEEN_ERROR_CATEGORIES = {}
53
54 def __init__(self, assert_fn):
55 """assert_fn: a function to call when we notice a problem."""
56 self._assert_fn = assert_fn
57 self._errors = []
erg+personal@google.com05189642010-04-30 20:43:03 +000058 cpplint.ResetNolintSuppressions()
erg@google.com4e00b9a2009-01-12 23:05:11 +000059
erg+personal@google.com05189642010-04-30 20:43:03 +000060 def __call__(self, unused_filename, linenum,
erg@google.com4e00b9a2009-01-12 23:05:11 +000061 category, confidence, message):
62 self._assert_fn(category in self._ERROR_CATEGORIES,
63 'Message "%s" has category "%s",'
64 ' which is not in _ERROR_CATEGORIES' % (message, category))
65 self._SEEN_ERROR_CATEGORIES[category] = 1
erg+personal@google.com05189642010-04-30 20:43:03 +000066 if cpplint._ShouldPrintError(category, confidence, linenum):
erg@google.com4e00b9a2009-01-12 23:05:11 +000067 self._errors.append('%s [%s] [%d]' % (message, category, confidence))
68
69 def Results(self):
70 if len(self._errors) < 2:
71 return ''.join(self._errors) # Most tests expect to have a string.
72 else:
73 return self._errors # Let's give a list if there is more than one.
74
75 def ResultList(self):
76 return self._errors
77
78 def VerifyAllCategoriesAreSeen(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +000079 """Fails if there's a category in _ERROR_CATEGORIES~_SEEN_ERROR_CATEGORIES.
erg@google.com4e00b9a2009-01-12 23:05:11 +000080
81 This should only be called after all tests are run, so
82 _SEEN_ERROR_CATEGORIES has had a chance to fully populate. Since
83 this isn't called from within the normal unittest framework, we
84 can't use the normal unittest assert macros. Instead we just exit
85 when we see an error. Good thing this test is always run last!
86 """
87 for category in self._ERROR_CATEGORIES:
88 if category not in self._SEEN_ERROR_CATEGORIES:
erg@google.com4e00b9a2009-01-12 23:05:11 +000089 sys.exit('FATAL ERROR: There are no tests for category "%s"' % category)
90
91 def RemoveIfPresent(self, substr):
92 for (index, error) in enumerate(self._errors):
93 if error.find(substr) != -1:
94 self._errors = self._errors[0:index] + self._errors[(index + 1):]
95 break
96
erg@google.come35f7652009-06-19 20:52:09 +000097
98# This class is a lame mock of codecs. We do not verify filename, mode, or
99# encoding, but for the current use case it is not needed.
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000100class MockIo(object):
avakulenko@google.com02af6282014-06-04 18:53:25 +0000101
erg@google.come35f7652009-06-19 20:52:09 +0000102 def __init__(self, mock_file):
103 self.mock_file = mock_file
104
erg@google.comd350fe52013-01-14 17:51:48 +0000105 def open(self, # pylint: disable-msg=C6409
106 unused_filename, unused_mode, unused_encoding, _):
erg@google.come35f7652009-06-19 20:52:09 +0000107 return self.mock_file
108
109
erg@google.com4e00b9a2009-01-12 23:05:11 +0000110class CpplintTestBase(unittest.TestCase):
111 """Provides some useful helper functions for cpplint tests."""
112
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000113 def setUp(self):
114 # Allow subclasses to cheat os.path.abspath called in FileInfo class.
115 self.os_path_abspath_orig = os.path.abspath
116
117 def tearDown(self):
118 os.path.abspath = self.os_path_abspath_orig
119
erg@google.com4e00b9a2009-01-12 23:05:11 +0000120 # Perform lint on single line of input and return the error message.
121 def PerformSingleLineLint(self, code):
122 error_collector = ErrorCollector(self.assert_)
123 lines = code.split('\n')
124 cpplint.RemoveMultiLineComments('foo.h', lines, error_collector)
125 clean_lines = cpplint.CleansedLines(lines)
126 include_state = cpplint._IncludeState()
127 function_state = cpplint._FunctionState()
avakulenko@google.com02af6282014-06-04 18:53:25 +0000128 nesting_state = cpplint.NestingState()
erg@google.com4e00b9a2009-01-12 23:05:11 +0000129 cpplint.ProcessLine('foo.cc', 'cc', clean_lines, 0,
130 include_state, function_state,
erg@google.comd350fe52013-01-14 17:51:48 +0000131 nesting_state, error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000132 # Single-line lint tests are allowed to fail the 'unlintable function'
133 # check.
134 error_collector.RemoveIfPresent(
135 'Lint failed to find start of function body.')
136 return error_collector.Results()
137
138 # Perform lint over multiple lines and return the error message.
139 def PerformMultiLineLint(self, code):
140 error_collector = ErrorCollector(self.assert_)
141 lines = code.split('\n')
142 cpplint.RemoveMultiLineComments('foo.h', lines, error_collector)
143 lines = cpplint.CleansedLines(lines)
avakulenko@google.com02af6282014-06-04 18:53:25 +0000144 nesting_state = cpplint.NestingState()
erg@google.com4e00b9a2009-01-12 23:05:11 +0000145 for i in xrange(lines.NumLines()):
erg@google.comd350fe52013-01-14 17:51:48 +0000146 nesting_state.Update('foo.h', lines, i, error_collector)
147 cpplint.CheckStyle('foo.h', lines, i, 'h', nesting_state,
erg@google.com8a95ecc2011-09-08 00:45:54 +0000148 error_collector)
erg@google.comd350fe52013-01-14 17:51:48 +0000149 cpplint.CheckForNonStandardConstructs('foo.h', lines, i,
150 nesting_state, error_collector)
erg@google.com2aa59982013-10-28 19:09:25 +0000151 nesting_state.CheckCompletedBlocks('foo.h', error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000152 return error_collector.Results()
153
154 # Similar to PerformMultiLineLint, but calls CheckLanguage instead of
155 # CheckForNonStandardConstructs
156 def PerformLanguageRulesCheck(self, file_name, code):
157 error_collector = ErrorCollector(self.assert_)
158 include_state = cpplint._IncludeState()
avakulenko@google.com02af6282014-06-04 18:53:25 +0000159 nesting_state = cpplint.NestingState()
erg@google.com4e00b9a2009-01-12 23:05:11 +0000160 lines = code.split('\n')
161 cpplint.RemoveMultiLineComments(file_name, lines, error_collector)
162 lines = cpplint.CleansedLines(lines)
163 ext = file_name[file_name.rfind('.') + 1:]
164 for i in xrange(lines.NumLines()):
165 cpplint.CheckLanguage(file_name, lines, i, ext, include_state,
erg@google.comfd5da632013-10-25 17:39:45 +0000166 nesting_state, error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000167 return error_collector.Results()
168
169 def PerformFunctionLengthsCheck(self, code):
170 """Perform Lint function length check on block of code and return warnings.
171
172 Builds up an array of lines corresponding to the code and strips comments
173 using cpplint functions.
174
175 Establishes an error collector and invokes the function length checking
176 function following cpplint's pattern.
177
178 Args:
179 code: C++ source code expected to generate a warning message.
180
181 Returns:
182 The accumulated errors.
183 """
184 file_name = 'foo.cc'
185 error_collector = ErrorCollector(self.assert_)
186 function_state = cpplint._FunctionState()
187 lines = code.split('\n')
188 cpplint.RemoveMultiLineComments(file_name, lines, error_collector)
189 lines = cpplint.CleansedLines(lines)
190 for i in xrange(lines.NumLines()):
191 cpplint.CheckForFunctionLengths(file_name, lines, i,
192 function_state, error_collector)
193 return error_collector.Results()
194
erg@google.come35f7652009-06-19 20:52:09 +0000195 def PerformIncludeWhatYouUse(self, code, filename='foo.h', io=codecs):
erg@google.com4e00b9a2009-01-12 23:05:11 +0000196 # First, build up the include state.
197 error_collector = ErrorCollector(self.assert_)
198 include_state = cpplint._IncludeState()
avakulenko@google.com02af6282014-06-04 18:53:25 +0000199 nesting_state = cpplint.NestingState()
erg@google.com4e00b9a2009-01-12 23:05:11 +0000200 lines = code.split('\n')
201 cpplint.RemoveMultiLineComments(filename, lines, error_collector)
202 lines = cpplint.CleansedLines(lines)
203 for i in xrange(lines.NumLines()):
204 cpplint.CheckLanguage(filename, lines, i, '.h', include_state,
erg@google.comfd5da632013-10-25 17:39:45 +0000205 nesting_state, error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000206 # We could clear the error_collector here, but this should
207 # also be fine, since our IncludeWhatYouUse unittests do not
208 # have language problems.
209
210 # Second, look for missing includes.
211 cpplint.CheckForIncludeWhatYouUse(filename, lines, include_state,
erg@google.come35f7652009-06-19 20:52:09 +0000212 error_collector, io)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000213 return error_collector.Results()
214
215 # Perform lint and compare the error message with "expected_message".
216 def TestLint(self, code, expected_message):
217 self.assertEquals(expected_message, self.PerformSingleLineLint(code))
218
219 def TestMultiLineLint(self, code, expected_message):
220 self.assertEquals(expected_message, self.PerformMultiLineLint(code))
221
222 def TestMultiLineLintRE(self, code, expected_message_re):
223 message = self.PerformMultiLineLint(code)
224 if not re.search(expected_message_re, message):
225 self.fail('Message was:\n' + message + 'Expected match to "' +
226 expected_message_re + '"')
227
228 def TestLanguageRulesCheck(self, file_name, code, expected_message):
229 self.assertEquals(expected_message,
230 self.PerformLanguageRulesCheck(file_name, code))
231
232 def TestIncludeWhatYouUse(self, code, expected_message):
233 self.assertEquals(expected_message,
234 self.PerformIncludeWhatYouUse(code))
235
236 def TestBlankLinesCheck(self, lines, start_errors, end_errors):
237 error_collector = ErrorCollector(self.assert_)
238 cpplint.ProcessFileData('foo.cc', 'cc', lines, error_collector)
239 self.assertEquals(
240 start_errors,
241 error_collector.Results().count(
erg@google.com2aa59982013-10-28 19:09:25 +0000242 'Redundant blank line at the start of a code block '
243 'should be deleted. [whitespace/blank_line] [2]'))
erg@google.com4e00b9a2009-01-12 23:05:11 +0000244 self.assertEquals(
245 end_errors,
246 error_collector.Results().count(
erg@google.com2aa59982013-10-28 19:09:25 +0000247 'Redundant blank line at the end of a code block '
248 'should be deleted. [whitespace/blank_line] [3]'))
erg@google.com4e00b9a2009-01-12 23:05:11 +0000249
250
251class CpplintTest(CpplintTestBase):
252
avakulenko@google.com554223d2014-12-04 22:00:20 +0000253 def GetNamespaceResults(self, lines):
254 error_collector = ErrorCollector(self.assert_)
255 cpplint.RemoveMultiLineComments('foo.h', lines, error_collector)
256 lines = cpplint.CleansedLines(lines)
257 nesting_state = cpplint.NestingState()
258 for i in xrange(lines.NumLines()):
259 nesting_state.Update('foo.h', lines, i, error_collector)
260 cpplint.CheckForNamespaceIndentation('foo.h', nesting_state,
261 lines, i, error_collector)
262
263 return error_collector.Results()
264
265 def testForwardDeclarationNameSpaceIndentation(self):
266 lines = ['namespace Test {',
267 ' class ForwardDeclaration;',
268 '} // namespace Test']
269
270 results = self.GetNamespaceResults(lines)
271 self.assertEquals(results, 'Do not indent within a namespace '
272 ' [runtime/indentation_namespace] [4]')
273
274 def testNameSpaceIndentationForClass(self):
275 lines = ['namespace Test {',
276 'void foo() { }',
277 ' class Test {',
278 ' };',
279 '} // namespace Test']
280
281 results = self.GetNamespaceResults(lines)
282 self.assertEquals(results, 'Do not indent within a namespace '
283 ' [runtime/indentation_namespace] [4]')
284
285 def testNameSpaceIndentationNoError(self):
286 lines = ['namespace Test {',
287 'void foo() { }',
288 '} // namespace Test']
289
290 results = self.GetNamespaceResults(lines)
291 self.assertEquals(results, '')
292
Alex Vakulenko01e47232016-05-06 13:54:15 -0700293 def testWhitespaceBeforeNamespace(self):
294 lines = [' namespace Test {',
295 ' void foo() { }',
296 ' } // namespace Test']
297
298 results = self.GetNamespaceResults(lines)
299 self.assertEquals(results, '')
300
avakulenko@google.com554223d2014-12-04 22:00:20 +0000301 def testFalsePositivesNoError(self):
302 lines = ['namespace Test {',
303 'struct OuterClass {',
304 ' struct NoFalsePositivesHere;',
305 ' struct NoFalsePositivesHere member_variable;',
306 '};',
307 '} // namespace Test']
308
309 results = self.GetNamespaceResults(lines)
310 self.assertEquals(results, '')
311
312
erg@google.com4e00b9a2009-01-12 23:05:11 +0000313 # Test get line width.
314 def testGetLineWidth(self):
315 self.assertEquals(0, cpplint.GetLineWidth(''))
316 self.assertEquals(10, cpplint.GetLineWidth(u'x' * 10))
317 self.assertEquals(16, cpplint.GetLineWidth(u'都|道|府|県|支庁'))
318
erg@google.com8a95ecc2011-09-08 00:45:54 +0000319 def testGetTextInside(self):
320 self.assertEquals('', cpplint._GetTextInside('fun()', r'fun\('))
321 self.assertEquals('x, y', cpplint._GetTextInside('f(x, y)', r'f\('))
322 self.assertEquals('a(), b(c())', cpplint._GetTextInside(
323 'printf(a(), b(c()))', r'printf\('))
324 self.assertEquals('x, y{}', cpplint._GetTextInside('f[x, y{}]', r'f\['))
325 self.assertEquals(None, cpplint._GetTextInside('f[a, b(}]', r'f\['))
326 self.assertEquals(None, cpplint._GetTextInside('f[x, y]', r'f\('))
327 self.assertEquals('y, h(z, (a + b))', cpplint._GetTextInside(
328 'f(x, g(y, h(z, (a + b))))', r'g\('))
329 self.assertEquals('f(f(x))', cpplint._GetTextInside('f(f(f(x)))', r'f\('))
330 # Supports multiple lines.
331 self.assertEquals('\n return loop(x);\n',
332 cpplint._GetTextInside(
333 'int loop(int x) {\n return loop(x);\n}\n', r'\{'))
avakulenko@google.com02af6282014-06-04 18:53:25 +0000334 # '^' matches the beginning of each line.
erg@google.com8a95ecc2011-09-08 00:45:54 +0000335 self.assertEquals('x, y',
336 cpplint._GetTextInside(
337 '#include "inl.h" // skip #define\n'
338 '#define A2(x, y) a_inl_(x, y, __LINE__)\n'
339 '#define A(x) a_inl_(x, "", __LINE__)\n',
340 r'^\s*#define\s*\w+\('))
341
erg@google.com4e00b9a2009-01-12 23:05:11 +0000342 def testFindNextMultiLineCommentStart(self):
343 self.assertEquals(1, cpplint.FindNextMultiLineCommentStart([''], 0))
344
345 lines = ['a', 'b', '/* c']
346 self.assertEquals(2, cpplint.FindNextMultiLineCommentStart(lines, 0))
347
348 lines = ['char a[] = "/*";'] # not recognized as comment.
349 self.assertEquals(1, cpplint.FindNextMultiLineCommentStart(lines, 0))
350
351 def testFindNextMultiLineCommentEnd(self):
352 self.assertEquals(1, cpplint.FindNextMultiLineCommentEnd([''], 0))
353 lines = ['a', 'b', ' c */']
354 self.assertEquals(2, cpplint.FindNextMultiLineCommentEnd(lines, 0))
355
356 def testRemoveMultiLineCommentsFromRange(self):
357 lines = ['a', ' /* comment ', ' * still comment', ' comment */ ', 'b']
358 cpplint.RemoveMultiLineCommentsFromRange(lines, 1, 4)
avakulenko@google.com554223d2014-12-04 22:00:20 +0000359 self.assertEquals(['a', '/**/', '/**/', '/**/', 'b'], lines)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000360
361 def testSpacesAtEndOfLine(self):
362 self.TestLint(
363 '// Hello there ',
364 'Line ends in whitespace. Consider deleting these extra spaces.'
365 ' [whitespace/end_of_line] [4]')
366
367 # Test line length check.
368 def testLineLengthCheck(self):
369 self.TestLint(
370 '// Hello',
371 '')
372 self.TestLint(
Alex Vakulenko01e47232016-05-06 13:54:15 -0700373 '// x' + ' x' * 40,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000374 'Lines should be <= 80 characters long'
375 ' [whitespace/line_length] [2]')
376 self.TestLint(
Alex Vakulenko01e47232016-05-06 13:54:15 -0700377 '// x' + ' x' * 50,
378 'Lines should be <= 80 characters long'
379 ' [whitespace/line_length] [2]')
380 self.TestLint(
381 '// //some/path/to/f' + ('i' * 100) + 'le',
382 '')
383 self.TestLint(
384 '// //some/path/to/f' + ('i' * 100) + 'le',
385 '')
386 self.TestLint(
387 '// //some/path/to/f' + ('i' * 50) + 'le and some comments',
388 'Lines should be <= 80 characters long'
389 ' [whitespace/line_length] [2]')
erg@google.coma87abb82009-02-24 01:41:01 +0000390 self.TestLint(
391 '// http://g' + ('o' * 100) + 'gle.com/',
392 '')
393 self.TestLint(
394 '// https://g' + ('o' * 100) + 'gle.com/',
395 '')
396 self.TestLint(
397 '// https://g' + ('o' * 60) + 'gle.com/ and some comments',
398 'Lines should be <= 80 characters long'
399 ' [whitespace/line_length] [2]')
erg@google.com36649102009-03-25 21:18:36 +0000400 self.TestLint(
avakulenko@google.com554223d2014-12-04 22:00:20 +0000401 '// Read https://g' + ('o' * 60) + 'gle.com/',
erg@google.com36649102009-03-25 21:18:36 +0000402 '')
erg@google.comd7d27472011-09-07 17:36:35 +0000403 self.TestLint(
404 '// $Id: g' + ('o' * 80) + 'gle.cc#1 $',
405 '')
406 self.TestLint(
407 '// $Id: g' + ('o' * 80) + 'gle.cc#1',
408 'Lines should be <= 80 characters long'
409 ' [whitespace/line_length] [2]')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000410 self.TestMultiLineLint(
411 'static const char kCStr[] = "g' + ('o' * 50) + 'gle";\n',
412 'Lines should be <= 80 characters long'
413 ' [whitespace/line_length] [2]')
414 self.TestMultiLineLint(
415 'static const char kRawStr[] = R"(g' + ('o' * 50) + 'gle)";\n',
416 '') # no warning because raw string content is elided
417 self.TestMultiLineLint(
418 'static const char kMultiLineRawStr[] = R"(\n'
419 'g' + ('o' * 80) + 'gle\n'
420 ')";',
421 '')
422 self.TestMultiLineLint(
423 'static const char kL' + ('o' * 50) + 'ngIdentifier[] = R"()";\n',
424 'Lines should be <= 80 characters long'
425 ' [whitespace/line_length] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000426
erg+personal@google.com05189642010-04-30 20:43:03 +0000427 # Test error suppression annotations.
428 def testErrorSuppression(self):
429 # Two errors on same line:
430 self.TestLint(
431 'long a = (int64) 65;',
432 ['Using C-style cast. Use static_cast<int64>(...) instead'
433 ' [readability/casting] [4]',
434 'Use int16/int64/etc, rather than the C type long'
435 ' [runtime/int] [4]',
erg@google.com8a95ecc2011-09-08 00:45:54 +0000436 ])
erg+personal@google.com05189642010-04-30 20:43:03 +0000437 # One category of error suppressed:
438 self.TestLint(
439 'long a = (int64) 65; // NOLINT(runtime/int)',
440 'Using C-style cast. Use static_cast<int64>(...) instead'
441 ' [readability/casting] [4]')
442 # All categories suppressed: (two aliases)
443 self.TestLint('long a = (int64) 65; // NOLINT', '')
444 self.TestLint('long a = (int64) 65; // NOLINT(*)', '')
445 # Malformed NOLINT directive:
446 self.TestLint(
447 'long a = 65; // NOLINT(foo)',
erg@google.com8a95ecc2011-09-08 00:45:54 +0000448 ['Unknown NOLINT error category: foo'
449 ' [readability/nolint] [5]',
450 'Use int16/int64/etc, rather than the C type long [runtime/int] [4]',
451 ])
erg+personal@google.com05189642010-04-30 20:43:03 +0000452 # Irrelevant NOLINT directive has no effect:
453 self.TestLint(
454 'long a = 65; // NOLINT(readability/casting)',
erg@google.com8a95ecc2011-09-08 00:45:54 +0000455 'Use int16/int64/etc, rather than the C type long'
avakulenko@google.com02af6282014-06-04 18:53:25 +0000456 ' [runtime/int] [4]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000457 # NOLINTNEXTLINE silences warning for the next line instead of current line
458 error_collector = ErrorCollector(self.assert_)
459 cpplint.ProcessFileData('test.cc', 'cc',
460 ['// Copyright 2014 Your Company.',
461 '// NOLINTNEXTLINE(whitespace/line_length)',
462 '// ./command' + (' -verbose' * 80),
463 ''],
464 error_collector)
465 self.assertEquals('', error_collector.Results())
Alex Vakulenko01e47232016-05-06 13:54:15 -0700466 # LINT_C_FILE silences cast warnings for entire file.
467 error_collector = ErrorCollector(self.assert_)
468 cpplint.ProcessFileData('test.h', 'h',
469 ['// Copyright 2014 Your Company.',
470 '// NOLINT(build/header_guard)',
471 'int64 a = (uint64) 65;',
472 '// LINT_C_FILE',
473 ''],
474 error_collector)
475 self.assertEquals('', error_collector.Results())
476 # Vim modes silence cast warnings for entire file.
477 for modeline in ['vi:filetype=c',
478 'vi:sw=8 filetype=c',
479 'vi:sw=8 filetype=c ts=8',
480 'vi: filetype=c',
481 'vi: sw=8 filetype=c',
482 'vi: sw=8 filetype=c ts=8',
483 'vim:filetype=c',
484 'vim:sw=8 filetype=c',
485 'vim:sw=8 filetype=c ts=8',
486 'vim: filetype=c',
487 'vim: sw=8 filetype=c',
488 'vim: sw=8 filetype=c ts=8',
489 'vim: set filetype=c:',
490 'vim: set sw=8 filetype=c:',
491 'vim: set sw=8 filetype=c ts=8:',
492 'vim: set filetype=c :',
493 'vim: set sw=8 filetype=c :',
494 'vim: set sw=8 filetype=c ts=8 :',
495 'vim: se filetype=c:',
496 'vim: se sw=8 filetype=c:',
497 'vim: se sw=8 filetype=c ts=8:',
498 'vim: se filetype=c :',
499 'vim: se sw=8 filetype=c :',
500 'vim: se sw=8 filetype=c ts=8 :']:
501 error_collector = ErrorCollector(self.assert_)
502 cpplint.ProcessFileData('test.h', 'h',
503 ['// Copyright 2014 Your Company.',
504 '// NOLINT(build/header_guard)',
505 'int64 a = (uint64) 65;',
506 '/* Prevent warnings about the modeline',
507 modeline,
508 '*/',
509 ''],
510 error_collector)
511 self.assertEquals('', error_collector.Results())
512 # LINT_KERNEL_FILE silences whitespace/tab warnings for entire file.
513 error_collector = ErrorCollector(self.assert_)
514 cpplint.ProcessFileData('test.h', 'h',
515 ['// Copyright 2014 Your Company.',
516 '// NOLINT(build/header_guard)',
517 'struct test {',
518 '\tint member;',
519 '};',
520 '// LINT_KERNEL_FILE',
521 ''],
522 error_collector)
523 self.assertEquals('', error_collector.Results())
Piotr Semenova3c36d92016-06-30 11:45:37 +0300524 # NOLINT, NOLINTNEXTLINE silences the readability/braces warning for "};".
525 error_collector = ErrorCollector(self.assert_)
526 cpplint.ProcessFileData('test.cc', 'cc',
527 ['// Copyright 2014 Your Company.',
528 'for (int i = 0; i != 100; ++i) {',
529 '\tstd::cout << i << std::endl;',
530 '}; // NOLINT',
531 'for (int i = 0; i != 100; ++i) {',
532 '\tstd::cout << i << std::endl;',
533 '// NOLINTNEXTLINE',
534 '};',
535 '// LINT_KERNEL_FILE',
536 ''],
537 error_collector)
538 self.assertEquals('', error_collector.Results())
erg+personal@google.com05189642010-04-30 20:43:03 +0000539
erg@google.com4e00b9a2009-01-12 23:05:11 +0000540 # Test Variable Declarations.
541 def testVariableDeclarations(self):
542 self.TestLint(
543 'long a = 65;',
544 'Use int16/int64/etc, rather than the C type long'
545 ' [runtime/int] [4]')
546 self.TestLint(
547 'long double b = 65.0;',
548 '')
549 self.TestLint(
550 'long long aa = 6565;',
551 'Use int16/int64/etc, rather than the C type long'
552 ' [runtime/int] [4]')
553
554 # Test C-style cast cases.
555 def testCStyleCast(self):
556 self.TestLint(
557 'int a = (int)1.0;',
558 'Using C-style cast. Use static_cast<int>(...) instead'
559 ' [readability/casting] [4]')
560 self.TestLint(
avakulenko@google.com554223d2014-12-04 22:00:20 +0000561 'int a = (int)-1.0;',
562 'Using C-style cast. Use static_cast<int>(...) instead'
563 ' [readability/casting] [4]')
564 self.TestLint(
erg@google.com8f91ab22011-09-06 21:04:45 +0000565 'int *a = (int *)NULL;',
erg@google.com4e00b9a2009-01-12 23:05:11 +0000566 'Using C-style cast. Use reinterpret_cast<int *>(...) instead'
567 ' [readability/casting] [4]')
568
569 self.TestLint(
570 'uint16 a = (uint16)1.0;',
571 'Using C-style cast. Use static_cast<uint16>(...) instead'
572 ' [readability/casting] [4]')
573 self.TestLint(
574 'int32 a = (int32)1.0;',
575 'Using C-style cast. Use static_cast<int32>(...) instead'
576 ' [readability/casting] [4]')
577 self.TestLint(
578 'uint64 a = (uint64)1.0;',
579 'Using C-style cast. Use static_cast<uint64>(...) instead'
580 ' [readability/casting] [4]')
581
582 # These shouldn't be recognized casts.
583 self.TestLint('u a = (u)NULL;', '')
584 self.TestLint('uint a = (uint)NULL;', '')
erg@google.comc6671232013-10-25 21:44:03 +0000585 self.TestLint('typedef MockCallback<int(int)> CallbackType;', '')
586 self.TestLint('scoped_ptr< MockCallback<int(int)> > callback_value;', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000587 self.TestLint('std::function<int(bool)>', '')
588 self.TestLint('x = sizeof(int)', '')
589 self.TestLint('x = alignof(int)', '')
590 self.TestLint('alignas(int) char x[42]', '')
591 self.TestLint('alignas(alignof(x)) char y[42]', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +0000592 self.TestLint('void F(int (func)(int));', '')
593 self.TestLint('void F(int (func)(int*));', '')
594 self.TestLint('void F(int (Class::member)(int));', '')
595 self.TestLint('void F(int (Class::member)(int*));', '')
596 self.TestLint('void F(int (Class::member)(int), int param);', '')
597 self.TestLint('void F(int (Class::member)(int*), int param);', '')
598
599 # These should not be recognized (lambda functions without arg names).
600 self.TestLint('[](int/*unused*/) -> bool {', '')
601 self.TestLint('[](int /*unused*/) -> bool {', '')
602 self.TestLint('auto f = [](MyStruct* /*unused*/)->int {', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -0700603 self.TestLint('[](int) -> bool {', '')
604 self.TestLint('auto f = [](MyStruct*)->int {', '')
605
606 # Cast with brace initializers
607 self.TestLint('int64_t{4096} * 1000 * 1000', '')
608 self.TestLint('size_t{4096} * 1000 * 1000', '')
609 self.TestLint('uint_fast16_t{4096} * 1000 * 1000', '')
610
611 # Brace initializer with templated type
612 self.TestMultiLineLint(
613 """
614 template <typename Type1,
615 typename Type2>
616 void Function(int arg1,
617 int arg2) {
618 variable &= ~Type1{0} - 1;
619 }""",
620 '')
621 self.TestMultiLineLint(
622 """
623 template <typename Type>
624 class Class {
625 void Function() {
626 variable &= ~Type{0} - 1;
627 }
628 };""",
629 '')
630 self.TestMultiLineLint(
631 """
632 template <typename Type>
633 class Class {
634 void Function() {
635 variable &= ~Type{0} - 1;
636 }
637 };""",
638 '')
639 self.TestMultiLineLint(
640 """
641 namespace {
642 template <typename Type>
643 class Class {
644 void Function() {
645 if (block) {
646 variable &= ~Type{0} - 1;
647 }
648 }
649 };
650 }""",
651 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000652
653 # Test taking address of casts (runtime/casting)
654 def testRuntimeCasting(self):
erg@google.comc6671232013-10-25 21:44:03 +0000655 error_msg = ('Are you taking an address of a cast? '
656 'This is dangerous: could be a temp var. '
657 'Take the address before doing the cast, rather than after'
658 ' [runtime/casting] [4]')
659 self.TestLint('int* x = &static_cast<int*>(foo);', error_msg)
660 self.TestLint('int* x = &reinterpret_cast<int *>(foo);', error_msg)
661 self.TestLint('int* x = &(int*)foo;',
662 ['Using C-style cast. Use reinterpret_cast<int*>(...) '
663 'instead [readability/casting] [4]',
664 error_msg])
avakulenko@google.com554223d2014-12-04 22:00:20 +0000665 self.TestLint('BudgetBuckets&(BudgetWinHistory::*BucketFn)(void) const;',
666 '')
667 self.TestLint('&(*func_ptr)(arg)', '')
668 self.TestLint('Compute(arg, &(*func_ptr)(i, j));', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000669
avakulenko@google.com02af6282014-06-04 18:53:25 +0000670 # Alternative error message
671 alt_error_msg = ('Are you taking an address of something dereferenced '
672 'from a cast? Wrapping the dereferenced expression in '
673 'parentheses will make the binding more obvious'
674 ' [readability/casting] [4]')
675 self.TestLint('int* x = &down_cast<Obj*>(obj)->member_;', alt_error_msg)
676 self.TestLint('int* x = &down_cast<Obj*>(obj)[index];', alt_error_msg)
677 self.TestLint('int* x = &(down_cast<Obj*>(obj)->member_);', '')
678 self.TestLint('int* x = &(down_cast<Obj*>(obj)[index]);', '')
679 self.TestLint('int* x = &down_cast<Obj*>(obj)\n->member_;', alt_error_msg)
680 self.TestLint('int* x = &(down_cast<Obj*>(obj)\n->member_);', '')
681
erg@google.com4e00b9a2009-01-12 23:05:11 +0000682 # It's OK to cast an address.
erg@google.comc6671232013-10-25 21:44:03 +0000683 self.TestLint('int* x = reinterpret_cast<int *>(&foo);', '')
684
685 # Function pointers returning references should not be confused
686 # with taking address of old-style casts.
687 self.TestLint('auto x = implicit_cast<string &(*)(int)>(&foo);', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000688
689 def testRuntimeSelfinit(self):
690 self.TestLint(
691 'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }',
692 'You seem to be initializing a member variable with itself.'
693 ' [runtime/init] [4]')
694 self.TestLint(
Alex Vakulenko01e47232016-05-06 13:54:15 -0700695 'Foo::Foo(Bar r, Bel l) : r_(CHECK_NOTNULL(r_)) { }',
696 'You seem to be initializing a member variable with itself.'
697 ' [runtime/init] [4]')
698 self.TestLint(
erg@google.com4e00b9a2009-01-12 23:05:11 +0000699 'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }',
700 '')
701 self.TestLint(
702 'Foo::Foo(Bar r) : r_(r), l_(r_), ll_(l_) { }',
703 '')
704
erg@google.com4e00b9a2009-01-12 23:05:11 +0000705 # Test for unnamed arguments in a method.
706 def testCheckForUnnamedParams(self):
Alex Vakulenko01e47232016-05-06 13:54:15 -0700707 self.TestLint('virtual void Func(int*) const;', '')
708 self.TestLint('virtual void Func(int*);', '')
709 self.TestLint('void Method(char*) {', '')
710 self.TestLint('void Method(char*);', '')
711 self.TestLint('static void operator delete[](void*) throw();', '')
712 self.TestLint('int Method(int);', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000713
avakulenko@google.com02af6282014-06-04 18:53:25 +0000714 self.TestLint('virtual void Func(int* p);', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000715 self.TestLint('void operator delete(void* x) throw();', '')
716 self.TestLint('void Method(char* x) {', '')
717 self.TestLint('void Method(char* /*x*/) {', '')
718 self.TestLint('void Method(char* x);', '')
719 self.TestLint('typedef void (*Method)(int32 x);', '')
720 self.TestLint('static void operator delete[](void* x) throw();', '')
721 self.TestLint('static void operator delete[](void* /*x*/) throw();', '')
722
erg@google.comd350fe52013-01-14 17:51:48 +0000723 self.TestLint('X operator++(int);', '')
724 self.TestLint('X operator++(int) {', '')
725 self.TestLint('X operator--(int);', '')
726 self.TestLint('X operator--(int /*unused*/) {', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000727 self.TestLint('MACRO(int);', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +0000728 self.TestLint('MACRO(func(int));', '')
729 self.TestLint('MACRO(arg, func(int));', '')
erg@google.comd350fe52013-01-14 17:51:48 +0000730
erg@google.comc6671232013-10-25 21:44:03 +0000731 self.TestLint('void (*func)(void*);', '')
732 self.TestLint('void Func((*func)(void*)) {}', '')
733 self.TestLint('template <void Func(void*)> void func();', '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000734 self.TestLint('virtual void f(int /*unused*/) {', '')
735 self.TestLint('void f(int /*unused*/) override {', '')
736 self.TestLint('void f(int /*unused*/) final {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000737
738 # Test deprecated casts such as int(d)
739 def testDeprecatedCast(self):
740 self.TestLint(
741 'int a = int(2.2);',
742 'Using deprecated casting style. '
743 'Use static_cast<int>(...) instead'
744 ' [readability/casting] [4]')
erg@google.com8a95ecc2011-09-08 00:45:54 +0000745
746 self.TestLint(
747 '(char *) "foo"',
748 'Using C-style cast. '
749 'Use const_cast<char *>(...) instead'
750 ' [readability/casting] [4]')
751
752 self.TestLint(
753 '(int*)foo',
754 'Using C-style cast. '
755 'Use reinterpret_cast<int*>(...) instead'
756 ' [readability/casting] [4]')
757
erg@google.com4e00b9a2009-01-12 23:05:11 +0000758 # Checks for false positives...
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000759 self.TestLint('int a = int();', '') # constructor
760 self.TestLint('X::X() : a(int()) {}', '') # default constructor
761 self.TestLint('operator bool();', '') # Conversion operator
762 self.TestLint('new int64(123);', '') # "new" operator on basic type
763 self.TestLint('new int64(123);', '') # "new" operator on basic type
Alex Vakulenko01e47232016-05-06 13:54:15 -0700764 self.TestLint('new const int(42);', '') # "new" on const-qualified type
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000765 self.TestLint('using a = bool(int arg);', '') # C++11 alias-declaration
766 self.TestLint('x = bit_cast<double(*)[3]>(y);', '') # array of array
767 self.TestLint('void F(const char(&src)[N]);', '') # array of references
768
769 # Placement new
avakulenko@google.com02af6282014-06-04 18:53:25 +0000770 self.TestLint(
771 'new(field_ptr) int(field->default_value_enum()->number());',
772 '')
773
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000774 # C++11 function wrappers
775 self.TestLint('std::function<int(bool)>', '')
776 self.TestLint('std::function<const int(bool)>', '')
777 self.TestLint('std::function< int(bool) >', '')
778 self.TestLint('mfunction<int(bool)>', '')
779
avakulenko@google.com02af6282014-06-04 18:53:25 +0000780 error_collector = ErrorCollector(self.assert_)
781 cpplint.ProcessFileData(
782 'test.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000783 ['// Copyright 2014 Your Company. All Rights Reserved.',
avakulenko@google.com02af6282014-06-04 18:53:25 +0000784 'typedef std::function<',
785 ' bool(int)> F;',
786 ''],
787 error_collector)
788 self.assertEquals('', error_collector.Results())
erg@google.comc6671232013-10-25 21:44:03 +0000789
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000790 # Return types for function pointers
791 self.TestLint('typedef bool(FunctionPointer)();', '')
792 self.TestLint('typedef bool(FunctionPointer)(int param);', '')
793 self.TestLint('typedef bool(MyClass::*MemberFunctionPointer)();', '')
794 self.TestLint('typedef bool(MyClass::* MemberFunctionPointer)();', '')
795 self.TestLint('typedef bool(MyClass::*MemberFunctionPointer)() const;', '')
796 self.TestLint('void Function(bool(FunctionPointerArg)());', '')
797 self.TestLint('void Function(bool(FunctionPointerArg)()) {}', '')
798 self.TestLint('typedef set<int64, bool(*)(int64, int64)> SortedIdSet', '')
erg@google.comc6671232013-10-25 21:44:03 +0000799 self.TestLint(
800 'bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *t)) {}',
801 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000802
803 # The second parameter to a gMock method definition is a function signature
804 # that often looks like a bad cast but should not picked up by lint.
805 def testMockMethod(self):
806 self.TestLint(
807 'MOCK_METHOD0(method, int());',
808 '')
809 self.TestLint(
810 'MOCK_CONST_METHOD1(method, float(string));',
811 '')
812 self.TestLint(
813 'MOCK_CONST_METHOD2_T(method, double(float, float));',
814 '')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000815 self.TestLint(
816 'MOCK_CONST_METHOD1(method, SomeType(int));',
817 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000818
erg@google.comd350fe52013-01-14 17:51:48 +0000819 error_collector = ErrorCollector(self.assert_)
820 cpplint.ProcessFileData('mock.cc', 'cc',
821 ['MOCK_METHOD1(method1,',
erg@google.comc6671232013-10-25 21:44:03 +0000822 ' bool(int));',
823 'MOCK_METHOD1(',
824 ' method2,',
825 ' bool(int));',
826 'MOCK_CONST_METHOD2(',
827 ' method3, bool(int,',
828 ' int));',
829 'MOCK_METHOD1(method4, int(bool));',
erg@google.comd350fe52013-01-14 17:51:48 +0000830 'const int kConstant = int(42);'], # true positive
831 error_collector)
832 self.assertEquals(
833 0,
834 error_collector.Results().count(
835 ('Using deprecated casting style. '
836 'Use static_cast<bool>(...) instead '
837 '[readability/casting] [4]')))
838 self.assertEquals(
839 1,
840 error_collector.Results().count(
841 ('Using deprecated casting style. '
842 'Use static_cast<int>(...) instead '
843 '[readability/casting] [4]')))
844
erg@google.comd7d27472011-09-07 17:36:35 +0000845 # Like gMock method definitions, MockCallback instantiations look very similar
846 # to bad casts.
847 def testMockCallback(self):
848 self.TestLint(
849 'MockCallback<bool(int)>',
850 '')
851 self.TestLint(
852 'MockCallback<int(float, char)>',
853 '')
854
erg@google.come35f7652009-06-19 20:52:09 +0000855 # Test false errors that happened with some include file names
856 def testIncludeFilenameFalseError(self):
857 self.TestLint(
858 '#include "foo/long-foo.h"',
859 '')
860 self.TestLint(
861 '#include "foo/sprintf.h"',
862 '')
863
erg@google.com4e00b9a2009-01-12 23:05:11 +0000864 # Test typedef cases. There was a bug that cpplint misidentified
865 # typedef for pointer to function as C-style cast and produced
866 # false-positive error messages.
867 def testTypedefForPointerToFunction(self):
868 self.TestLint(
869 'typedef void (*Func)(int x);',
870 '')
871 self.TestLint(
872 'typedef void (*Func)(int *x);',
873 '')
874 self.TestLint(
875 'typedef void Func(int x);',
876 '')
877 self.TestLint(
878 'typedef void Func(int *x);',
879 '')
880
881 def testIncludeWhatYouUseNoImplementationFiles(self):
882 code = 'std::vector<int> foo;'
883 self.assertEquals('Add #include <vector> for vector<>'
884 ' [build/include_what_you_use] [4]',
885 self.PerformIncludeWhatYouUse(code, 'foo.h'))
886 self.assertEquals('',
887 self.PerformIncludeWhatYouUse(code, 'foo.cc'))
888
889 def testIncludeWhatYouUse(self):
890 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000891 """#include <vector>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000892 std::vector<int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000893 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000894 '')
895 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000896 """#include <map>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000897 std::pair<int,int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000898 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000899 'Add #include <utility> for pair<>'
900 ' [build/include_what_you_use] [4]')
901 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000902 """#include <multimap>
903 std::pair<int,int> foo;
904 """,
905 'Add #include <utility> for pair<>'
906 ' [build/include_what_you_use] [4]')
907 self.TestIncludeWhatYouUse(
908 """#include <hash_map>
909 std::pair<int,int> foo;
910 """,
911 'Add #include <utility> for pair<>'
912 ' [build/include_what_you_use] [4]')
913 self.TestIncludeWhatYouUse(
lhchavez2890dff2016-07-11 19:37:29 -0700914 """#include <hash_map>
915 auto foo = std::make_pair(1, 2);
916 """,
917 'Add #include <utility> for make_pair'
918 ' [build/include_what_you_use] [4]')
919 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000920 """#include <utility>
921 std::pair<int,int> foo;
922 """,
923 '')
924 self.TestIncludeWhatYouUse(
925 """#include <vector>
926 DECLARE_string(foobar);
927 """,
928 '')
929 self.TestIncludeWhatYouUse(
930 """#include <vector>
931 DEFINE_string(foobar, "", "");
932 """,
933 '')
934 self.TestIncludeWhatYouUse(
935 """#include <vector>
936 std::pair<int,int> foo;
937 """,
938 'Add #include <utility> for pair<>'
939 ' [build/include_what_you_use] [4]')
940 self.TestIncludeWhatYouUse(
941 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000942 std::vector<int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000943 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000944 'Add #include <vector> for vector<>'
945 ' [build/include_what_you_use] [4]')
946 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000947 """#include <vector>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000948 std::set<int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000949 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000950 'Add #include <set> for set<>'
951 ' [build/include_what_you_use] [4]')
952 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000953 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000954 hash_map<int, int> foobar;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000955 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000956 'Add #include <hash_map> for hash_map<>'
957 ' [build/include_what_you_use] [4]')
958 self.TestIncludeWhatYouUse(
lhchavez3ae81f12016-07-11 19:00:34 -0700959 """#include "base/containers/hash_tables.h"
960 base::hash_map<int, int> foobar;
961 """,
962 '')
963 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000964 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000965 bool foobar = std::less<int>(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000966 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000967 'Add #include <functional> for less<>'
968 ' [build/include_what_you_use] [4]')
969 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000970 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000971 bool foobar = min<int>(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000972 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000973 'Add #include <algorithm> for min [build/include_what_you_use] [4]')
974 self.TestIncludeWhatYouUse(
975 'void a(const string &foobar);',
976 'Add #include <string> for string [build/include_what_you_use] [4]')
977 self.TestIncludeWhatYouUse(
erg+personal@google.com05189642010-04-30 20:43:03 +0000978 'void a(const std::string &foobar);',
979 'Add #include <string> for string [build/include_what_you_use] [4]')
980 self.TestIncludeWhatYouUse(
981 'void a(const my::string &foobar);',
982 '') # Avoid false positives on strings in other namespaces.
983 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000984 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000985 bool foobar = swap(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000986 """,
Alex Vakulenko01e47232016-05-06 13:54:15 -0700987 'Add #include <utility> for swap [build/include_what_you_use] [4]')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000988 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000989 """#include "base/foobar.h"
erg@google.coma87abb82009-02-24 01:41:01 +0000990 bool foobar = transform(a.begin(), a.end(), b.start(), Foo);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000991 """,
erg@google.coma87abb82009-02-24 01:41:01 +0000992 'Add #include <algorithm> for transform '
993 '[build/include_what_you_use] [4]')
994 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000995 """#include "base/foobar.h"
erg@google.coma87abb82009-02-24 01:41:01 +0000996 bool foobar = min_element(a.begin(), a.end());
erg@google.com8a95ecc2011-09-08 00:45:54 +0000997 """,
erg@google.coma87abb82009-02-24 01:41:01 +0000998 'Add #include <algorithm> for min_element '
999 '[build/include_what_you_use] [4]')
1000 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001001 """foo->swap(0,1);
erg@google.com4e00b9a2009-01-12 23:05:11 +00001002 foo.swap(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +00001003 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +00001004 '')
1005 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001006 """#include <string>
erg@google.com4e00b9a2009-01-12 23:05:11 +00001007 void a(const std::multimap<int,string> &foobar);
erg@google.com8a95ecc2011-09-08 00:45:54 +00001008 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +00001009 'Add #include <map> for multimap<>'
1010 ' [build/include_what_you_use] [4]')
1011 self.TestIncludeWhatYouUse(
lhchavez2890dff2016-07-11 19:37:29 -07001012 """#include <string>
1013 void a(const std::unordered_map<int,string> &foobar);
1014 """,
1015 'Add #include <unordered_map> for unordered_map<>'
1016 ' [build/include_what_you_use] [4]')
1017 self.TestIncludeWhatYouUse(
1018 """#include <string>
1019 void a(const std::unordered_set<int> &foobar);
1020 """,
1021 'Add #include <unordered_set> for unordered_set<>'
1022 ' [build/include_what_you_use] [4]')
1023 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001024 """#include <queue>
erg@google.com4e00b9a2009-01-12 23:05:11 +00001025 void a(const std::priority_queue<int> &foobar);
erg@google.com8a95ecc2011-09-08 00:45:54 +00001026 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +00001027 '')
1028 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001029 """#include <assert.h>
erg@google.com4e00b9a2009-01-12 23:05:11 +00001030 #include <string>
1031 #include <vector>
1032 #include "base/basictypes.h"
1033 #include "base/port.h"
erg@google.com8a95ecc2011-09-08 00:45:54 +00001034 vector<string> hajoa;""", '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001035 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001036 """#include <string>
erg@google.com4e00b9a2009-01-12 23:05:11 +00001037 int i = numeric_limits<int>::max()
erg@google.com8a95ecc2011-09-08 00:45:54 +00001038 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +00001039 'Add #include <limits> for numeric_limits<>'
1040 ' [build/include_what_you_use] [4]')
1041 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001042 """#include <limits>
erg@google.com4e00b9a2009-01-12 23:05:11 +00001043 int i = numeric_limits<int>::max()
erg@google.com8a95ecc2011-09-08 00:45:54 +00001044 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +00001045 '')
lhchavez2890dff2016-07-11 19:37:29 -07001046 self.TestIncludeWhatYouUse(
1047 """#include <string>
1048 std::unique_ptr<int> x;
1049 """,
1050 'Add #include <memory> for unique_ptr<>'
1051 ' [build/include_what_you_use] [4]')
1052 self.TestIncludeWhatYouUse(
1053 """#include <string>
1054 auto x = std::make_unique<int>(0);
1055 """,
1056 'Add #include <memory> for make_unique<>'
1057 ' [build/include_what_you_use] [4]')
1058 self.TestIncludeWhatYouUse(
1059 """#include <vector>
1060 vector<int> foo(vector<int> x) { return std::move(x); }
1061 """,
1062 'Add #include <utility> for move'
1063 ' [build/include_what_you_use] [4]')
1064 self.TestIncludeWhatYouUse(
1065 """#include <string>
1066 int a, b;
1067 std::swap(a, b);
1068 """,
1069 'Add #include <utility> for swap'
1070 ' [build/include_what_you_use] [4]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001071
erg@google.come35f7652009-06-19 20:52:09 +00001072 # Test the UpdateIncludeState code path.
1073 mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"']
1074 message = self.PerformIncludeWhatYouUse(
1075 '#include "blah/a.h"',
1076 filename='blah/a.cc',
1077 io=MockIo(mock_header_contents))
1078 self.assertEquals(message, '')
1079
1080 mock_header_contents = ['#include <set>']
1081 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001082 """#include "blah/a.h"
1083 std::set<int> foo;""",
erg@google.come35f7652009-06-19 20:52:09 +00001084 filename='blah/a.cc',
1085 io=MockIo(mock_header_contents))
1086 self.assertEquals(message, '')
1087
1088 # Make sure we can find the correct header file if the cc file seems to be
1089 # a temporary file generated by Emacs's flymake.
1090 mock_header_contents = ['']
1091 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001092 """#include "blah/a.h"
1093 std::set<int> foo;""",
erg@google.come35f7652009-06-19 20:52:09 +00001094 filename='blah/a_flymake.cc',
1095 io=MockIo(mock_header_contents))
1096 self.assertEquals(message, 'Add #include <set> for set<> '
erg@google.com8a95ecc2011-09-08 00:45:54 +00001097 '[build/include_what_you_use] [4]')
erg@google.come35f7652009-06-19 20:52:09 +00001098
1099 # If there's just a cc and the header can't be found then it's ok.
1100 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001101 """#include "blah/a.h"
1102 std::set<int> foo;""",
erg@google.come35f7652009-06-19 20:52:09 +00001103 filename='blah/a.cc')
1104 self.assertEquals(message, '')
1105
1106 # Make sure we find the headers with relative paths.
1107 mock_header_contents = ['']
1108 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001109 """#include "%s/a.h"
1110 std::set<int> foo;""" % os.path.basename(os.getcwd()),
erg@google.come35f7652009-06-19 20:52:09 +00001111 filename='a.cc',
1112 io=MockIo(mock_header_contents))
1113 self.assertEquals(message, 'Add #include <set> for set<> '
erg@google.com8a95ecc2011-09-08 00:45:54 +00001114 '[build/include_what_you_use] [4]')
erg@google.come35f7652009-06-19 20:52:09 +00001115
1116 def testFilesBelongToSameModule(self):
1117 f = cpplint.FilesBelongToSameModule
1118 self.assertEquals((True, ''), f('a.cc', 'a.h'))
1119 self.assertEquals((True, ''), f('base/google.cc', 'base/google.h'))
1120 self.assertEquals((True, ''), f('base/google_test.cc', 'base/google.h'))
1121 self.assertEquals((True, ''),
1122 f('base/google_unittest.cc', 'base/google.h'))
1123 self.assertEquals((True, ''),
1124 f('base/internal/google_unittest.cc',
1125 'base/public/google.h'))
1126 self.assertEquals((True, 'xxx/yyy/'),
1127 f('xxx/yyy/base/internal/google_unittest.cc',
1128 'base/public/google.h'))
1129 self.assertEquals((True, 'xxx/yyy/'),
1130 f('xxx/yyy/base/google_unittest.cc',
1131 'base/public/google.h'))
1132 self.assertEquals((True, ''),
1133 f('base/google_unittest.cc', 'base/google-inl.h'))
1134 self.assertEquals((True, '/home/build/google3/'),
1135 f('/home/build/google3/base/google.cc', 'base/google.h'))
1136
1137 self.assertEquals((False, ''),
1138 f('/home/build/google3/base/google.cc', 'basu/google.h'))
1139 self.assertEquals((False, ''), f('a.cc', 'b.h'))
1140
erg@google.com4e00b9a2009-01-12 23:05:11 +00001141 def testCleanseLine(self):
erg@google.comd7d27472011-09-07 17:36:35 +00001142 self.assertEquals('int foo = 0;',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001143 cpplint.CleanseComments('int foo = 0; // danger!'))
1144 self.assertEquals('int o = 0;',
1145 cpplint.CleanseComments('int /* foo */ o = 0;'))
1146 self.assertEquals('foo(int a, int b);',
1147 cpplint.CleanseComments('foo(int a /* abc */, int b);'))
1148 self.assertEqual('f(a, b);',
1149 cpplint.CleanseComments('f(a, /* name */ b);'))
1150 self.assertEqual('f(a, b);',
erg@google.com2aa59982013-10-28 19:09:25 +00001151 cpplint.CleanseComments('f(a /* name */, b);'))
erg@google.com4e00b9a2009-01-12 23:05:11 +00001152 self.assertEqual('f(a, b);',
1153 cpplint.CleanseComments('f(a, /* name */b);'))
avakulenko@google.com02af6282014-06-04 18:53:25 +00001154 self.assertEqual('f(a, b, c);',
1155 cpplint.CleanseComments('f(a, /**/b, /**/c);'))
1156 self.assertEqual('f(a, b, c);',
1157 cpplint.CleanseComments('f(a, /**/b/**/, c);'))
erg@google.com4e00b9a2009-01-12 23:05:11 +00001158
erg@google.com2aa59982013-10-28 19:09:25 +00001159 def testRawStrings(self):
1160 self.TestMultiLineLint(
1161 """
1162 void Func() {
1163 static const char kString[] = R"(
1164 #endif <- invalid preprocessor should be ignored
1165 */ <- invalid comment should be ignored too
1166 )";
1167 }""",
1168 '')
1169 self.TestMultiLineLint(
1170 """
1171 void Func() {
1172 string s = R"TrueDelimiter(
1173 )"
1174 )FalseDelimiter"
1175 )TrueDelimiter";
1176 }""",
1177 '')
1178 self.TestMultiLineLint(
1179 """
1180 void Func() {
1181 char char kString[] = R"( ";" )";
1182 }""",
1183 '')
1184 self.TestMultiLineLint(
1185 """
1186 static const char kRawString[] = R"(
1187 \tstatic const int kLineWithTab = 1;
1188 static const int kLineWithTrailingWhiteSpace = 1;\x20
1189
1190 void WeirdNumberOfSpacesAtLineStart() {
1191 string x;
1192 x += StrCat("Use StrAppend instead");
1193 }
1194
1195 void BlankLineAtEndOfBlock() {
1196 // TODO incorrectly formatted
1197 //Badly formatted comment
1198
1199 }
1200
1201 )";""",
1202 '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00001203 self.TestMultiLineLint(
1204 """
1205 void Func() {
1206 string s = StrCat(R"TrueDelimiter(
1207 )"
1208 )FalseDelimiter"
1209 )TrueDelimiter", R"TrueDelimiter2(
1210 )"
1211 )FalseDelimiter2"
1212 )TrueDelimiter2");
1213 }""",
1214 '')
1215 self.TestMultiLineLint(
1216 """
1217 static SomeStruct kData = {
1218 {0, R"(line1
1219 line2
1220 )"}
1221 };""",
1222 '')
erg@google.com2aa59982013-10-28 19:09:25 +00001223
erg@google.com4e00b9a2009-01-12 23:05:11 +00001224 def testMultiLineComments(self):
1225 # missing explicit is bad
1226 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001227 r"""int a = 0;
erg@google.com4e00b9a2009-01-12 23:05:11 +00001228 /* multi-liner
1229 class Foo {
1230 Foo(int f); // should cause a lint warning in code
1231 }
erg@google.com8a95ecc2011-09-08 00:45:54 +00001232 */ """,
erg@google.com4e00b9a2009-01-12 23:05:11 +00001233 '')
1234 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001235 r"""/* int a = 0; multi-liner
1236 static const int b = 0;""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001237 'Could not find end of multi-line comment'
1238 ' [readability/multiline_comment] [5]')
erg@google.com8a95ecc2011-09-08 00:45:54 +00001239 self.TestMultiLineLint(r""" /* multi-line comment""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001240 'Could not find end of multi-line comment'
1241 ' [readability/multiline_comment] [5]')
erg@google.com8a95ecc2011-09-08 00:45:54 +00001242 self.TestMultiLineLint(r""" // /* comment, but not multi-line""", '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001243 self.TestMultiLineLint(r"""/**********
1244 */""", '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00001245 self.TestMultiLineLint(r"""/**
1246 * Doxygen comment
1247 */""",
1248 '')
1249 self.TestMultiLineLint(r"""/*!
1250 * Doxygen comment
1251 */""",
1252 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001253
1254 def testMultilineStrings(self):
1255 multiline_string_error_message = (
1256 'Multi-line string ("...") found. This lint script doesn\'t '
erg@google.com2aa59982013-10-28 19:09:25 +00001257 'do well with such strings, and may give bogus warnings. '
1258 'Use C++11 raw strings or concatenation instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00001259 ' [readability/multiline_string] [5]')
1260
1261 file_path = 'mydir/foo.cc'
1262
1263 error_collector = ErrorCollector(self.assert_)
1264 cpplint.ProcessFileData(file_path, 'cc',
1265 ['const char* str = "This is a\\',
1266 ' multiline string.";'],
1267 error_collector)
1268 self.assertEquals(
1269 2, # One per line.
1270 error_collector.ResultList().count(multiline_string_error_message))
1271
1272 # Test non-explicit single-argument constructors
1273 def testExplicitSingleArgumentConstructors(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001274 old_verbose_level = cpplint._cpplint_state.verbose_level
1275 cpplint._cpplint_state.verbose_level = 0
1276
1277 try:
1278 # missing explicit is bad
1279 self.TestMultiLineLint(
1280 """
1281 class Foo {
1282 Foo(int f);
1283 };""",
1284 'Single-parameter constructors should be marked explicit.'
1285 ' [runtime/explicit] [5]')
1286 # missing explicit is bad, even with whitespace
1287 self.TestMultiLineLint(
1288 """
1289 class Foo {
1290 Foo (int f);
1291 };""",
1292 ['Extra space before ( in function call [whitespace/parens] [4]',
1293 'Single-parameter constructors should be marked explicit.'
1294 ' [runtime/explicit] [5]'])
1295 # missing explicit, with distracting comment, is still bad
1296 self.TestMultiLineLint(
1297 """
1298 class Foo {
1299 Foo(int f); // simpler than Foo(blargh, blarg)
1300 };""",
1301 'Single-parameter constructors should be marked explicit.'
1302 ' [runtime/explicit] [5]')
1303 # missing explicit, with qualified classname
1304 self.TestMultiLineLint(
1305 """
1306 class Qualifier::AnotherOne::Foo {
1307 Foo(int f);
1308 };""",
1309 'Single-parameter constructors should be marked explicit.'
1310 ' [runtime/explicit] [5]')
1311 # missing explicit for inline constructors is bad as well
1312 self.TestMultiLineLint(
1313 """
1314 class Foo {
1315 inline Foo(int f);
1316 };""",
1317 'Single-parameter constructors should be marked explicit.'
1318 ' [runtime/explicit] [5]')
Dana Jansens2db65fe2017-03-02 13:19:58 -05001319 # missing explicit for constexpr constructors is bad as well
1320 self.TestMultiLineLint(
1321 """
1322 class Foo {
1323 constexpr Foo(int f);
1324 };""",
1325 'Single-parameter constructors should be marked explicit.'
1326 ' [runtime/explicit] [5]')
1327 # missing explicit for constexpr+inline constructors is bad as well
1328 self.TestMultiLineLint(
1329 """
1330 class Foo {
1331 constexpr inline Foo(int f);
1332 };""",
1333 'Single-parameter constructors should be marked explicit.'
1334 ' [runtime/explicit] [5]')
1335 self.TestMultiLineLint(
1336 """
1337 class Foo {
1338 inline constexpr Foo(int f);
1339 };""",
1340 'Single-parameter constructors should be marked explicit.'
1341 ' [runtime/explicit] [5]')
1342 # explicit with inline is accepted
1343 self.TestMultiLineLint(
1344 """
1345 class Foo {
1346 inline explicit Foo(int f);
1347 };""",
1348 '')
1349 self.TestMultiLineLint(
1350 """
1351 class Foo {
1352 explicit inline Foo(int f);
1353 };""",
1354 '')
1355 # explicit with constexpr is accepted
1356 self.TestMultiLineLint(
1357 """
1358 class Foo {
1359 constexpr explicit Foo(int f);
1360 };""",
1361 '')
1362 self.TestMultiLineLint(
1363 """
1364 class Foo {
1365 explicit constexpr Foo(int f);
1366 };""",
1367 '')
1368 # explicit with constexpr+inline is accepted
1369 self.TestMultiLineLint(
1370 """
1371 class Foo {
1372 inline constexpr explicit Foo(int f);
1373 };""",
1374 '')
1375 self.TestMultiLineLint(
1376 """
1377 class Foo {
1378 explicit inline constexpr Foo(int f);
1379 };""",
1380 '')
1381 self.TestMultiLineLint(
1382 """
1383 class Foo {
1384 constexpr inline explicit Foo(int f);
1385 };""",
1386 '')
1387 self.TestMultiLineLint(
1388 """
1389 class Foo {
1390 explicit constexpr inline Foo(int f);
1391 };""",
1392 '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001393 # structs are caught as well.
1394 self.TestMultiLineLint(
1395 """
1396 struct Foo {
1397 Foo(int f);
1398 };""",
1399 'Single-parameter constructors should be marked explicit.'
1400 ' [runtime/explicit] [5]')
1401 # Templatized classes are caught as well.
1402 self.TestMultiLineLint(
1403 """
1404 template<typename T> class Foo {
1405 Foo(int f);
1406 };""",
1407 'Single-parameter constructors should be marked explicit.'
1408 ' [runtime/explicit] [5]')
1409 # inline case for templatized classes.
1410 self.TestMultiLineLint(
1411 """
1412 template<typename T> class Foo {
1413 inline Foo(int f);
1414 };""",
1415 'Single-parameter constructors should be marked explicit.'
1416 ' [runtime/explicit] [5]')
1417 # constructors with a default argument should still be marked explicit
1418 self.TestMultiLineLint(
1419 """
1420 class Foo {
1421 Foo(int f = 0);
1422 };""",
1423 'Constructors callable with one argument should be marked explicit.'
1424 ' [runtime/explicit] [5]')
1425 # multi-argument constructors with all but one default argument should be
1426 # marked explicit
1427 self.TestMultiLineLint(
1428 """
1429 class Foo {
1430 Foo(int f, int g = 0);
1431 };""",
1432 'Constructors callable with one argument should be marked explicit.'
1433 ' [runtime/explicit] [5]')
1434 # multi-argument constructors with all default arguments should be marked
1435 # explicit
1436 self.TestMultiLineLint(
1437 """
1438 class Foo {
1439 Foo(int f = 0, int g = 0);
1440 };""",
1441 'Constructors callable with one argument should be marked explicit.'
1442 ' [runtime/explicit] [5]')
1443 # explicit no-argument constructors are bad
1444 self.TestMultiLineLint(
1445 """
1446 class Foo {
1447 explicit Foo();
1448 };""",
1449 'Zero-parameter constructors should not be marked explicit.'
1450 ' [runtime/explicit] [5]')
1451 # void constructors are considered no-argument
1452 self.TestMultiLineLint(
1453 """
1454 class Foo {
1455 explicit Foo(void);
1456 };""",
1457 'Zero-parameter constructors should not be marked explicit.'
1458 ' [runtime/explicit] [5]')
Alex Vakulenko01e47232016-05-06 13:54:15 -07001459 # No warning for multi-parameter constructors
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001460 self.TestMultiLineLint(
1461 """
1462 class Foo {
1463 explicit Foo(int f, int g);
1464 };""",
Alex Vakulenko01e47232016-05-06 13:54:15 -07001465 '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001466 self.TestMultiLineLint(
1467 """
1468 class Foo {
1469 explicit Foo(int f, int g = 0);
1470 };""",
1471 '')
1472 # single-argument constructors that take a function that takes multiple
1473 # arguments should be explicit
1474 self.TestMultiLineLint(
1475 """
1476 class Foo {
1477 Foo(void (*f)(int f, int g));
1478 };""",
1479 'Single-parameter constructors should be marked explicit.'
1480 ' [runtime/explicit] [5]')
1481 # single-argument constructors that take a single template argument with
1482 # multiple parameters should be explicit
1483 self.TestMultiLineLint(
1484 """
1485 template <typename T, typename S>
1486 class Foo {
1487 Foo(Bar<T, S> b);
1488 };""",
1489 'Single-parameter constructors should be marked explicit.'
1490 ' [runtime/explicit] [5]')
1491 # but copy constructors that take multiple template parameters are OK
1492 self.TestMultiLineLint(
1493 """
1494 template <typename T, S>
1495 class Foo {
1496 Foo(Foo<T, S>& f);
1497 };""",
1498 '')
1499 # proper style is okay
1500 self.TestMultiLineLint(
1501 """
1502 class Foo {
1503 explicit Foo(int f);
1504 };""",
1505 '')
1506 # two argument constructor is okay
1507 self.TestMultiLineLint(
1508 """
1509 class Foo {
1510 Foo(int f, int b);
1511 };""",
1512 '')
1513 # two argument constructor, across two lines, is okay
1514 self.TestMultiLineLint(
1515 """
1516 class Foo {
1517 Foo(int f,
1518 int b);
1519 };""",
1520 '')
1521 # non-constructor (but similar name), is okay
1522 self.TestMultiLineLint(
1523 """
1524 class Foo {
1525 aFoo(int f);
1526 };""",
1527 '')
1528 # constructor with void argument is okay
1529 self.TestMultiLineLint(
1530 """
1531 class Foo {
1532 Foo(void);
1533 };""",
1534 '')
1535 # single argument method is okay
1536 self.TestMultiLineLint(
1537 """
1538 class Foo {
1539 Bar(int b);
1540 };""",
1541 '')
1542 # comments should be ignored
1543 self.TestMultiLineLint(
1544 """
1545 class Foo {
1546 // Foo(int f);
1547 };""",
1548 '')
1549 # single argument function following class definition is okay
1550 # (okay, it's not actually valid, but we don't want a false positive)
1551 self.TestMultiLineLint(
1552 """
1553 class Foo {
1554 Foo(int f, int b);
1555 };
1556 Foo(int f);""",
1557 '')
1558 # single argument function is okay
1559 self.TestMultiLineLint(
1560 """static Foo(int f);""",
1561 '')
1562 # single argument copy constructor is okay.
1563 self.TestMultiLineLint(
1564 """
1565 class Foo {
1566 Foo(const Foo&);
1567 };""",
1568 '')
1569 self.TestMultiLineLint(
1570 """
1571 class Foo {
1572 Foo(Foo const&);
1573 };""",
1574 '')
1575 self.TestMultiLineLint(
1576 """
1577 class Foo {
1578 Foo(Foo&);
1579 };""",
1580 '')
1581 # templatized copy constructor is okay.
1582 self.TestMultiLineLint(
1583 """
1584 template<typename T> class Foo {
1585 Foo(const Foo<T>&);
1586 };""",
1587 '')
1588 # Special case for std::initializer_list
1589 self.TestMultiLineLint(
1590 """
1591 class Foo {
1592 Foo(std::initializer_list<T> &arg) {}
1593 };""",
1594 '')
1595 # Anything goes inside an assembly block
1596 error_collector = ErrorCollector(self.assert_)
1597 cpplint.ProcessFileData('foo.cc', 'cc',
1598 ['void Func() {',
1599 ' __asm__ (',
1600 ' "hlt"',
1601 ' );',
1602 ' asm {',
1603 ' movdqa [edx + 32], xmm2',
1604 ' }',
1605 '}'],
1606 error_collector)
1607 self.assertEquals(
1608 0,
1609 error_collector.ResultList().count(
1610 'Extra space before ( in function call [whitespace/parens] [4]'))
1611 self.assertEquals(
1612 0,
1613 error_collector.ResultList().count(
1614 'Closing ) should be moved to the previous line '
1615 '[whitespace/parens] [2]'))
1616 self.assertEquals(
1617 0,
1618 error_collector.ResultList().count(
1619 'Extra space before [ [whitespace/braces] [5]'))
1620 finally:
1621 cpplint._cpplint_state.verbose_level = old_verbose_level
erg@google.com4e00b9a2009-01-12 23:05:11 +00001622
1623 def testSlashStarCommentOnSingleLine(self):
1624 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001625 """/* static */ Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001626 '')
1627 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001628 """/*/ static */ Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001629 '')
1630 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001631 """/*/ static Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001632 'Could not find end of multi-line comment'
1633 ' [readability/multiline_comment] [5]')
1634 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001635 """ /*/ static Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001636 'Could not find end of multi-line comment'
1637 ' [readability/multiline_comment] [5]')
1638 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001639 """ /**/ static Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001640 '')
1641
1642 # Test suspicious usage of "if" like this:
1643 # if (a == b) {
1644 # DoSomething();
1645 # } if (a == c) { // Should be "else if".
1646 # DoSomething(); // This gets called twice if a == b && a == c.
1647 # }
1648 def testSuspiciousUsageOfIf(self):
1649 self.TestLint(
1650 ' if (a == b) {',
1651 '')
1652 self.TestLint(
1653 ' } if (a == b) {',
1654 'Did you mean "else if"? If not, start a new line for "if".'
1655 ' [readability/braces] [4]')
1656
1657 # Test suspicious usage of memset. Specifically, a 0
1658 # as the final argument is almost certainly an error.
1659 def testSuspiciousUsageOfMemset(self):
1660 # Normal use is okay.
1661 self.TestLint(
1662 ' memset(buf, 0, sizeof(buf))',
1663 '')
1664
1665 # A 0 as the final argument is almost certainly an error.
1666 self.TestLint(
1667 ' memset(buf, sizeof(buf), 0)',
1668 'Did you mean "memset(buf, 0, sizeof(buf))"?'
1669 ' [runtime/memset] [4]')
1670 self.TestLint(
1671 ' memset(buf, xsize * ysize, 0)',
1672 'Did you mean "memset(buf, 0, xsize * ysize)"?'
1673 ' [runtime/memset] [4]')
1674
1675 # There is legitimate test code that uses this form.
1676 # This is okay since the second argument is a literal.
1677 self.TestLint(
1678 " memset(buf, 'y', 0)",
1679 '')
1680 self.TestLint(
1681 ' memset(buf, 4, 0)',
1682 '')
1683 self.TestLint(
1684 ' memset(buf, -1, 0)',
1685 '')
1686 self.TestLint(
1687 ' memset(buf, 0xF1, 0)',
1688 '')
1689 self.TestLint(
1690 ' memset(buf, 0xcd, 0)',
1691 '')
1692
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001693 def testRedundantVirtual(self):
1694 self.TestLint('virtual void F()', '')
1695 self.TestLint('virtual void F();', '')
1696 self.TestLint('virtual void F() {}', '')
1697
1698 message_template = ('"%s" is redundant since function is already '
1699 'declared as "%s" [readability/inheritance] [4]')
1700 for virt_specifier in ['override', 'final']:
1701 error_message = message_template % ('virtual', virt_specifier)
1702 self.TestLint('virtual int F() %s' % virt_specifier, error_message)
1703 self.TestLint('virtual int F() %s;' % virt_specifier, error_message)
1704 self.TestLint('virtual int F() %s {' % virt_specifier, error_message)
1705
1706 error_collector = ErrorCollector(self.assert_)
1707 cpplint.ProcessFileData(
1708 'foo.cc', 'cc',
1709 ['// Copyright 2014 Your Company.',
1710 'virtual void F(int a,',
1711 ' int b) ' + virt_specifier + ';',
1712 'virtual void F(int a,',
1713 ' int b) LOCKS_EXCLUDED(lock) ' + virt_specifier + ';',
1714 'virtual void F(int a,',
1715 ' int b)',
1716 ' LOCKS_EXCLUDED(lock) ' + virt_specifier + ';',
1717 ''],
1718 error_collector)
1719 self.assertEquals(
1720 [error_message, error_message, error_message],
1721 error_collector.Results())
1722
1723 error_message = message_template % ('override', 'final')
1724 self.TestLint('int F() override final', error_message)
1725 self.TestLint('int F() override final;', error_message)
1726 self.TestLint('int F() override final {}', error_message)
1727 self.TestLint('int F() final override', error_message)
1728 self.TestLint('int F() final override;', error_message)
1729 self.TestLint('int F() final override {}', error_message)
1730
avakulenko@google.com554223d2014-12-04 22:00:20 +00001731 error_collector = ErrorCollector(self.assert_)
1732 cpplint.ProcessFileData(
1733 'foo.cc', 'cc',
1734 ['// Copyright 2014 Your Company.',
1735 'struct A : virtual B {',
1736 ' ~A() override;'
1737 '};',
1738 'class C',
1739 ' : public D,',
1740 ' public virtual E {',
1741 ' void Func() override;',
1742 '}',
1743 ''],
1744 error_collector)
1745 self.assertEquals('', error_collector.Results())
1746
1747 self.TestLint('void Finalize(AnnotationProto *final) override;', '')
1748
erg@google.com4e00b9a2009-01-12 23:05:11 +00001749 def testCheckDeprecated(self):
erg@google.com4e00b9a2009-01-12 23:05:11 +00001750 self.TestLanguageRulesCheck('foo_test.cc', '#include <iostream>', '')
1751 self.TestLanguageRulesCheck('foo_unittest.cc', '#include <iostream>', '')
1752
1753 def testCheckPosixThreading(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00001754 self.TestLint('var = sctime_r()', '')
1755 self.TestLint('var = strtok_r()', '')
1756 self.TestLint('var = strtok_r(foo, ba, r)', '')
1757 self.TestLint('var = brand()', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001758 self.TestLint('_rand()', '')
1759 self.TestLint('.rand()', '')
erg@google.comd350fe52013-01-14 17:51:48 +00001760 self.TestLint('->rand()', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00001761 self.TestLint('ACMRandom rand(seed)', '')
1762 self.TestLint('ISAACRandom rand()', '')
1763 self.TestLint('var = rand()',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001764 'Consider using rand_r(...) instead of rand(...)'
1765 ' for improved thread safety.'
1766 ' [runtime/threadsafe_fn] [2]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00001767 self.TestLint('var = strtok(str, delim)',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001768 'Consider using strtok_r(...) '
1769 'instead of strtok(...)'
1770 ' for improved thread safety.'
1771 ' [runtime/threadsafe_fn] [2]')
1772
erg@google.com2aa59982013-10-28 19:09:25 +00001773 def testVlogMisuse(self):
1774 self.TestLint('VLOG(1)', '')
1775 self.TestLint('VLOG(99)', '')
1776 self.TestLint('LOG(ERROR)', '')
1777 self.TestLint('LOG(INFO)', '')
1778 self.TestLint('LOG(WARNING)', '')
1779 self.TestLint('LOG(FATAL)', '')
1780 self.TestLint('LOG(DFATAL)', '')
1781 self.TestLint('VLOG(SOMETHINGWEIRD)', '')
1782 self.TestLint('MYOWNVLOG(ERROR)', '')
1783 errmsg = ('VLOG() should be used with numeric verbosity level. '
1784 'Use LOG() if you want symbolic severity levels.'
1785 ' [runtime/vlog] [5]')
1786 self.TestLint('VLOG(ERROR)', errmsg)
1787 self.TestLint('VLOG(INFO)', errmsg)
1788 self.TestLint('VLOG(WARNING)', errmsg)
1789 self.TestLint('VLOG(FATAL)', errmsg)
1790 self.TestLint('VLOG(DFATAL)', errmsg)
1791 self.TestLint(' VLOG(ERROR)', errmsg)
1792 self.TestLint(' VLOG(INFO)', errmsg)
1793 self.TestLint(' VLOG(WARNING)', errmsg)
1794 self.TestLint(' VLOG(FATAL)', errmsg)
1795 self.TestLint(' VLOG(DFATAL)', errmsg)
1796
1797
erg@google.com4e00b9a2009-01-12 23:05:11 +00001798 # Test potential format string bugs like printf(foo).
1799 def testFormatStrings(self):
1800 self.TestLint('printf("foo")', '')
1801 self.TestLint('printf("foo: %s", foo)', '')
1802 self.TestLint('DocidForPrintf(docid)', '') # Should not trigger.
erg@google.com8a95ecc2011-09-08 00:45:54 +00001803 self.TestLint('printf(format, value)', '') # Should not trigger.
erg@google.comd350fe52013-01-14 17:51:48 +00001804 self.TestLint('printf(__VA_ARGS__)', '') # Should not trigger.
erg@google.com8a95ecc2011-09-08 00:45:54 +00001805 self.TestLint('printf(format.c_str(), value)', '') # Should not trigger.
1806 self.TestLint('printf(format(index).c_str(), value)', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001807 self.TestLint(
1808 'printf(foo)',
1809 'Potential format string bug. Do printf("%s", foo) instead.'
1810 ' [runtime/printf] [4]')
1811 self.TestLint(
1812 'printf(foo.c_str())',
1813 'Potential format string bug. '
1814 'Do printf("%s", foo.c_str()) instead.'
1815 ' [runtime/printf] [4]')
1816 self.TestLint(
1817 'printf(foo->c_str())',
1818 'Potential format string bug. '
1819 'Do printf("%s", foo->c_str()) instead.'
1820 ' [runtime/printf] [4]')
1821 self.TestLint(
1822 'StringPrintf(foo)',
1823 'Potential format string bug. Do StringPrintf("%s", foo) instead.'
1824 ''
1825 ' [runtime/printf] [4]')
1826
erg@google.coma868d2d2009-10-09 21:18:45 +00001827 # Test disallowed use of operator& and other operators.
1828 def testIllegalOperatorOverloading(self):
1829 errmsg = ('Unary operator& is dangerous. Do not use it.'
1830 ' [runtime/operator] [4]')
1831 self.TestLint('void operator=(const Myclass&)', '')
1832 self.TestLint('void operator&(int a, int b)', '') # binary operator& ok
1833 self.TestLint('void operator&() { }', errmsg)
1834 self.TestLint('void operator & ( ) { }',
avakulenko@google.com02af6282014-06-04 18:53:25 +00001835 ['Extra space after ( [whitespace/parens] [2]', errmsg])
erg@google.coma868d2d2009-10-09 21:18:45 +00001836
1837 # const string reference members are dangerous..
1838 def testConstStringReferenceMembers(self):
1839 errmsg = ('const string& members are dangerous. It is much better to use '
1840 'alternatives, such as pointers or simple constants.'
1841 ' [runtime/member_string_references] [2]')
1842
1843 members_declarations = ['const string& church',
1844 'const string &turing',
1845 'const string & godel']
1846 # TODO(unknown): Enable also these tests if and when we ever
1847 # decide to check for arbitrary member references.
1848 # "const Turing & a",
1849 # "const Church& a",
1850 # "const vector<int>& a",
1851 # "const Kurt::Godel & godel",
1852 # "const Kazimierz::Kuratowski& kk" ]
1853
1854 # The Good.
1855
1856 self.TestLint('void f(const string&)', '')
1857 self.TestLint('const string& f(const string& a, const string& b)', '')
1858 self.TestLint('typedef const string& A;', '')
1859
1860 for decl in members_declarations:
1861 self.TestLint(decl + ' = b;', '')
1862 self.TestLint(decl + ' =', '')
1863
1864 # The Bad.
1865
1866 for decl in members_declarations:
1867 self.TestLint(decl + ';', errmsg)
1868
erg@google.com4e00b9a2009-01-12 23:05:11 +00001869 # Variable-length arrays are not permitted.
1870 def testVariableLengthArrayDetection(self):
1871 errmsg = ('Do not use variable-length arrays. Use an appropriately named '
1872 "('k' followed by CamelCase) compile-time constant for the size."
1873 ' [runtime/arrays] [1]')
1874
1875 self.TestLint('int a[any_old_variable];', errmsg)
1876 self.TestLint('int doublesize[some_var * 2];', errmsg)
1877 self.TestLint('int a[afunction()];', errmsg)
1878 self.TestLint('int a[function(kMaxFooBars)];', errmsg)
1879 self.TestLint('bool a_list[items_->size()];', errmsg)
1880 self.TestLint('namespace::Type buffer[len+1];', errmsg)
1881
1882 self.TestLint('int a[64];', '')
1883 self.TestLint('int a[0xFF];', '')
1884 self.TestLint('int first[256], second[256];', '')
1885 self.TestLint('int array_name[kCompileTimeConstant];', '')
1886 self.TestLint('char buf[somenamespace::kBufSize];', '')
1887 self.TestLint('int array_name[ALL_CAPS];', '')
1888 self.TestLint('AClass array1[foo::bar::ALL_CAPS];', '')
1889 self.TestLint('int a[kMaxStrLen + 1];', '')
1890 self.TestLint('int a[sizeof(foo)];', '')
1891 self.TestLint('int a[sizeof(*foo)];', '')
1892 self.TestLint('int a[sizeof foo];', '')
1893 self.TestLint('int a[sizeof(struct Foo)];', '')
1894 self.TestLint('int a[128 - sizeof(const bar)];', '')
1895 self.TestLint('int a[(sizeof(foo) * 4)];', '')
1896 self.TestLint('int a[(arraysize(fixed_size_array)/2) << 1];', '')
1897 self.TestLint('delete a[some_var];', '')
1898 self.TestLint('return a[some_var];', '')
1899
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001900 # DISALLOW_COPY_AND_ASSIGN and DISALLOW_IMPLICIT_CONSTRUCTORS should be at
1901 # end of class if present.
1902 def testDisallowMacrosAtEnd(self):
erg@google.com4e00b9a2009-01-12 23:05:11 +00001903 for macro_name in (
erg@google.com4e00b9a2009-01-12 23:05:11 +00001904 'DISALLOW_COPY_AND_ASSIGN',
1905 'DISALLOW_IMPLICIT_CONSTRUCTORS'):
avakulenko@google.com554223d2014-12-04 22:00:20 +00001906 error_collector = ErrorCollector(self.assert_)
1907 cpplint.ProcessFileData(
1908 'foo.cc', 'cc',
1909 ['// Copyright 2014 Your Company.',
1910 'class SomeClass {',
1911 ' private:',
1912 ' %s(SomeClass);' % macro_name,
1913 ' int member_;',
1914 '};',
1915 ''],
1916 error_collector)
1917 self.assertEquals(
erg@google.com4e00b9a2009-01-12 23:05:11 +00001918 ('%s should be the last thing in the class' % macro_name) +
avakulenko@google.com554223d2014-12-04 22:00:20 +00001919 ' [readability/constructors] [3]',
1920 error_collector.Results())
1921
1922 error_collector = ErrorCollector(self.assert_)
1923 cpplint.ProcessFileData(
1924 'foo.cc', 'cc',
1925 ['// Copyright 2014 Your Company.',
1926 'class OuterClass {',
1927 ' private:',
1928 ' struct InnerClass {',
1929 ' private:',
1930 ' %s(InnerClass);' % macro_name,
1931 ' int member;',
1932 ' };',
1933 '};',
1934 ''],
1935 error_collector)
1936 self.assertEquals(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001937 ('%s should be the last thing in the class' % macro_name) +
avakulenko@google.com554223d2014-12-04 22:00:20 +00001938 ' [readability/constructors] [3]',
1939 error_collector.Results())
1940
1941 error_collector = ErrorCollector(self.assert_)
1942 cpplint.ProcessFileData(
1943 'foo.cc', 'cc',
1944 ['// Copyright 2014 Your Company.',
1945 'class OuterClass1 {',
1946 ' private:',
1947 ' struct InnerClass1 {',
1948 ' private:',
1949 ' %s(InnerClass1);' % macro_name,
1950 ' };',
1951 ' %s(OuterClass1);' % macro_name,
1952 '};',
1953 'struct OuterClass2 {',
1954 ' private:',
1955 ' class InnerClass2 {',
1956 ' private:',
1957 ' %s(InnerClass2);' % macro_name,
1958 ' // comment',
1959 ' };',
1960 '',
1961 ' %s(OuterClass2);' % macro_name,
1962 '',
1963 ' // comment',
1964 '};',
1965 'void Func() {',
1966 ' struct LocalClass {',
1967 ' private:',
1968 ' %s(LocalClass);' % macro_name,
1969 ' } variable;',
1970 '}',
1971 ''],
1972 error_collector)
1973 self.assertEquals('', error_collector.Results())
erg@google.com4e00b9a2009-01-12 23:05:11 +00001974
erg@google.comd350fe52013-01-14 17:51:48 +00001975 # DISALLOW* macros should be in the private: section.
1976 def testMisplacedDisallowMacros(self):
1977 for macro_name in (
erg@google.comd350fe52013-01-14 17:51:48 +00001978 'DISALLOW_COPY_AND_ASSIGN',
1979 'DISALLOW_IMPLICIT_CONSTRUCTORS'):
1980 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001981 """
1982 class A {'
erg@google.comd350fe52013-01-14 17:51:48 +00001983 public:
1984 %s(A);
1985 };""" % macro_name,
1986 ('%s must be in the private: section' % macro_name) +
1987 ' [readability/constructors] [3]')
1988
1989 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001990 """
1991 struct B {'
erg@google.comd350fe52013-01-14 17:51:48 +00001992 %s(B);
1993 };""" % macro_name,
1994 ('%s must be in the private: section' % macro_name) +
1995 ' [readability/constructors] [3]')
1996
1997 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001998 """
1999 class Outer1 {'
erg@google.comd350fe52013-01-14 17:51:48 +00002000 private:
2001 struct Inner1 {
2002 %s(Inner1);
2003 };
2004 %s(Outer1);
2005 };""" % (macro_name, macro_name),
2006 ('%s must be in the private: section' % macro_name) +
2007 ' [readability/constructors] [3]')
2008
2009 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00002010 """
2011 class Outer2 {'
erg@google.comd350fe52013-01-14 17:51:48 +00002012 private:
2013 class Inner2 {
2014 %s(Inner2);
2015 };
2016 %s(Outer2);
2017 };""" % (macro_name, macro_name),
2018 '')
2019 # Extra checks to make sure that nested classes are handled
2020 # correctly. Use different macros for inner and outer classes so
2021 # that we can tell the error messages apart.
2022 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00002023 """
2024 class Outer3 {
erg@google.comd350fe52013-01-14 17:51:48 +00002025 struct Inner3 {
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002026 DISALLOW_COPY_AND_ASSIGN(Inner3);
erg@google.comd350fe52013-01-14 17:51:48 +00002027 };
2028 DISALLOW_IMPLICIT_CONSTRUCTORS(Outer3);
2029 };""",
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002030 ('DISALLOW_COPY_AND_ASSIGN must be in the private: section'
erg@google.comd350fe52013-01-14 17:51:48 +00002031 ' [readability/constructors] [3]'))
2032 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00002033 """
2034 struct Outer4 {
erg@google.comd350fe52013-01-14 17:51:48 +00002035 class Inner4 {
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002036 DISALLOW_COPY_AND_ASSIGN(Inner4);
erg@google.comd350fe52013-01-14 17:51:48 +00002037 };
2038 DISALLOW_IMPLICIT_CONSTRUCTORS(Outer4);
2039 };""",
2040 ('DISALLOW_IMPLICIT_CONSTRUCTORS must be in the private: section'
2041 ' [readability/constructors] [3]'))
2042
erg@google.com4e00b9a2009-01-12 23:05:11 +00002043 # Brace usage
2044 def testBraces(self):
2045 # Braces shouldn't be followed by a ; unless they're defining a struct
2046 # or initializing an array
2047 self.TestLint('int a[3] = { 1, 2, 3 };', '')
2048 self.TestLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00002049 """const int foo[] =
2050 {1, 2, 3 };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00002051 '')
2052 # For single line, unmatched '}' with a ';' is ignored (not enough context)
2053 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00002054 """int a[3] = { 1,
erg@google.com4e00b9a2009-01-12 23:05:11 +00002055 2,
erg@google.com8a95ecc2011-09-08 00:45:54 +00002056 3 };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00002057 '')
2058 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00002059 """int a[2][3] = { { 1, 2 },
2060 { 3, 4 } };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00002061 '')
2062 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00002063 """int a[2][3] =
erg@google.com4e00b9a2009-01-12 23:05:11 +00002064 { { 1, 2 },
erg@google.com8a95ecc2011-09-08 00:45:54 +00002065 { 3, 4 } };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00002066 '')
2067
2068 # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements
2069 def testCheckCheck(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002070 self.TestLint('CHECK(x == 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002071 'Consider using CHECK_EQ instead of CHECK(a == b)'
2072 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002073 self.TestLint('CHECK(x != 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002074 'Consider using CHECK_NE instead of CHECK(a != b)'
2075 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002076 self.TestLint('CHECK(x >= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002077 'Consider using CHECK_GE instead of CHECK(a >= b)'
2078 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002079 self.TestLint('CHECK(x > 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002080 'Consider using CHECK_GT instead of CHECK(a > b)'
2081 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002082 self.TestLint('CHECK(x <= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002083 'Consider using CHECK_LE instead of CHECK(a <= b)'
2084 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002085 self.TestLint('CHECK(x < 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002086 'Consider using CHECK_LT instead of CHECK(a < b)'
2087 ' [readability/check] [2]')
2088
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002089 self.TestLint('DCHECK(x == 42);',
erg@google.come35f7652009-06-19 20:52:09 +00002090 'Consider using DCHECK_EQ instead of DCHECK(a == b)'
2091 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002092 self.TestLint('DCHECK(x != 42);',
erg@google.come35f7652009-06-19 20:52:09 +00002093 'Consider using DCHECK_NE instead of DCHECK(a != b)'
2094 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002095 self.TestLint('DCHECK(x >= 42);',
erg@google.come35f7652009-06-19 20:52:09 +00002096 'Consider using DCHECK_GE instead of DCHECK(a >= b)'
2097 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002098 self.TestLint('DCHECK(x > 42);',
erg@google.come35f7652009-06-19 20:52:09 +00002099 'Consider using DCHECK_GT instead of DCHECK(a > b)'
2100 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002101 self.TestLint('DCHECK(x <= 42);',
erg@google.come35f7652009-06-19 20:52:09 +00002102 'Consider using DCHECK_LE instead of DCHECK(a <= b)'
2103 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002104 self.TestLint('DCHECK(x < 42);',
erg@google.come35f7652009-06-19 20:52:09 +00002105 'Consider using DCHECK_LT instead of DCHECK(a < b)'
2106 ' [readability/check] [2]')
2107
erg@google.com4e00b9a2009-01-12 23:05:11 +00002108 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002109 'EXPECT_TRUE("42" == x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002110 'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)'
2111 ' [readability/check] [2]')
2112 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002113 'EXPECT_TRUE("42" != x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002114 'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)'
2115 ' [readability/check] [2]')
2116 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002117 'EXPECT_TRUE(+42 >= x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002118 'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)'
2119 ' [readability/check] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002120
2121 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002122 'EXPECT_FALSE(x == 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002123 'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)'
2124 ' [readability/check] [2]')
2125 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002126 'EXPECT_FALSE(x != 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002127 'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)'
2128 ' [readability/check] [2]')
2129 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002130 'EXPECT_FALSE(x >= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002131 'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)'
2132 ' [readability/check] [2]')
2133 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002134 'ASSERT_FALSE(x > 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002135 'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)'
2136 ' [readability/check] [2]')
2137 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002138 'ASSERT_FALSE(x <= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002139 'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)'
2140 ' [readability/check] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002141
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002142 self.TestLint('CHECK(x<42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002143 ['Missing spaces around <'
2144 ' [whitespace/operators] [3]',
2145 'Consider using CHECK_LT instead of CHECK(a < b)'
2146 ' [readability/check] [2]'])
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002147 self.TestLint('CHECK(x>42);',
erg@google.comd350fe52013-01-14 17:51:48 +00002148 ['Missing spaces around >'
2149 ' [whitespace/operators] [3]',
2150 'Consider using CHECK_GT instead of CHECK(a > b)'
2151 ' [readability/check] [2]'])
erg@google.com4e00b9a2009-01-12 23:05:11 +00002152
erg@google.com0075d142013-11-05 22:28:07 +00002153 self.TestLint('using some::namespace::operator<<;', '')
2154 self.TestLint('using some::namespace::operator>>;', '')
erg@google.comc6671232013-10-25 21:44:03 +00002155
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002156 self.TestLint('CHECK(x->y == 42);',
erg@google.comc6671232013-10-25 21:44:03 +00002157 'Consider using CHECK_EQ instead of CHECK(a == b)'
2158 ' [readability/check] [2]')
2159
erg@google.com4e00b9a2009-01-12 23:05:11 +00002160 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002161 ' EXPECT_TRUE(42 < x); // Random comment.',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002162 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
2163 ' [readability/check] [2]')
2164 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002165 'EXPECT_TRUE( 42 < x );',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002166 ['Extra space after ( in function call'
2167 ' [whitespace/parens] [4]',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002168 'Extra space before ) [whitespace/parens] [2]',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002169 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
2170 ' [readability/check] [2]'])
erg@google.com4e00b9a2009-01-12 23:05:11 +00002171
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002172 self.TestLint('CHECK(4\'2 == x);',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002173 'Consider using CHECK_EQ instead of CHECK(a == b)'
2174 ' [readability/check] [2]')
2175
2176 def testCheckCheckFalsePositives(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002177 self.TestLint('CHECK(some_iterator == obj.end());', '')
2178 self.TestLint('EXPECT_TRUE(some_iterator == obj.end());', '')
2179 self.TestLint('EXPECT_FALSE(some_iterator == obj.end());', '')
2180 self.TestLint('CHECK(some_pointer != NULL);', '')
2181 self.TestLint('EXPECT_TRUE(some_pointer != NULL);', '')
2182 self.TestLint('EXPECT_FALSE(some_pointer != NULL);', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002183
2184 self.TestLint('CHECK(CreateTestFile(dir, (1 << 20)));', '')
2185 self.TestLint('CHECK(CreateTestFile(dir, (1 >> 20)));', '')
2186
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002187 self.TestLint('CHECK(x ^ (y < 42));', '')
2188 self.TestLint('CHECK((x > 42) ^ (x < 54));', '')
2189 self.TestLint('CHECK(a && b < 42);', '')
2190 self.TestLint('CHECK(42 < a && a < b);', '')
2191 self.TestLint('SOFT_CHECK(x > 42);', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002192
2193 self.TestMultiLineLint(
2194 """_STLP_DEFINE_BINARY_OP_CHECK(==, _OP_EQUAL);
2195 _STLP_DEFINE_BINARY_OP_CHECK(!=, _OP_NOT_EQUAL);
2196 _STLP_DEFINE_BINARY_OP_CHECK(<, _OP_LESS_THAN);
2197 _STLP_DEFINE_BINARY_OP_CHECK(<=, _OP_LESS_EQUAL);
2198 _STLP_DEFINE_BINARY_OP_CHECK(>, _OP_GREATER_THAN);
2199 _STLP_DEFINE_BINARY_OP_CHECK(>=, _OP_GREATER_EQUAL);
2200 _STLP_DEFINE_BINARY_OP_CHECK(+, _OP_PLUS);
2201 _STLP_DEFINE_BINARY_OP_CHECK(*, _OP_TIMES);
2202 _STLP_DEFINE_BINARY_OP_CHECK(/, _OP_DIVIDE);
2203 _STLP_DEFINE_BINARY_OP_CHECK(-, _OP_SUBTRACT);
2204 _STLP_DEFINE_BINARY_OP_CHECK(%, _OP_MOD);""",
2205 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002206
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002207 self.TestLint('CHECK(x < 42) << "Custom error message";', '')
2208
erg@google.comd350fe52013-01-14 17:51:48 +00002209 # Alternative token to punctuation operator replacements
2210 def testCheckAltTokens(self):
2211 self.TestLint('true or true',
2212 'Use operator || instead of or'
2213 ' [readability/alt_tokens] [2]')
2214 self.TestLint('true and true',
2215 'Use operator && instead of and'
2216 ' [readability/alt_tokens] [2]')
2217 self.TestLint('if (not true)',
2218 'Use operator ! instead of not'
2219 ' [readability/alt_tokens] [2]')
2220 self.TestLint('1 bitor 1',
2221 'Use operator | instead of bitor'
2222 ' [readability/alt_tokens] [2]')
2223 self.TestLint('1 xor 1',
2224 'Use operator ^ instead of xor'
2225 ' [readability/alt_tokens] [2]')
2226 self.TestLint('1 bitand 1',
2227 'Use operator & instead of bitand'
2228 ' [readability/alt_tokens] [2]')
2229 self.TestLint('x = compl 1',
2230 'Use operator ~ instead of compl'
2231 ' [readability/alt_tokens] [2]')
2232 self.TestLint('x and_eq y',
2233 'Use operator &= instead of and_eq'
2234 ' [readability/alt_tokens] [2]')
2235 self.TestLint('x or_eq y',
2236 'Use operator |= instead of or_eq'
2237 ' [readability/alt_tokens] [2]')
2238 self.TestLint('x xor_eq y',
2239 'Use operator ^= instead of xor_eq'
2240 ' [readability/alt_tokens] [2]')
2241 self.TestLint('x not_eq y',
2242 'Use operator != instead of not_eq'
2243 ' [readability/alt_tokens] [2]')
2244 self.TestLint('line_continuation or',
2245 'Use operator || instead of or'
2246 ' [readability/alt_tokens] [2]')
2247 self.TestLint('if(true and(parentheses',
2248 'Use operator && instead of and'
2249 ' [readability/alt_tokens] [2]')
2250
2251 self.TestLint('#include "base/false-and-false.h"', '')
2252 self.TestLint('#error false or false', '')
2253 self.TestLint('false nor false', '')
2254 self.TestLint('false nand false', '')
2255
erg@google.com4e00b9a2009-01-12 23:05:11 +00002256 # Passing and returning non-const references
2257 def testNonConstReference(self):
2258 # Passing a non-const reference as function parameter is forbidden.
2259 operand_error_message = ('Is this a non-const reference? '
erg@google.comfd5da632013-10-25 17:39:45 +00002260 'If so, make const or use a pointer: %s'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002261 ' [runtime/references] [2]')
2262 # Warn of use of a non-const reference in operators and functions
erg@google.comfd5da632013-10-25 17:39:45 +00002263 self.TestLint('bool operator>(Foo& s, Foo& f);',
2264 [operand_error_message % 'Foo& s',
2265 operand_error_message % 'Foo& f'])
2266 self.TestLint('bool operator+(Foo& s, Foo& f);',
2267 [operand_error_message % 'Foo& s',
2268 operand_error_message % 'Foo& f'])
2269 self.TestLint('int len(Foo& s);', operand_error_message % 'Foo& s')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002270 # Allow use of non-const references in a few specific cases
2271 self.TestLint('stream& operator>>(stream& s, Foo& f);', '')
2272 self.TestLint('stream& operator<<(stream& s, Foo& f);', '')
2273 self.TestLint('void swap(Bar& a, Bar& b);', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002274 self.TestLint('ostream& LogFunc(ostream& s);', '')
2275 self.TestLint('ostringstream& LogFunc(ostringstream& s);', '')
2276 self.TestLint('istream& LogFunc(istream& s);', '')
2277 self.TestLint('istringstream& LogFunc(istringstream& s);', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002278 # Returning a non-const reference from a function is OK.
2279 self.TestLint('int& g();', '')
2280 # Passing a const reference to a struct (using the struct keyword) is OK.
2281 self.TestLint('void foo(const struct tm& tm);', '')
2282 # Passing a const reference to a typename is OK.
2283 self.TestLint('void foo(const typename tm& tm);', '')
erg@google.comfd5da632013-10-25 17:39:45 +00002284 # Const reference to a pointer type is OK.
2285 self.TestLint('void foo(const Bar* const& p) {', '')
2286 self.TestLint('void foo(Bar const* const& p) {', '')
2287 self.TestLint('void foo(Bar* const& p) {', '')
2288 # Const reference to a templated type is OK.
2289 self.TestLint('void foo(const std::vector<std::string>& v);', '')
2290 # Non-const reference to a pointer type is not OK.
2291 self.TestLint('void foo(Bar*& p);',
2292 operand_error_message % 'Bar*& p')
2293 self.TestLint('void foo(const Bar*& p);',
2294 operand_error_message % 'const Bar*& p')
2295 self.TestLint('void foo(Bar const*& p);',
2296 operand_error_message % 'Bar const*& p')
2297 self.TestLint('void foo(struct Bar*& p);',
2298 operand_error_message % 'struct Bar*& p')
2299 self.TestLint('void foo(const struct Bar*& p);',
2300 operand_error_message % 'const struct Bar*& p')
2301 self.TestLint('void foo(struct Bar const*& p);',
2302 operand_error_message % 'struct Bar const*& p')
2303 # Non-const reference to a templated type is not OK.
2304 self.TestLint('void foo(std::vector<int>& p);',
2305 operand_error_message % 'std::vector<int>& p')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002306 # Returning an address of something is not prohibited.
2307 self.TestLint('return &something;', '')
erg@google.comd7d27472011-09-07 17:36:35 +00002308 self.TestLint('if (condition) {return &something; }', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002309 self.TestLint('if (condition) return &something;', '')
2310 self.TestLint('if (condition) address = &something;', '')
2311 self.TestLint('if (condition) result = lhs&rhs;', '')
2312 self.TestLint('if (condition) result = lhs & rhs;', '')
2313 self.TestLint('a = (b+c) * sizeof &f;', '')
2314 self.TestLint('a = MySize(b) * sizeof &f;', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002315 # We don't get confused by C++11 range-based for loops.
2316 self.TestLint('for (const string& s : c)', '')
2317 self.TestLint('for (auto& r : c)', '')
2318 self.TestLint('for (typename Type& a : b)', '')
erg@google.comfd5da632013-10-25 17:39:45 +00002319 # We don't get confused by some other uses of '&'.
2320 self.TestLint('T& operator=(const T& t);', '')
2321 self.TestLint('int g() { return (a & b); }', '')
2322 self.TestLint('T& r = (T&)*(vp());', '')
2323 self.TestLint('T& r = v', '')
2324 self.TestLint('static_assert((kBits & kMask) == 0, "text");', '')
2325 self.TestLint('COMPILE_ASSERT((kBits & kMask) == 0, text);', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002326 # Spaces before template arguments. This is poor style, but
2327 # happens 0.15% of the time.
2328 self.TestLint('void Func(const vector <int> &const_x, '
2329 'vector <int> &nonconst_x) {',
2330 operand_error_message % 'vector<int> &nonconst_x')
erg@google.comfd5da632013-10-25 17:39:45 +00002331
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002332 # Derived member functions are spared from override check
2333 self.TestLint('void Func(X& x);', operand_error_message % 'X& x')
2334 self.TestLint('void Func(X& x) {}', operand_error_message % 'X& x')
2335 self.TestLint('void Func(X& x) override;', '')
2336 self.TestLint('void Func(X& x) override {', '')
2337 self.TestLint('void Func(X& x) const override;', '')
2338 self.TestLint('void Func(X& x) const override {', '')
2339
avakulenko@google.com554223d2014-12-04 22:00:20 +00002340 # Don't warn on out-of-line method definitions.
2341 self.TestLint('void NS::Func(X& x) {', '')
2342 error_collector = ErrorCollector(self.assert_)
2343 cpplint.ProcessFileData(
2344 'foo.cc', 'cc',
2345 ['// Copyright 2014 Your Company. All Rights Reserved.',
2346 'void a::b() {}',
2347 'void f(int& q) {}',
2348 ''],
2349 error_collector)
2350 self.assertEquals(
2351 operand_error_message % 'int& q',
2352 error_collector.Results())
2353
avakulenko@google.com02af6282014-06-04 18:53:25 +00002354 # Other potential false positives. These need full parser
erg@google.comfd5da632013-10-25 17:39:45 +00002355 # state to reproduce as opposed to just TestLint.
2356 error_collector = ErrorCollector(self.assert_)
2357 cpplint.ProcessFileData(
2358 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002359 ['// Copyright 2014 Your Company. All Rights Reserved.',
erg@google.comfd5da632013-10-25 17:39:45 +00002360 'void swap(int &x,',
2361 ' int &y) {',
2362 '}',
2363 'void swap(',
2364 ' sparsegroup<T, GROUP_SIZE, Alloc> &x,',
2365 ' sparsegroup<T, GROUP_SIZE, Alloc> &y) {',
2366 '}',
2367 'ostream& operator<<(',
2368 ' ostream& out',
2369 ' const dense_hash_set<Value, Hash, Equals, Alloc>& seq) {',
2370 '}',
avakulenko@google.com554223d2014-12-04 22:00:20 +00002371 'class A {',
2372 ' void Function(',
2373 ' string &x) override {',
2374 ' }',
2375 '};',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002376 'void Derived::Function(',
avakulenko@google.com554223d2014-12-04 22:00:20 +00002377 ' string &x) {',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002378 '}',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002379 '#define UNSUPPORTED_MASK(_mask) \\',
2380 ' if (flags & _mask) { \\',
2381 ' LOG(FATAL) << "Unsupported flag: " << #_mask; \\',
2382 ' }',
2383 'Constructor::Constructor()',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002384 ' : initializer1_(a1 & b1),',
2385 ' initializer2_(a2 & b2) {',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002386 '}',
2387 'Constructor::Constructor()',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002388 ' : initializer1_{a3 & b3},',
2389 ' initializer2_(a4 & b4) {',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002390 '}',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002391 'Constructor::Constructor()',
2392 ' : initializer1_{a5 & b5},',
2393 ' initializer2_(a6 & b6) {}',
erg@google.comfd5da632013-10-25 17:39:45 +00002394 ''],
2395 error_collector)
2396 self.assertEquals('', error_collector.Results())
erg@google.com4e00b9a2009-01-12 23:05:11 +00002397
erg@google.comc6671232013-10-25 21:44:03 +00002398 # Multi-line references
avakulenko@google.com02af6282014-06-04 18:53:25 +00002399 error_collector = ErrorCollector(self.assert_)
erg@google.comc6671232013-10-25 21:44:03 +00002400 cpplint.ProcessFileData(
2401 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002402 ['// Copyright 2014 Your Company. All Rights Reserved.',
erg@google.comc6671232013-10-25 21:44:03 +00002403 'void Func(const Outer::',
2404 ' Inner& const_x,',
2405 ' const Outer',
2406 ' ::Inner& const_y,',
erg@google.com2aa59982013-10-28 19:09:25 +00002407 ' const Outer<',
2408 ' int>::Inner& const_z,',
erg@google.comc6671232013-10-25 21:44:03 +00002409 ' Outer::',
2410 ' Inner& nonconst_x,',
2411 ' Outer',
erg@google.com2aa59982013-10-28 19:09:25 +00002412 ' ::Inner& nonconst_y,',
2413 ' Outer<',
2414 ' int>::Inner& nonconst_z) {',
erg@google.comc6671232013-10-25 21:44:03 +00002415 '}',
2416 ''],
2417 error_collector)
2418 self.assertEquals(
2419 [operand_error_message % 'Outer::Inner& nonconst_x',
erg@google.com2aa59982013-10-28 19:09:25 +00002420 operand_error_message % 'Outer::Inner& nonconst_y',
2421 operand_error_message % 'Outer<int>::Inner& nonconst_z'],
erg@google.comc6671232013-10-25 21:44:03 +00002422 error_collector.Results())
2423
avakulenko@google.com02af6282014-06-04 18:53:25 +00002424 # A peculiar false positive due to bad template argument parsing
2425 error_collector = ErrorCollector(self.assert_)
2426 cpplint.ProcessFileData(
2427 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002428 ['// Copyright 2014 Your Company. All Rights Reserved.',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002429 'inline RCULocked<X>::ReadPtr::ReadPtr(const RCULocked* rcu) {',
2430 ' DCHECK(!(data & kFlagMask)) << "Error";',
2431 '}',
2432 '',
2433 'RCULocked<X>::WritePtr::WritePtr(RCULocked* rcu)',
2434 ' : lock_(&rcu_->mutex_) {',
2435 '}',
2436 ''],
2437 error_collector.Results())
2438 self.assertEquals('', error_collector.Results())
2439
erg@google.com4e00b9a2009-01-12 23:05:11 +00002440 def testBraceAtBeginOfLine(self):
2441 self.TestLint('{',
2442 '{ should almost always be at the end of the previous line'
2443 ' [whitespace/braces] [4]')
2444
erg@google.comd350fe52013-01-14 17:51:48 +00002445 error_collector = ErrorCollector(self.assert_)
2446 cpplint.ProcessFileData('foo.cc', 'cc',
2447 ['int function()',
2448 '{', # warning here
2449 ' MutexLock l(&mu);',
2450 '}',
2451 'int variable;'
2452 '{', # no warning
2453 ' MutexLock l(&mu);',
2454 '}',
erg@google.comc6671232013-10-25 21:44:03 +00002455 'MyType m = {',
2456 ' {value1, value2},',
2457 ' {', # no warning
2458 ' loooong_value1, looooong_value2',
2459 ' }',
2460 '};',
erg@google.comd350fe52013-01-14 17:51:48 +00002461 '#if PREPROCESSOR',
2462 '{', # no warning
2463 ' MutexLock l(&mu);',
2464 '}',
2465 '#endif'],
2466 error_collector)
2467 self.assertEquals(1, error_collector.Results().count(
2468 '{ should almost always be at the end of the previous line'
2469 ' [whitespace/braces] [4]'))
2470
erg@google.com2aa59982013-10-28 19:09:25 +00002471 self.TestMultiLineLint(
2472 """
2473 foo(
2474 {
2475 loooooooooooooooong_value,
2476 });""",
2477 '')
2478
erg@google.com4e00b9a2009-01-12 23:05:11 +00002479 def testMismatchingSpacesInParens(self):
2480 self.TestLint('if (foo ) {', 'Mismatching spaces inside () in if'
2481 ' [whitespace/parens] [5]')
2482 self.TestLint('switch ( foo) {', 'Mismatching spaces inside () in switch'
2483 ' [whitespace/parens] [5]')
erg@google.come35f7652009-06-19 20:52:09 +00002484 self.TestLint('for (foo; ba; bar ) {', 'Mismatching spaces inside () in for'
2485 ' [whitespace/parens] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002486 self.TestLint('for (; foo; bar) {', '')
2487 self.TestLint('for ( ; foo; bar) {', '')
2488 self.TestLint('for ( ; foo; bar ) {', '')
erg@google.come35f7652009-06-19 20:52:09 +00002489 self.TestLint('for (foo; bar; ) {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002490 self.TestLint('while ( foo ) {', 'Should have zero or one spaces inside'
2491 ' ( and ) in while [whitespace/parens] [5]')
2492
2493 def testSpacingForFncall(self):
2494 self.TestLint('if (foo) {', '')
erg@google.comd7d27472011-09-07 17:36:35 +00002495 self.TestLint('for (foo; bar; baz) {', '')
2496 self.TestLint('for (;;) {', '')
erg@google.comc6671232013-10-25 21:44:03 +00002497 # Space should be allowed in placement new operators.
2498 self.TestLint('Something* p = new (place) Something();', '')
erg@google.comd7d27472011-09-07 17:36:35 +00002499 # Test that there is no warning when increment statement is empty.
2500 self.TestLint('for (foo; baz;) {', '')
2501 self.TestLint('for (foo;bar;baz) {', 'Missing space after ;'
2502 ' [whitespace/semicolon] [3]')
2503 # we don't warn about this semicolon, at least for now
2504 self.TestLint('if (condition) {return &something; }',
2505 '')
2506 # seen in some macros
2507 self.TestLint('DoSth();\\', '')
2508 # Test that there is no warning about semicolon here.
2509 self.TestLint('abc;// this is abc',
2510 'At least two spaces is best between code'
2511 ' and comments [whitespace/comments] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002512 self.TestLint('while (foo) {', '')
2513 self.TestLint('switch (foo) {', '')
2514 self.TestLint('foo( bar)', 'Extra space after ( in function call'
2515 ' [whitespace/parens] [4]')
erg@google.comd7d27472011-09-07 17:36:35 +00002516 self.TestLint('foo( // comment', '')
2517 self.TestLint('foo( // comment',
2518 'At least two spaces is best between code'
2519 ' and comments [whitespace/comments] [2]')
erg@google.com36649102009-03-25 21:18:36 +00002520 self.TestLint('foobar( \\', '')
2521 self.TestLint('foobar( \\', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002522 self.TestLint('( a + b)', 'Extra space after ('
2523 ' [whitespace/parens] [2]')
2524 self.TestLint('((a+b))', '')
2525 self.TestLint('foo (foo)', 'Extra space before ( in function call'
2526 ' [whitespace/parens] [4]')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002527 # asm volatile () may have a space, as it isn't a function call.
2528 self.TestLint('asm volatile ("")', '')
2529 self.TestLint('__asm__ __volatile__ ("")', '')
erg@google.comfd5da632013-10-25 17:39:45 +00002530 self.TestLint('} catch (const Foo& ex) {', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00002531 self.TestLint('case (42):', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002532 self.TestLint('typedef foo (*foo)(foo)', '')
2533 self.TestLint('typedef foo (*foo12bar_)(foo)', '')
2534 self.TestLint('typedef foo (Foo::*bar)(foo)', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002535 self.TestLint('using foo = type (Foo::*bar)(foo)', '')
2536 self.TestLint('using foo = type (Foo::*bar)(', '')
2537 self.TestLint('using foo = type (Foo::*)(', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002538 self.TestLint('foo (Foo::*bar)(', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002539 self.TestLint('foo (x::y::*z)(', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002540 self.TestLint('foo (Foo::bar)(',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002541 'Extra space before ( in function call'
2542 ' [whitespace/parens] [4]')
erg@google.comd350fe52013-01-14 17:51:48 +00002543 self.TestLint('foo (*bar)(', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002544 self.TestLint('typedef foo (Foo::*bar)(', '')
2545 self.TestLint('(foo)(bar)', '')
2546 self.TestLint('Foo (*foo)(bar)', '')
2547 self.TestLint('Foo (*foo)(Bar bar,', '')
2548 self.TestLint('char (*p)[sizeof(foo)] = &foo', '')
2549 self.TestLint('char (&ref)[sizeof(foo)] = &foo', '')
2550 self.TestLint('const char32 (*table[])[6];', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002551 # The sizeof operator is often written as if it were a function call, with
2552 # an opening parenthesis directly following the operator name, but it can
2553 # also be written like any other operator, with a space following the
2554 # operator name, and the argument optionally in parentheses.
2555 self.TestLint('sizeof(foo)', '')
2556 self.TestLint('sizeof foo', '')
2557 self.TestLint('sizeof (foo)', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002558
2559 def testSpacingBeforeBraces(self):
2560 self.TestLint('if (foo){', 'Missing space before {'
2561 ' [whitespace/braces] [5]')
2562 self.TestLint('for{', 'Missing space before {'
2563 ' [whitespace/braces] [5]')
2564 self.TestLint('for {', '')
2565 self.TestLint('EXPECT_DEBUG_DEATH({', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00002566 self.TestLint('std::is_convertible<A, B>{}', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002567 self.TestLint('blah{32}', 'Missing space before {'
2568 ' [whitespace/braces] [5]')
2569 self.TestLint('int8_t{3}', '')
2570 self.TestLint('int16_t{3}', '')
2571 self.TestLint('int32_t{3}', '')
2572 self.TestLint('uint64_t{12345}', '')
2573 self.TestLint('constexpr int64_t kBatchGapMicros ='
2574 ' int64_t{7} * 24 * 3600 * 1000000; // 1 wk.', '')
2575 self.TestLint('MoveOnly(int i1, int i2) : ip1{new int{i1}}, '
2576 'ip2{new int{i2}} {}',
2577 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002578
erg@google.comfd5da632013-10-25 17:39:45 +00002579 def testSemiColonAfterBraces(self):
Alex Vakulenko01e47232016-05-06 13:54:15 -07002580 self.TestLint('if (cond) { func(); };',
erg@google.comfd5da632013-10-25 17:39:45 +00002581 'You don\'t need a ; after a } [readability/braces] [4]')
erg@google.com2aa59982013-10-28 19:09:25 +00002582 self.TestLint('void Func() {};',
2583 'You don\'t need a ; after a } [readability/braces] [4]')
2584 self.TestLint('void Func() const {};',
2585 'You don\'t need a ; after a } [readability/braces] [4]')
erg@google.comfd5da632013-10-25 17:39:45 +00002586 self.TestLint('class X {};', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00002587 for keyword in ['struct', 'union']:
2588 for align in ['', ' alignas(16)']:
2589 for typename in ['', ' X']:
2590 for identifier in ['', ' x']:
2591 self.TestLint(keyword + align + typename + ' {}' + identifier + ';',
2592 '')
erg@google.com2aa59982013-10-28 19:09:25 +00002593
2594 self.TestLint('class X : public Y {};', '')
2595 self.TestLint('class X : public MACRO() {};', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002596 self.TestLint('class X : public decltype(expr) {};', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002597 self.TestLint('DEFINE_FACADE(PCQueue::Watcher, PCQueue) {};', '')
2598 self.TestLint('VCLASS(XfaTest, XfaContextTest) {};', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002599 self.TestLint('class STUBBY_CLASS(H, E) {};', '')
2600 self.TestLint('class STUBBY2_CLASS(H, E) {};', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002601 self.TestLint('TEST(TestCase, TestName) {};',
2602 'You don\'t need a ; after a } [readability/braces] [4]')
2603 self.TestLint('TEST_F(TestCase, TestName) {};',
2604 'You don\'t need a ; after a } [readability/braces] [4]')
2605
2606 self.TestLint('file_tocs_[i] = (FileToc) {a, b, c};', '')
2607 self.TestMultiLineLint('class X : public Y,\npublic Z {};', '')
2608
avakulenko@google.com02af6282014-06-04 18:53:25 +00002609 def testLambda(self):
2610 self.TestLint('auto x = []() {};', '')
2611 self.TestLint('return []() {};', '')
2612 self.TestMultiLineLint('auto x = []() {\n};\n', '')
2613 self.TestLint('int operator[](int x) {};',
2614 'You don\'t need a ; after a } [readability/braces] [4]')
2615
2616 self.TestMultiLineLint('auto x = [&a,\nb]() {};', '')
2617 self.TestMultiLineLint('auto x = [&a,\nb]\n() {};', '')
2618 self.TestMultiLineLint('auto x = [&a,\n'
2619 ' b](\n'
2620 ' int a,\n'
2621 ' int b) {\n'
2622 ' return a +\n'
2623 ' b;\n'
2624 '};\n',
2625 '')
2626
avakulenko@google.com02af6282014-06-04 18:53:25 +00002627 # Avoid false positives with operator[]
2628 self.TestLint('table_to_children[&*table].push_back(dependent);', '')
2629
erg@google.com2aa59982013-10-28 19:09:25 +00002630 def testBraceInitializerList(self):
2631 self.TestLint('MyStruct p = {1, 2};', '')
2632 self.TestLint('MyStruct p{1, 2};', '')
2633 self.TestLint('vector<int> p = {1, 2};', '')
2634 self.TestLint('vector<int> p{1, 2};', '')
2635 self.TestLint('x = vector<int>{1, 2};', '')
2636 self.TestLint('x = (struct in_addr){ 0 };', '')
2637 self.TestLint('Func(vector<int>{1, 2})', '')
2638 self.TestLint('Func((struct in_addr){ 0 })', '')
2639 self.TestLint('Func(vector<int>{1, 2}, 3)', '')
2640 self.TestLint('Func((struct in_addr){ 0 }, 3)', '')
2641 self.TestLint('LOG(INFO) << char{7};', '')
2642 self.TestLint('LOG(INFO) << char{7} << "!";', '')
2643 self.TestLint('int p[2] = {1, 2};', '')
2644 self.TestLint('return {1, 2};', '')
2645 self.TestLint('std::unique_ptr<Foo> foo{new Foo{}};', '')
2646 self.TestLint('auto foo = std::unique_ptr<Foo>{new Foo{}};', '')
2647 self.TestLint('static_assert(Max7String{}.IsValid(), "");', '')
2648 self.TestLint('map_of_pairs[{1, 2}] = 3;', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002649 self.TestLint('ItemView{has_offer() ? new Offer{offer()} : nullptr', '')
2650 self.TestLint('template <class T, EnableIf<::std::is_const<T>{}> = 0>', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002651
2652 self.TestMultiLineLint('std::unique_ptr<Foo> foo{\n'
2653 ' new Foo{}\n'
2654 '};\n', '')
2655 self.TestMultiLineLint('std::unique_ptr<Foo> foo{\n'
2656 ' new Foo{\n'
2657 ' new Bar{}\n'
2658 ' }\n'
2659 '};\n', '')
2660 self.TestMultiLineLint('if (true) {\n'
Alex Vakulenko01e47232016-05-06 13:54:15 -07002661 ' if (false){ func(); }\n'
erg@google.com2aa59982013-10-28 19:09:25 +00002662 '}\n',
2663 'Missing space before { [whitespace/braces] [5]')
2664 self.TestMultiLineLint('MyClass::MyClass()\n'
2665 ' : initializer_{\n'
2666 ' Func()} {\n'
2667 '}\n', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002668 self.TestLint('const pair<string, string> kCL' +
2669 ('o' * 41) + 'gStr[] = {\n',
2670 'Lines should be <= 80 characters long'
2671 ' [whitespace/line_length] [2]')
2672 self.TestMultiLineLint('const pair<string, string> kCL' +
2673 ('o' * 40) + 'ngStr[] =\n'
2674 ' {\n'
2675 ' {"gooooo", "oooogle"},\n'
2676 '};\n', '')
2677 self.TestMultiLineLint('const pair<string, string> kCL' +
2678 ('o' * 39) + 'ngStr[] =\n'
2679 ' {\n'
2680 ' {"gooooo", "oooogle"},\n'
2681 '};\n', '{ should almost always be at the end of '
2682 'the previous line [whitespace/braces] [4]')
erg@google.comfd5da632013-10-25 17:39:45 +00002683
erg@google.com4e00b9a2009-01-12 23:05:11 +00002684 def testSpacingAroundElse(self):
2685 self.TestLint('}else {', 'Missing space before else'
2686 ' [whitespace/braces] [5]')
2687 self.TestLint('} else{', 'Missing space before {'
2688 ' [whitespace/braces] [5]')
2689 self.TestLint('} else {', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002690 self.TestLint('} else if (foo) {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002691
erg@google.com8a95ecc2011-09-08 00:45:54 +00002692 def testSpacingWithInitializerLists(self):
2693 self.TestLint('int v[1][3] = {{1, 2, 3}};', '')
2694 self.TestLint('int v[1][1] = {{0}};', '')
2695
erg@google.com4e00b9a2009-01-12 23:05:11 +00002696 def testSpacingForBinaryOps(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00002697 self.TestLint('if (foo||bar) {', 'Missing spaces around ||'
2698 ' [whitespace/operators] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002699 self.TestLint('if (foo<=bar) {', 'Missing spaces around <='
2700 ' [whitespace/operators] [3]')
2701 self.TestLint('if (foo<bar) {', 'Missing spaces around <'
2702 ' [whitespace/operators] [3]')
erg@google.comd350fe52013-01-14 17:51:48 +00002703 self.TestLint('if (foo>bar) {', 'Missing spaces around >'
2704 ' [whitespace/operators] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002705 self.TestLint('if (foo<bar->baz) {', 'Missing spaces around <'
2706 ' [whitespace/operators] [3]')
2707 self.TestLint('if (foo<bar->bar) {', 'Missing spaces around <'
2708 ' [whitespace/operators] [3]')
erg@google.comd350fe52013-01-14 17:51:48 +00002709 self.TestLint('template<typename T = double>', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002710 self.TestLint('std::unique_ptr<No<Spaces>>', '')
2711 self.TestLint('typedef hash_map<Foo, Bar>', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002712 self.TestLint('10<<20', '')
2713 self.TestLint('10<<a',
2714 'Missing spaces around << [whitespace/operators] [3]')
2715 self.TestLint('a<<20',
2716 'Missing spaces around << [whitespace/operators] [3]')
2717 self.TestLint('a<<b',
2718 'Missing spaces around << [whitespace/operators] [3]')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002719 self.TestLint('10LL<<20', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002720 self.TestLint('10ULL<<20', '')
2721 self.TestLint('a>>b',
2722 'Missing spaces around >> [whitespace/operators] [3]')
2723 self.TestLint('10>>b',
2724 'Missing spaces around >> [whitespace/operators] [3]')
2725 self.TestLint('LOG(ERROR)<<*foo',
2726 'Missing spaces around << [whitespace/operators] [3]')
2727 self.TestLint('LOG(ERROR)<<&foo',
2728 'Missing spaces around << [whitespace/operators] [3]')
2729 self.TestLint('StringCoder<vector<string>>::ToString()', '')
2730 self.TestLint('map<pair<int, int>, map<int, int>>::iterator', '')
2731 self.TestLint('func<int, pair<int, pair<int, int>>>()', '')
2732 self.TestLint('MACRO1(list<list<int>>)', '')
2733 self.TestLint('MACRO2(list<list<int>>, 42)', '')
2734 self.TestLint('void DoFoo(const set<vector<string>>& arg1);', '')
2735 self.TestLint('void SetFoo(set<vector<string>>* arg1);', '')
2736 self.TestLint('foo = new set<vector<string>>;', '')
2737 self.TestLint('reinterpret_cast<set<vector<string>>*>(a);', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002738 self.TestLint('MACRO(<<)', '')
2739 self.TestLint('MACRO(<<, arg)', '')
2740 self.TestLint('MACRO(<<=)', '')
2741 self.TestLint('MACRO(<<=, arg)', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002742
avakulenko@google.com02af6282014-06-04 18:53:25 +00002743 self.TestLint('using Vector3<T>::operator==;', '')
2744 self.TestLint('using Vector3<T>::operator!=;', '')
2745
erg@google.com4e00b9a2009-01-12 23:05:11 +00002746 def testSpacingBeforeLastSemicolon(self):
2747 self.TestLint('call_function() ;',
2748 'Extra space before last semicolon. If this should be an '
erg@google.comd350fe52013-01-14 17:51:48 +00002749 'empty statement, use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002750 ' [whitespace/semicolon] [5]')
2751 self.TestLint('while (true) ;',
2752 'Extra space before last semicolon. If this should be an '
erg@google.comd350fe52013-01-14 17:51:48 +00002753 'empty statement, use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002754 ' [whitespace/semicolon] [5]')
2755 self.TestLint('default:;',
erg@google.comd350fe52013-01-14 17:51:48 +00002756 'Semicolon defining empty statement. Use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002757 ' [whitespace/semicolon] [5]')
2758 self.TestLint(' ;',
2759 'Line contains only semicolon. If this should be an empty '
erg@google.comd350fe52013-01-14 17:51:48 +00002760 'statement, use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002761 ' [whitespace/semicolon] [5]')
2762 self.TestLint('for (int i = 0; ;', '')
2763
erg@google.comc6671232013-10-25 21:44:03 +00002764 def testEmptyBlockBody(self):
erg@google.comd350fe52013-01-14 17:51:48 +00002765 self.TestLint('while (true);',
2766 'Empty loop bodies should use {} or continue'
2767 ' [whitespace/empty_loop_body] [5]')
erg@google.comc6671232013-10-25 21:44:03 +00002768 self.TestLint('if (true);',
2769 'Empty conditional bodies should use {}'
2770 ' [whitespace/empty_conditional_body] [5]')
erg@google.comd350fe52013-01-14 17:51:48 +00002771 self.TestLint('while (true)', '')
2772 self.TestLint('while (true) continue;', '')
2773 self.TestLint('for (;;);',
2774 'Empty loop bodies should use {} or continue'
2775 ' [whitespace/empty_loop_body] [5]')
2776 self.TestLint('for (;;)', '')
2777 self.TestLint('for (;;) continue;', '')
2778 self.TestLint('for (;;) func();', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002779 self.TestLint('if (test) {}',
2780 'If statement had no body and no else clause'
2781 ' [whitespace/empty_if_body] [4]')
2782 self.TestLint('if (test) func();', '')
2783 self.TestLint('if (test) {} else {}', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002784 self.TestMultiLineLint("""while (true &&
2785 false);""",
2786 'Empty loop bodies should use {} or continue'
2787 ' [whitespace/empty_loop_body] [5]')
2788 self.TestMultiLineLint("""do {
2789 } while (false);""",
2790 '')
2791 self.TestMultiLineLint("""#define MACRO \\
2792 do { \\
2793 } while (false);""",
2794 '')
2795 self.TestMultiLineLint("""do {
2796 } while (false); // next line gets a warning
2797 while (false);""",
2798 'Empty loop bodies should use {} or continue'
2799 ' [whitespace/empty_loop_body] [5]')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002800 self.TestMultiLineLint("""if (test) {
2801 }""",
2802 'If statement had no body and no else clause'
2803 ' [whitespace/empty_if_body] [4]')
2804 self.TestMultiLineLint("""if (test,
2805 func({})) {
2806 }""",
2807 'If statement had no body and no else clause'
2808 ' [whitespace/empty_if_body] [4]')
2809 self.TestMultiLineLint("""if (test)
2810 func();""", '')
2811 self.TestLint('if (test) { hello; }', '')
2812 self.TestLint('if (test({})) { hello; }', '')
2813 self.TestMultiLineLint("""if (test) {
2814 func();
2815 }""", '')
2816 self.TestMultiLineLint("""if (test) {
2817 // multiline
2818 // comment
2819 }""", '')
2820 self.TestMultiLineLint("""if (test) { // comment
2821 }""", '')
2822 self.TestMultiLineLint("""if (test) {
2823 } else {
2824 }""", '')
2825 self.TestMultiLineLint("""if (func(p1,
2826 p2,
2827 p3)) {
2828 func();
2829 }""", '')
2830 self.TestMultiLineLint("""if (func({}, p1)) {
2831 func();
2832 }""", '')
erg@google.comd350fe52013-01-14 17:51:48 +00002833
2834 def testSpacingForRangeBasedFor(self):
2835 # Basic correctly formatted case:
2836 self.TestLint('for (int i : numbers) {', '')
2837
2838 # Missing space before colon:
2839 self.TestLint('for (int i: numbers) {',
2840 'Missing space around colon in range-based for loop'
2841 ' [whitespace/forcolon] [2]')
2842 # Missing space after colon:
2843 self.TestLint('for (int i :numbers) {',
2844 'Missing space around colon in range-based for loop'
2845 ' [whitespace/forcolon] [2]')
2846 # Missing spaces both before and after the colon.
2847 self.TestLint('for (int i:numbers) {',
2848 'Missing space around colon in range-based for loop'
2849 ' [whitespace/forcolon] [2]')
2850
2851 # The scope operator '::' shouldn't cause warnings...
2852 self.TestLint('for (std::size_t i : sizes) {}', '')
2853 # ...but it shouldn't suppress them either.
2854 self.TestLint('for (std::size_t i: sizes) {}',
2855 'Missing space around colon in range-based for loop'
2856 ' [whitespace/forcolon] [2]')
2857
2858
erg@google.com4e00b9a2009-01-12 23:05:11 +00002859 # Static or global STL strings.
2860 def testStaticOrGlobalSTLStrings(self):
Alex Vakulenko01e47232016-05-06 13:54:15 -07002861 # A template for the error message for a const global/static string.
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002862 error_msg = ('For a static/global string constant, use a C style '
2863 'string instead: "%s[]". [runtime/string] [4]')
2864
Alex Vakulenko01e47232016-05-06 13:54:15 -07002865 # The error message for a non-const global/static string variable.
2866 nonconst_error_msg = ('Static/global string variables are not permitted.'
2867 ' [runtime/string] [4]')
2868
erg@google.com4e00b9a2009-01-12 23:05:11 +00002869 self.TestLint('string foo;',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002870 nonconst_error_msg)
erg@google.com4e00b9a2009-01-12 23:05:11 +00002871 self.TestLint('string kFoo = "hello"; // English',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002872 nonconst_error_msg)
erg@google.com4e00b9a2009-01-12 23:05:11 +00002873 self.TestLint('static string foo;',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002874 nonconst_error_msg)
erg@google.com4e00b9a2009-01-12 23:05:11 +00002875 self.TestLint('static const string foo;',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002876 error_msg % 'static const char foo')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002877 self.TestLint('static const std::string foo;',
2878 error_msg % 'static const char foo')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002879 self.TestLint('string Foo::bar;',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002880 nonconst_error_msg)
2881
2882 self.TestLint('std::string foo;',
2883 nonconst_error_msg)
2884 self.TestLint('std::string kFoo = "hello"; // English',
2885 nonconst_error_msg)
2886 self.TestLint('static std::string foo;',
2887 nonconst_error_msg)
2888 self.TestLint('static const std::string foo;',
2889 error_msg % 'static const char foo')
2890 self.TestLint('std::string Foo::bar;',
2891 nonconst_error_msg)
2892
2893 self.TestLint('::std::string foo;',
2894 nonconst_error_msg)
2895 self.TestLint('::std::string kFoo = "hello"; // English',
2896 nonconst_error_msg)
2897 self.TestLint('static ::std::string foo;',
2898 nonconst_error_msg)
2899 self.TestLint('static const ::std::string foo;',
2900 error_msg % 'static const char foo')
2901 self.TestLint('::std::string Foo::bar;',
2902 nonconst_error_msg)
2903
avakulenko@google.com02af6282014-06-04 18:53:25 +00002904 self.TestLint('string* pointer', '')
2905 self.TestLint('string *pointer', '')
2906 self.TestLint('string* pointer = Func();', '')
2907 self.TestLint('string *pointer = Func();', '')
2908 self.TestLint('const string* pointer', '')
2909 self.TestLint('const string *pointer', '')
2910 self.TestLint('const string* pointer = Func();', '')
2911 self.TestLint('const string *pointer = Func();', '')
2912 self.TestLint('string const* pointer', '')
2913 self.TestLint('string const *pointer', '')
2914 self.TestLint('string const* pointer = Func();', '')
2915 self.TestLint('string const *pointer = Func();', '')
2916 self.TestLint('string* const pointer', '')
2917 self.TestLint('string *const pointer', '')
2918 self.TestLint('string* const pointer = Func();', '')
2919 self.TestLint('string *const pointer = Func();', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002920 self.TestLint('string Foo::bar() {}', '')
2921 self.TestLint('string Foo::operator*() {}', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002922 # Rare case.
Alex Vakulenko01e47232016-05-06 13:54:15 -07002923 self.TestLint('string foo("foobar");', nonconst_error_msg)
erg@google.com4e00b9a2009-01-12 23:05:11 +00002924 # Should not catch local or member variables.
2925 self.TestLint(' string foo', '')
2926 # Should not catch functions.
2927 self.TestLint('string EmptyString() { return ""; }', '')
2928 self.TestLint('string EmptyString () { return ""; }', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07002929 self.TestLint('string const& FileInfo::Pathname() const;', '')
2930 self.TestLint('string const &FileInfo::Pathname() const;', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002931 self.TestLint('string VeryLongNameFunctionSometimesEndsWith(\n'
2932 ' VeryLongNameType very_long_name_variable) {}', '')
2933 self.TestLint('template<>\n'
2934 'string FunctionTemplateSpecialization<SomeType>(\n'
2935 ' int x) { return ""; }', '')
2936 self.TestLint('template<>\n'
2937 'string FunctionTemplateSpecialization<vector<A::B>* >(\n'
2938 ' int x) { return ""; }', '')
2939
2940 # should not catch methods of template classes.
2941 self.TestLint('string Class<Type>::Method() const {\n'
2942 ' return "";\n'
2943 '}\n', '')
2944 self.TestLint('string Class<Type>::Method(\n'
2945 ' int arg) const {\n'
2946 ' return "";\n'
2947 '}\n', '')
2948
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002949 # Check multiline cases.
2950 error_collector = ErrorCollector(self.assert_)
2951 cpplint.ProcessFileData('foo.cc', 'cc',
2952 ['// Copyright 2014 Your Company.',
2953 'string Class',
2954 '::MemberFunction1();',
2955 'string Class::',
2956 'MemberFunction2();',
2957 'string Class::',
2958 'NestedClass::MemberFunction3();',
2959 'string TemplateClass<T>::',
2960 'NestedClass::MemberFunction4();',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002961 'const string Class',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002962 '::static_member_variable1;',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002963 'const string Class::',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002964 'static_member_variable2;',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002965 'const string Class',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002966 '::static_member_variable3 = "initial value";',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002967 'const string Class::',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002968 'static_member_variable4 = "initial value";',
Alex Vakulenko01e47232016-05-06 13:54:15 -07002969 'string Class::',
2970 'static_member_variable5;',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002971 ''],
2972 error_collector)
2973 self.assertEquals(error_collector.Results(),
Alex Vakulenko01e47232016-05-06 13:54:15 -07002974 [error_msg % 'const char Class::static_member_variable1',
2975 error_msg % 'const char Class::static_member_variable2',
2976 error_msg % 'const char Class::static_member_variable3',
2977 error_msg % 'const char Class::static_member_variable4',
2978 nonconst_error_msg])
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002979
erg@google.com4e00b9a2009-01-12 23:05:11 +00002980 def testNoSpacesInFunctionCalls(self):
2981 self.TestLint('TellStory(1, 3);',
2982 '')
2983 self.TestLint('TellStory(1, 3 );',
2984 'Extra space before )'
2985 ' [whitespace/parens] [2]')
2986 self.TestLint('TellStory(1 /* wolf */, 3 /* pigs */);',
2987 '')
erg@google.com8a95ecc2011-09-08 00:45:54 +00002988 self.TestMultiLineLint("""TellStory(1, 3
2989 );""",
2990 'Closing ) should be moved to the previous line'
2991 ' [whitespace/parens] [2]')
2992 self.TestMultiLineLint("""TellStory(Wolves(1),
2993 Pigs(3
2994 ));""",
2995 'Closing ) should be moved to the previous line'
2996 ' [whitespace/parens] [2]')
2997 self.TestMultiLineLint("""TellStory(1,
2998 3 );""",
2999 'Extra space before )'
3000 ' [whitespace/parens] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003001
3002 def testToDoComments(self):
3003 start_space = ('Too many spaces before TODO'
3004 ' [whitespace/todo] [2]')
3005 missing_username = ('Missing username in TODO; it should look like '
3006 '"// TODO(my_username): Stuff."'
3007 ' [readability/todo] [2]')
3008 end_space = ('TODO(my_username) should be followed by a space'
3009 ' [whitespace/todo] [2]')
3010
3011 self.TestLint('// TODOfix this',
3012 [start_space, missing_username, end_space])
3013 self.TestLint('// TODO(ljenkins)fix this',
3014 [start_space, end_space])
3015 self.TestLint('// TODO fix this',
3016 [start_space, missing_username])
3017 self.TestLint('// TODO fix this', missing_username)
3018 self.TestLint('// TODO: fix this', missing_username)
3019 self.TestLint('//TODO(ljenkins): Fix this',
3020 'Should have a space between // and comment'
3021 ' [whitespace/comments] [4]')
3022 self.TestLint('// TODO(ljenkins):Fix this', end_space)
3023 self.TestLint('// TODO(ljenkins):', '')
3024 self.TestLint('// TODO(ljenkins): fix this', '')
3025 self.TestLint('// TODO(ljenkins): Fix this', '')
erg@google.comd350fe52013-01-14 17:51:48 +00003026 self.TestLint('#if 1 // TEST_URLTODOCID_WHICH_HAS_THAT_WORD_IN_IT_H_', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003027 self.TestLint('// See also similar TODO above', '')
Alex Vakulenko01e47232016-05-06 13:54:15 -07003028 self.TestLint(r'EXPECT_EQ("\\", '
3029 r'NormalizePath("/./../foo///bar/..//x/../..", ""));',
3030 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003031
3032 def testTwoSpacesBetweenCodeAndComments(self):
3033 self.TestLint('} // namespace foo',
3034 'At least two spaces is best between code and comments'
3035 ' [whitespace/comments] [2]')
3036 self.TestLint('}// namespace foo',
3037 'At least two spaces is best between code and comments'
3038 ' [whitespace/comments] [2]')
3039 self.TestLint('printf("foo"); // Outside quotes.',
3040 'At least two spaces is best between code and comments'
3041 ' [whitespace/comments] [2]')
3042 self.TestLint('int i = 0; // Having two spaces is fine.', '')
3043 self.TestLint('int i = 0; // Having three spaces is OK.', '')
3044 self.TestLint('// Top level comment', '')
3045 self.TestLint(' // Line starts with two spaces.', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003046 self.TestMultiLineLint('void foo() {\n'
3047 ' { // A scope is opening.\n'
3048 ' int a;', '')
3049 self.TestMultiLineLint('void foo() {\n'
3050 ' { // A scope is opening.\n'
3051 '#define A a',
3052 'At least two spaces is best between code and '
3053 'comments [whitespace/comments] [2]')
3054 self.TestMultiLineLint(' foo();\n'
3055 ' { // An indented scope is opening.\n'
3056 ' int a;', '')
3057 self.TestMultiLineLint('vector<int> my_elements = {// first\n'
3058 ' 1,', '')
3059 self.TestMultiLineLint('vector<int> my_elements = {// my_elements is ..\n'
3060 ' 1,',
3061 'At least two spaces is best between code and '
3062 'comments [whitespace/comments] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003063 self.TestLint('if (foo) { // not a pure scope; comment is too close!',
3064 'At least two spaces is best between code and comments'
3065 ' [whitespace/comments] [2]')
3066 self.TestLint('printf("// In quotes.")', '')
3067 self.TestLint('printf("\\"%s // In quotes.")', '')
3068 self.TestLint('printf("%s", "// In quotes.")', '')
3069
3070 def testSpaceAfterCommentMarker(self):
3071 self.TestLint('//', '')
3072 self.TestLint('//x', 'Should have a space between // and comment'
3073 ' [whitespace/comments] [4]')
3074 self.TestLint('// x', '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00003075 self.TestLint('///', '')
3076 self.TestLint('/// x', '')
3077 self.TestLint('//!', '')
erg@google.come35f7652009-06-19 20:52:09 +00003078 self.TestLint('//----', '')
3079 self.TestLint('//====', '')
3080 self.TestLint('//////', '')
3081 self.TestLint('////// x', '')
erg@google.com6d8d9832013-10-31 19:46:18 +00003082 self.TestLint('///< x', '') # After-member Doxygen comment
3083 self.TestLint('//!< x', '') # After-member Doxygen comment
erg@google.come35f7652009-06-19 20:52:09 +00003084 self.TestLint('////x', 'Should have a space between // and comment'
3085 ' [whitespace/comments] [4]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003086 self.TestLint('//}', '')
3087 self.TestLint('//}x', 'Should have a space between // and comment'
3088 ' [whitespace/comments] [4]')
erg@google.com6d8d9832013-10-31 19:46:18 +00003089 self.TestLint('//!<x', 'Should have a space between // and comment'
3090 ' [whitespace/comments] [4]')
3091 self.TestLint('///<x', 'Should have a space between // and comment'
3092 ' [whitespace/comments] [4]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003093
3094 # Test a line preceded by empty or comment lines. There was a bug
3095 # that caused it to print the same warning N times if the erroneous
3096 # line was preceded by N lines of empty or comment lines. To be
3097 # precise, the '// marker so line numbers and indices both start at
3098 # 1' line was also causing the issue.
3099 def testLinePrecededByEmptyOrCommentLines(self):
3100 def DoTest(self, lines):
3101 error_collector = ErrorCollector(self.assert_)
3102 cpplint.ProcessFileData('foo.cc', 'cc', lines, error_collector)
3103 # The warning appears only once.
3104 self.assertEquals(
3105 1,
3106 error_collector.Results().count(
3107 'Do not use namespace using-directives. '
3108 'Use using-declarations instead.'
3109 ' [build/namespaces] [5]'))
3110 DoTest(self, ['using namespace foo;'])
3111 DoTest(self, ['', '', '', 'using namespace foo;'])
3112 DoTest(self, ['// hello', 'using namespace foo;'])
3113
3114 def testNewlineAtEOF(self):
3115 def DoTest(self, data, is_missing_eof):
3116 error_collector = ErrorCollector(self.assert_)
3117 cpplint.ProcessFileData('foo.cc', 'cc', data.split('\n'),
3118 error_collector)
3119 # The warning appears only once.
3120 self.assertEquals(
3121 int(is_missing_eof),
3122 error_collector.Results().count(
3123 'Could not find a newline character at the end of the file.'
3124 ' [whitespace/ending_newline] [5]'))
3125
3126 DoTest(self, '// Newline\n// at EOF\n', False)
3127 DoTest(self, '// No newline\n// at EOF', True)
3128
3129 def testInvalidUtf8(self):
3130 def DoTest(self, raw_bytes, has_invalid_utf8):
3131 error_collector = ErrorCollector(self.assert_)
3132 cpplint.ProcessFileData(
3133 'foo.cc', 'cc',
3134 unicode(raw_bytes, 'utf8', 'replace').split('\n'),
3135 error_collector)
3136 # The warning appears only once.
3137 self.assertEquals(
3138 int(has_invalid_utf8),
3139 error_collector.Results().count(
3140 'Line contains invalid UTF-8'
3141 ' (or Unicode replacement character).'
3142 ' [readability/utf8] [5]'))
3143
3144 DoTest(self, 'Hello world\n', False)
3145 DoTest(self, '\xe9\x8e\xbd\n', False)
3146 DoTest(self, '\xe9x\x8e\xbd\n', True)
3147 # This is the encoding of the replacement character itself (which
3148 # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')).
3149 DoTest(self, '\xef\xbf\xbd\n', True)
3150
erg@google.com2aa59982013-10-28 19:09:25 +00003151 def testBadCharacters(self):
3152 # Test for NUL bytes only
3153 error_collector = ErrorCollector(self.assert_)
3154 cpplint.ProcessFileData('nul.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003155 ['// Copyright 2014 Your Company.',
erg@google.com2aa59982013-10-28 19:09:25 +00003156 '\0', ''], error_collector)
3157 self.assertEquals(
3158 error_collector.Results(),
3159 'Line contains NUL byte. [readability/nul] [5]')
3160
3161 # Make sure both NUL bytes and UTF-8 are caught if they appear on
3162 # the same line.
3163 error_collector = ErrorCollector(self.assert_)
3164 cpplint.ProcessFileData(
3165 'nul_utf8.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003166 ['// Copyright 2014 Your Company.',
erg@google.com2aa59982013-10-28 19:09:25 +00003167 unicode('\xe9x\0', 'utf8', 'replace'), ''],
3168 error_collector)
3169 self.assertEquals(
3170 error_collector.Results(),
3171 ['Line contains invalid UTF-8 (or Unicode replacement character).'
3172 ' [readability/utf8] [5]',
3173 'Line contains NUL byte. [readability/nul] [5]'])
3174
erg@google.com4e00b9a2009-01-12 23:05:11 +00003175 def testIsBlankLine(self):
3176 self.assert_(cpplint.IsBlankLine(''))
3177 self.assert_(cpplint.IsBlankLine(' '))
3178 self.assert_(cpplint.IsBlankLine(' \t\r\n'))
3179 self.assert_(not cpplint.IsBlankLine('int a;'))
3180 self.assert_(not cpplint.IsBlankLine('{'))
3181
3182 def testBlankLinesCheck(self):
3183 self.TestBlankLinesCheck(['{\n', '\n', '\n', '}\n'], 1, 1)
3184 self.TestBlankLinesCheck([' if (foo) {\n', '\n', ' }\n'], 1, 1)
3185 self.TestBlankLinesCheck(
3186 ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0)
3187 self.TestBlankLinesCheck(['\n', 'run("{");\n', '\n'], 0, 0)
3188 self.TestBlankLinesCheck(['\n', ' if (foo) { return 0; }\n', '\n'], 0, 0)
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003189 self.TestBlankLinesCheck(
3190 ['int x(\n', ' int a) {\n', '\n', 'return 0;\n', '}'], 0, 0)
3191 self.TestBlankLinesCheck(
3192 ['int x(\n', ' int a) const {\n', '\n', 'return 0;\n', '}'], 0, 0)
3193 self.TestBlankLinesCheck(
3194 ['int x(\n', ' int a) {\n', '\n', 'return 0;\n', '}'], 1, 0)
3195 self.TestBlankLinesCheck(
3196 ['int x(\n', ' int a) {\n', '\n', 'return 0;\n', '}'], 1, 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00003197
3198 def testAllowBlankLineBeforeClosingNamespace(self):
3199 error_collector = ErrorCollector(self.assert_)
3200 cpplint.ProcessFileData('foo.cc', 'cc',
erg@google.comd350fe52013-01-14 17:51:48 +00003201 ['namespace {',
3202 '',
3203 '} // namespace',
3204 'namespace another_namespace {',
3205 '',
3206 '}',
3207 'namespace {',
3208 '',
3209 'template<class T, ',
3210 ' class A = hoge<T>, ',
3211 ' class B = piyo<T>, ',
3212 ' class C = fuga<T> >',
3213 'class D {',
3214 ' public:',
3215 '};',
3216 '', '', '', '',
3217 '}'],
erg@google.com4e00b9a2009-01-12 23:05:11 +00003218 error_collector)
3219 self.assertEquals(0, error_collector.Results().count(
erg@google.com2aa59982013-10-28 19:09:25 +00003220 'Redundant blank line at the end of a code block should be deleted.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00003221 ' [whitespace/blank_line] [3]'))
3222
3223 def testAllowBlankLineBeforeIfElseChain(self):
3224 error_collector = ErrorCollector(self.assert_)
3225 cpplint.ProcessFileData('foo.cc', 'cc',
3226 ['if (hoge) {',
3227 '', # No warning
3228 '} else if (piyo) {',
3229 '', # No warning
3230 '} else if (piyopiyo) {',
3231 ' hoge = true;', # No warning
3232 '} else {',
3233 '', # Warning on this line
3234 '}'],
3235 error_collector)
3236 self.assertEquals(1, error_collector.Results().count(
erg@google.com2aa59982013-10-28 19:09:25 +00003237 'Redundant blank line at the end of a code block should be deleted.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00003238 ' [whitespace/blank_line] [3]'))
3239
avakulenko@google.com02af6282014-06-04 18:53:25 +00003240 def testAllowBlankLineAfterExtern(self):
3241 error_collector = ErrorCollector(self.assert_)
3242 cpplint.ProcessFileData('foo.cc', 'cc',
3243 ['extern "C" {',
3244 '',
3245 'EXPORTAPI void APICALL Some_function() {}',
3246 '',
3247 '}'],
3248 error_collector)
3249 self.assertEquals(0, error_collector.Results().count(
3250 'Redundant blank line at the start of a code block should be deleted.'
3251 ' [whitespace/blank_line] [2]'))
3252 self.assertEquals(0, error_collector.Results().count(
3253 'Redundant blank line at the end of a code block should be deleted.'
3254 ' [whitespace/blank_line] [3]'))
3255
erg@google.com8a95ecc2011-09-08 00:45:54 +00003256 def testBlankLineBeforeSectionKeyword(self):
3257 error_collector = ErrorCollector(self.assert_)
3258 cpplint.ProcessFileData('foo.cc', 'cc',
3259 ['class A {',
3260 ' public:',
3261 ' protected:', # warning 1
3262 ' private:', # warning 2
3263 ' struct B {',
3264 ' public:',
3265 ' private:'] + # warning 3
3266 ([''] * 100) + # Make A and B longer than 100 lines
3267 [' };',
3268 ' struct C {',
3269 ' protected:',
3270 ' private:', # C is too short for warnings
3271 ' };',
3272 '};',
3273 'class D',
3274 ' : public {',
3275 ' public:', # no warning
erg@google.comd350fe52013-01-14 17:51:48 +00003276 '};',
3277 'class E {\\',
3278 ' public:\\'] +
3279 (['\\'] * 100) + # Makes E > 100 lines
3280 [' int non_empty_line;\\',
3281 ' private:\\', # no warning
3282 ' int a;\\',
erg@google.com8a95ecc2011-09-08 00:45:54 +00003283 '};'],
3284 error_collector)
3285 self.assertEquals(2, error_collector.Results().count(
3286 '"private:" should be preceded by a blank line'
3287 ' [whitespace/blank_line] [3]'))
3288 self.assertEquals(1, error_collector.Results().count(
3289 '"protected:" should be preceded by a blank line'
3290 ' [whitespace/blank_line] [3]'))
3291
3292 def testNoBlankLineAfterSectionKeyword(self):
3293 error_collector = ErrorCollector(self.assert_)
3294 cpplint.ProcessFileData('foo.cc', 'cc',
3295 ['class A {',
3296 ' public:',
3297 '', # warning 1
3298 ' private:',
3299 '', # warning 2
3300 ' struct B {',
3301 ' protected:',
3302 '', # warning 3
3303 ' };',
3304 '};'],
3305 error_collector)
3306 self.assertEquals(1, error_collector.Results().count(
3307 'Do not leave a blank line after "public:"'
3308 ' [whitespace/blank_line] [3]'))
3309 self.assertEquals(1, error_collector.Results().count(
3310 'Do not leave a blank line after "protected:"'
3311 ' [whitespace/blank_line] [3]'))
3312 self.assertEquals(1, error_collector.Results().count(
3313 'Do not leave a blank line after "private:"'
3314 ' [whitespace/blank_line] [3]'))
3315
avakulenko@google.com02af6282014-06-04 18:53:25 +00003316 def testAllowBlankLinesInRawStrings(self):
3317 error_collector = ErrorCollector(self.assert_)
3318 cpplint.ProcessFileData('foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003319 ['// Copyright 2014 Your Company.',
avakulenko@google.com02af6282014-06-04 18:53:25 +00003320 'static const char *kData[] = {R"(',
3321 '',
3322 ')", R"(',
3323 '',
3324 ')"};',
3325 ''],
3326 error_collector)
3327 self.assertEquals('', error_collector.Results())
3328
erg@google.com4e00b9a2009-01-12 23:05:11 +00003329 def testElseOnSameLineAsClosingBraces(self):
3330 error_collector = ErrorCollector(self.assert_)
3331 cpplint.ProcessFileData('foo.cc', 'cc',
3332 ['if (hoge) {',
avakulenko@google.com02af6282014-06-04 18:53:25 +00003333 '}',
3334 'else if (piyo) {', # Warning on this line
erg@google.com4e00b9a2009-01-12 23:05:11 +00003335 '}',
3336 ' else {' # Warning on this line
3337 '',
3338 '}'],
3339 error_collector)
avakulenko@google.com02af6282014-06-04 18:53:25 +00003340 self.assertEquals(2, error_collector.Results().count(
3341 'An else should appear on the same line as the preceding }'
3342 ' [whitespace/newline] [4]'))
3343
3344 error_collector = ErrorCollector(self.assert_)
3345 cpplint.ProcessFileData('foo.cc', 'cc',
3346 ['if (hoge) {',
3347 '',
3348 '}',
3349 'else', # Warning on this line
3350 '{',
3351 '',
3352 '}'],
3353 error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +00003354 self.assertEquals(1, error_collector.Results().count(
3355 'An else should appear on the same line as the preceding }'
3356 ' [whitespace/newline] [4]'))
3357
avakulenko@google.com02af6282014-06-04 18:53:25 +00003358 error_collector = ErrorCollector(self.assert_)
3359 cpplint.ProcessFileData('foo.cc', 'cc',
3360 ['if (hoge) {',
3361 '',
3362 '}',
3363 'else_function();'],
3364 error_collector)
3365 self.assertEquals(0, error_collector.Results().count(
3366 'An else should appear on the same line as the preceding }'
3367 ' [whitespace/newline] [4]'))
3368
erg@google.comd350fe52013-01-14 17:51:48 +00003369 def testMultipleStatementsOnSameLine(self):
3370 error_collector = ErrorCollector(self.assert_)
3371 cpplint.ProcessFileData('foo.cc', 'cc',
3372 ['for (int i = 0; i < 1; i++) {}',
3373 'switch (x) {',
3374 ' case 0: func(); break; ',
3375 '}',
3376 'sum += MathUtil::SafeIntRound(x); x += 0.1;'],
3377 error_collector)
3378 self.assertEquals(0, error_collector.Results().count(
3379 'More than one command on the same line [whitespace/newline] [0]'))
3380
3381 old_verbose_level = cpplint._cpplint_state.verbose_level
3382 cpplint._cpplint_state.verbose_level = 0
3383 cpplint.ProcessFileData('foo.cc', 'cc',
3384 ['sum += MathUtil::SafeIntRound(x); x += 0.1;'],
3385 error_collector)
3386 cpplint._cpplint_state.verbose_level = old_verbose_level
3387
3388 def testEndOfNamespaceComments(self):
3389 error_collector = ErrorCollector(self.assert_)
3390 cpplint.ProcessFileData('foo.cc', 'cc',
3391 ['namespace {',
3392 '',
3393 '}', # No warning (too short)
3394 'namespace expected {',
3395 '} // namespace mismatched', # Warning here
3396 'namespace {',
3397 '} // namespace mismatched', # Warning here
3398 'namespace outer { namespace nested {'] +
3399 ([''] * 10) +
3400 ['}', # Warning here
3401 '}', # Warning here
3402 'namespace {'] +
3403 ([''] * 10) +
3404 ['}', # Warning here
3405 'namespace {'] +
3406 ([''] * 10) +
avakulenko@google.com02af6282014-06-04 18:53:25 +00003407 ['} // namespace some description', # Anon warning
3408 'namespace {'] +
3409 ([''] * 10) +
3410 ['} // namespace anonymous', # Variant warning
3411 'namespace {'] +
3412 ([''] * 10) +
3413 ['} // anonymous namespace (utils)', # Variant
3414 'namespace {'] +
3415 ([''] * 10) +
3416 ['} // anonymous namespace', # No warning
erg@google.comd350fe52013-01-14 17:51:48 +00003417 'namespace missing_comment {'] +
3418 ([''] * 10) +
3419 ['}', # Warning here
3420 'namespace no_warning {'] +
3421 ([''] * 10) +
3422 ['} // namespace no_warning',
3423 'namespace no_warning {'] +
3424 ([''] * 10) +
3425 ['}; // end namespace no_warning',
3426 '#define MACRO \\',
3427 'namespace c_style { \\'] +
3428 (['\\'] * 10) +
3429 ['} /* namespace c_style. */ \\',
3430 ';'],
3431 error_collector)
3432 self.assertEquals(1, error_collector.Results().count(
3433 'Namespace should be terminated with "// namespace expected"'
3434 ' [readability/namespace] [5]'))
3435 self.assertEquals(1, error_collector.Results().count(
3436 'Namespace should be terminated with "// namespace outer"'
3437 ' [readability/namespace] [5]'))
3438 self.assertEquals(1, error_collector.Results().count(
3439 'Namespace should be terminated with "// namespace nested"'
3440 ' [readability/namespace] [5]'))
3441 self.assertEquals(3, error_collector.Results().count(
avakulenko@google.com02af6282014-06-04 18:53:25 +00003442 'Anonymous namespace should be terminated with "// namespace"'
3443 ' [readability/namespace] [5]'))
3444 self.assertEquals(2, error_collector.Results().count(
3445 'Anonymous namespace should be terminated with "// namespace" or'
3446 ' "// anonymous namespace"'
erg@google.comd350fe52013-01-14 17:51:48 +00003447 ' [readability/namespace] [5]'))
3448 self.assertEquals(1, error_collector.Results().count(
3449 'Namespace should be terminated with "// namespace missing_comment"'
3450 ' [readability/namespace] [5]'))
3451 self.assertEquals(0, error_collector.Results().count(
3452 'Namespace should be terminated with "// namespace no_warning"'
3453 ' [readability/namespace] [5]'))
3454
erg@google.com4e00b9a2009-01-12 23:05:11 +00003455 def testElseClauseNotOnSameLineAsElse(self):
3456 self.TestLint(' else DoSomethingElse();',
3457 'Else clause should never be on same line as else '
3458 '(use 2 lines) [whitespace/newline] [4]')
3459 self.TestLint(' else ifDoSomethingElse();',
3460 'Else clause should never be on same line as else '
3461 '(use 2 lines) [whitespace/newline] [4]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003462 self.TestLint(' } else if (blah) {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003463 self.TestLint(' variable_ends_in_else = true;', '')
3464
3465 def testComma(self):
3466 self.TestLint('a = f(1,2);',
3467 'Missing space after , [whitespace/comma] [3]')
3468 self.TestLint('int tmp=a,a=b,b=tmp;',
3469 ['Missing spaces around = [whitespace/operators] [4]',
3470 'Missing space after , [whitespace/comma] [3]'])
3471 self.TestLint('f(a, /* name */ b);', '')
3472 self.TestLint('f(a, /* name */b);', '')
erg@google.com2aa59982013-10-28 19:09:25 +00003473 self.TestLint('f(a, /* name */-1);', '')
3474 self.TestLint('f(a, /* name */"1");', '')
erg@google.comc6671232013-10-25 21:44:03 +00003475 self.TestLint('f(1, /* empty macro arg */, 2)', '')
3476 self.TestLint('f(1,, 2)', '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003477 self.TestLint('operator,()', '')
3478 self.TestLint('operator,(a,b)',
3479 'Missing space after , [whitespace/comma] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003480
avakulenko@google.com554223d2014-12-04 22:00:20 +00003481 def testEqualsOperatorSpacing(self):
3482 self.TestLint('int tmp= a;',
3483 'Missing spaces around = [whitespace/operators] [4]')
3484 self.TestLint('int tmp =a;',
3485 'Missing spaces around = [whitespace/operators] [4]')
3486 self.TestLint('int tmp=a;',
3487 'Missing spaces around = [whitespace/operators] [4]')
3488 self.TestLint('int tmp= 7;',
3489 'Missing spaces around = [whitespace/operators] [4]')
3490 self.TestLint('int tmp =7;',
3491 'Missing spaces around = [whitespace/operators] [4]')
3492 self.TestLint('int tmp=7;',
3493 'Missing spaces around = [whitespace/operators] [4]')
3494 self.TestLint('int* tmp=*p;',
3495 'Missing spaces around = [whitespace/operators] [4]')
3496 self.TestLint('int* tmp= *p;',
3497 'Missing spaces around = [whitespace/operators] [4]')
3498 self.TestMultiLineLint(
3499 TrimExtraIndent('''
3500 lookahead_services_=
3501 ::strings::Split(FLAGS_ls, ",", ::strings::SkipEmpty());'''),
3502 'Missing spaces around = [whitespace/operators] [4]')
3503 self.TestLint('bool result = a>=42;',
3504 'Missing spaces around >= [whitespace/operators] [3]')
3505 self.TestLint('bool result = a<=42;',
3506 'Missing spaces around <= [whitespace/operators] [3]')
3507 self.TestLint('bool result = a==42;',
3508 'Missing spaces around == [whitespace/operators] [3]')
3509 self.TestLint('auto result = a!=42;',
3510 'Missing spaces around != [whitespace/operators] [3]')
3511 self.TestLint('int a = b!=c;',
3512 'Missing spaces around != [whitespace/operators] [3]')
3513 self.TestLint('a&=42;', '')
3514 self.TestLint('a|=42;', '')
3515 self.TestLint('a^=42;', '')
3516 self.TestLint('a+=42;', '')
3517 self.TestLint('a*=42;', '')
3518 self.TestLint('a/=42;', '')
3519 self.TestLint('a%=42;', '')
3520 self.TestLint('a>>=5;', '')
3521 self.TestLint('a<<=5;', '')
3522
3523 def testShiftOperatorSpacing(self):
3524 self.TestLint('a<<b',
3525 'Missing spaces around << [whitespace/operators] [3]')
3526 self.TestLint('a>>b',
3527 'Missing spaces around >> [whitespace/operators] [3]')
3528 self.TestLint('1<<20', '')
3529 self.TestLint('1024>>10', '')
3530 self.TestLint('Kernel<<<1, 2>>>()', '')
3531
erg@google.com4e00b9a2009-01-12 23:05:11 +00003532 def testIndent(self):
3533 self.TestLint('static int noindent;', '')
3534 self.TestLint(' int two_space_indent;', '')
3535 self.TestLint(' int four_space_indent;', '')
3536 self.TestLint(' int one_space_indent;',
3537 'Weird number of spaces at line-start. '
3538 'Are you using a 2-space indent? [whitespace/indent] [3]')
3539 self.TestLint(' int three_space_indent;',
3540 'Weird number of spaces at line-start. '
3541 'Are you using a 2-space indent? [whitespace/indent] [3]')
3542 self.TestLint(' char* one_space_indent = "public:";',
3543 'Weird number of spaces at line-start. '
3544 'Are you using a 2-space indent? [whitespace/indent] [3]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003545 self.TestLint(' public:', '')
3546 self.TestLint(' protected:', '')
3547 self.TestLint(' private:', '')
3548 self.TestLint(' protected: \\', '')
3549 self.TestLint(' public: \\', '')
3550 self.TestLint(' private: \\', '')
3551 self.TestMultiLineLint(
3552 TrimExtraIndent("""
3553 class foo {
3554 public slots:
3555 void bar();
3556 };"""),
3557 'Weird number of spaces at line-start. '
3558 'Are you using a 2-space indent? [whitespace/indent] [3]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003559 self.TestMultiLineLint(
3560 TrimExtraIndent('''
3561 static const char kRawString[] = R"("
3562 ")";'''),
3563 '')
3564 self.TestMultiLineLint(
3565 TrimExtraIndent('''
Alex Vakulenko01e47232016-05-06 13:54:15 -07003566 KV<Query,
3567 Tuple<TaxonomyId, PetacatCategoryId, double>>'''),
3568 '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003569 self.TestMultiLineLint(
3570 ' static const char kSingleLineRawString[] = R"(...)";',
3571 'Weird number of spaces at line-start. '
3572 'Are you using a 2-space indent? [whitespace/indent] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003573
erg@google.comfd5da632013-10-25 17:39:45 +00003574 def testSectionIndent(self):
3575 self.TestMultiLineLint(
3576 """
3577 class A {
3578 public: // no warning
3579 private: // warning here
3580 };""",
3581 'private: should be indented +1 space inside class A'
3582 ' [whitespace/indent] [3]')
3583 self.TestMultiLineLint(
3584 """
3585 class B {
3586 public: // no warning
3587 template<> struct C {
3588 public: // warning here
3589 protected: // no warning
3590 };
3591 };""",
3592 'public: should be indented +1 space inside struct C'
3593 ' [whitespace/indent] [3]')
3594 self.TestMultiLineLint(
3595 """
3596 struct D {
3597 };""",
3598 'Closing brace should be aligned with beginning of struct D'
3599 ' [whitespace/indent] [3]')
3600 self.TestMultiLineLint(
3601 """
3602 template<typename E> class F {
3603 };""",
3604 'Closing brace should be aligned with beginning of class F'
3605 ' [whitespace/indent] [3]')
3606 self.TestMultiLineLint(
3607 """
3608 class G {
3609 Q_OBJECT
3610 public slots:
3611 signals:
3612 };""",
3613 ['public slots: should be indented +1 space inside class G'
3614 ' [whitespace/indent] [3]',
3615 'signals: should be indented +1 space inside class G'
3616 ' [whitespace/indent] [3]'])
3617 self.TestMultiLineLint(
3618 """
3619 class H {
3620 /* comments */ class I {
3621 public: // no warning
3622 private: // warning here
3623 };
3624 };""",
3625 'private: should be indented +1 space inside class I'
3626 ' [whitespace/indent] [3]')
3627 self.TestMultiLineLint(
3628 """
3629 class J
3630 : public ::K {
3631 public: // no warning
3632 protected: // warning here
3633 };""",
3634 'protected: should be indented +1 space inside class J'
3635 ' [whitespace/indent] [3]')
3636 self.TestMultiLineLint(
3637 """
3638 class L
3639 : public M,
3640 public ::N {
3641 };""",
3642 '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003643 self.TestMultiLineLint(
3644 """
3645 template <class O,
3646 class P,
3647 class Q,
3648 typename R>
3649 static void Func() {
3650 }""",
3651 '')
3652
3653 def testConditionals(self):
3654 self.TestMultiLineLint(
3655 """
3656 if (foo)
3657 goto fail;
3658 goto fail;""",
3659 'If/else bodies with multiple statements require braces'
3660 ' [readability/braces] [4]')
3661 self.TestMultiLineLint(
3662 """
3663 if (foo)
3664 goto fail; goto fail;""",
3665 'If/else bodies with multiple statements require braces'
3666 ' [readability/braces] [4]')
3667 self.TestMultiLineLint(
3668 """
3669 if (foo)
3670 foo;
3671 else
3672 goto fail;
3673 goto fail;""",
3674 'If/else bodies with multiple statements require braces'
3675 ' [readability/braces] [4]')
3676 self.TestMultiLineLint(
3677 """
3678 if (foo) goto fail;
3679 goto fail;""",
3680 'If/else bodies with multiple statements require braces'
3681 ' [readability/braces] [4]')
3682 self.TestMultiLineLint(
3683 """
3684 if (foo)
3685 if (bar)
3686 baz;
3687 else
3688 qux;""",
3689 'Else clause should be indented at the same level as if. Ambiguous'
3690 ' nested if/else chains require braces. [readability/braces] [4]')
3691 self.TestMultiLineLint(
3692 """
3693 if (foo)
3694 if (bar)
3695 baz;
3696 else
3697 qux;""",
3698 'Else clause should be indented at the same level as if. Ambiguous'
3699 ' nested if/else chains require braces. [readability/braces] [4]')
3700 self.TestMultiLineLint(
3701 """
3702 if (foo) {
3703 bar;
3704 baz;
3705 } else
3706 qux;""",
3707 'If an else has a brace on one side, it should have it on both'
3708 ' [readability/braces] [5]')
3709 self.TestMultiLineLint(
3710 """
3711 if (foo)
3712 bar;
3713 else {
3714 baz;
3715 }""",
3716 'If an else has a brace on one side, it should have it on both'
3717 ' [readability/braces] [5]')
3718 self.TestMultiLineLint(
3719 """
3720 if (foo)
3721 bar;
3722 else if (baz) {
3723 qux;
3724 }""",
3725 'If an else has a brace on one side, it should have it on both'
3726 ' [readability/braces] [5]')
3727 self.TestMultiLineLint(
3728 """
3729 if (foo) {
3730 bar;
3731 } else if (baz)
3732 qux;""",
3733 'If an else has a brace on one side, it should have it on both'
3734 ' [readability/braces] [5]')
3735 self.TestMultiLineLint(
3736 """
3737 if (foo)
3738 goto fail;
3739 bar;""",
3740 '')
3741 self.TestMultiLineLint(
3742 """
3743 if (foo
3744 && bar) {
3745 baz;
3746 qux;
3747 }""",
3748 '')
3749 self.TestMultiLineLint(
3750 """
3751 if (foo)
3752 goto
3753 fail;""",
3754 '')
3755 self.TestMultiLineLint(
3756 """
3757 if (foo)
3758 bar;
3759 else
3760 baz;
3761 qux;""",
3762 '')
3763 self.TestMultiLineLint(
3764 """
3765 for (;;) {
3766 if (foo)
3767 bar;
3768 else
3769 baz;
3770 }""",
3771 '')
3772 self.TestMultiLineLint(
3773 """
3774 if (foo)
3775 bar;
3776 else if (baz)
3777 baz;""",
3778 '')
3779 self.TestMultiLineLint(
3780 """
3781 if (foo)
3782 bar;
3783 else
3784 baz;""",
3785 '')
3786 self.TestMultiLineLint(
3787 """
3788 if (foo) {
3789 bar;
3790 } else {
3791 baz;
3792 }""",
3793 '')
3794 self.TestMultiLineLint(
3795 """
3796 if (foo) {
3797 bar;
3798 } else if (baz) {
3799 qux;
3800 }""",
3801 '')
3802 # Note: this is an error for a different reason, but should not trigger the
3803 # single-line if error.
3804 self.TestMultiLineLint(
3805 """
3806 if (foo)
3807 {
3808 bar;
3809 baz;
3810 }""",
3811 '{ should almost always be at the end of the previous line'
3812 ' [whitespace/braces] [4]')
3813 self.TestMultiLineLint(
3814 """
3815 if (foo) { \\
3816 bar; \\
3817 baz; \\
3818 }""",
3819 '')
3820 self.TestMultiLineLint(
3821 """
3822 void foo() { if (bar) baz; }""",
3823 '')
3824 self.TestMultiLineLint(
3825 """
3826 #if foo
3827 bar;
3828 #else
3829 baz;
3830 qux;
Elliot Glaysherae118112016-09-30 15:34:26 -07003831 #endif""",
avakulenko@google.com02af6282014-06-04 18:53:25 +00003832 '')
avakulenko@google.com554223d2014-12-04 22:00:20 +00003833 self.TestMultiLineLint(
3834 """void F() {
3835 variable = [] { if (true); };
3836 variable =
3837 [] { if (true); };
3838 Call(
3839 [] { if (true); },
3840 [] { if (true); });
3841 }""",
3842 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003843
3844 def testTab(self):
3845 self.TestLint('\tint a;',
3846 'Tab found; better to use spaces [whitespace/tab] [1]')
3847 self.TestLint('int a = 5;\t\t// set a to 5',
3848 'Tab found; better to use spaces [whitespace/tab] [1]')
3849
3850 def testParseArguments(self):
3851 old_usage = cpplint._USAGE
3852 old_error_categories = cpplint._ERROR_CATEGORIES
3853 old_output_format = cpplint._cpplint_state.output_format
3854 old_verbose_level = cpplint._cpplint_state.verbose_level
LukeCz8920b132016-09-26 19:40:47 -05003855 old_headers = cpplint._hpp_headers
erg@google.com4e00b9a2009-01-12 23:05:11 +00003856 old_filters = cpplint._cpplint_state.filters
erg@google.comab53edf2013-11-05 22:23:37 +00003857 old_line_length = cpplint._line_length
erg@google.com19680272013-12-16 22:48:54 +00003858 old_valid_extensions = cpplint._valid_extensions
erg@google.com4e00b9a2009-01-12 23:05:11 +00003859 try:
3860 # Don't print usage during the tests, or filter categories
3861 cpplint._USAGE = ''
3862 cpplint._ERROR_CATEGORIES = ''
3863
3864 self.assertRaises(SystemExit, cpplint.ParseArguments, [])
3865 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--badopt'])
3866 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--help'])
3867 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--v=0'])
3868 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter='])
3869 # This is illegal because all filters must start with + or -
3870 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter=foo'])
3871 self.assertRaises(SystemExit, cpplint.ParseArguments,
3872 ['--filter=+a,b,-c'])
LukeCz8920b132016-09-26 19:40:47 -05003873 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--headers'])
erg@google.com4e00b9a2009-01-12 23:05:11 +00003874
3875 self.assertEquals(['foo.cc'], cpplint.ParseArguments(['foo.cc']))
3876 self.assertEquals(old_output_format, cpplint._cpplint_state.output_format)
3877 self.assertEquals(old_verbose_level, cpplint._cpplint_state.verbose_level)
3878
3879 self.assertEquals(['foo.cc'],
3880 cpplint.ParseArguments(['--v=1', 'foo.cc']))
3881 self.assertEquals(1, cpplint._cpplint_state.verbose_level)
3882 self.assertEquals(['foo.h'],
3883 cpplint.ParseArguments(['--v=3', 'foo.h']))
3884 self.assertEquals(3, cpplint._cpplint_state.verbose_level)
3885 self.assertEquals(['foo.cpp'],
3886 cpplint.ParseArguments(['--verbose=5', 'foo.cpp']))
3887 self.assertEquals(5, cpplint._cpplint_state.verbose_level)
3888 self.assertRaises(ValueError,
3889 cpplint.ParseArguments, ['--v=f', 'foo.cc'])
3890
3891 self.assertEquals(['foo.cc'],
3892 cpplint.ParseArguments(['--output=emacs', 'foo.cc']))
3893 self.assertEquals('emacs', cpplint._cpplint_state.output_format)
3894 self.assertEquals(['foo.h'],
3895 cpplint.ParseArguments(['--output=vs7', 'foo.h']))
3896 self.assertEquals('vs7', cpplint._cpplint_state.output_format)
3897 self.assertRaises(SystemExit,
3898 cpplint.ParseArguments, ['--output=blah', 'foo.cc'])
3899
3900 filt = '-,+whitespace,-whitespace/indent'
3901 self.assertEquals(['foo.h'],
3902 cpplint.ParseArguments(['--filter='+filt, 'foo.h']))
3903 self.assertEquals(['-', '+whitespace', '-whitespace/indent'],
3904 cpplint._cpplint_state.filters)
3905
3906 self.assertEquals(['foo.cc', 'foo.h'],
3907 cpplint.ParseArguments(['foo.cc', 'foo.h']))
erg@google.comab53edf2013-11-05 22:23:37 +00003908
3909 self.assertEqual(['foo.h'],
3910 cpplint.ParseArguments(['--linelength=120', 'foo.h']))
3911 self.assertEqual(120, cpplint._line_length)
erg@google.com19680272013-12-16 22:48:54 +00003912
3913 self.assertEqual(['foo.h'],
3914 cpplint.ParseArguments(['--extensions=hpp,cpp,cpp', 'foo.h']))
3915 self.assertEqual(set(['hpp', 'cpp']), cpplint._valid_extensions)
LukeCz8920b132016-09-26 19:40:47 -05003916
3917 self.assertEqual(set(['h']), cpplint._hpp_headers) # Default value
3918 self.assertEqual(['foo.h'],
3919 cpplint.ParseArguments(['--extensions=cpp,cpp', '--headers=hpp,h', 'foo.h']))
3920 self.assertEqual(set(['hpp', 'h']), cpplint._hpp_headers)
3921 self.assertEqual(set(['hpp', 'h', 'cpp']), cpplint._valid_extensions)
3922
erg@google.com4e00b9a2009-01-12 23:05:11 +00003923 finally:
3924 cpplint._USAGE = old_usage
3925 cpplint._ERROR_CATEGORIES = old_error_categories
3926 cpplint._cpplint_state.output_format = old_output_format
3927 cpplint._cpplint_state.verbose_level = old_verbose_level
3928 cpplint._cpplint_state.filters = old_filters
erg@google.comab53edf2013-11-05 22:23:37 +00003929 cpplint._line_length = old_line_length
erg@google.com19680272013-12-16 22:48:54 +00003930 cpplint._valid_extensions = old_valid_extensions
LukeCz8920b132016-09-26 19:40:47 -05003931 cpplint._hpp_headers = old_headers
erg@google.comab53edf2013-11-05 22:23:37 +00003932
3933 def testLineLength(self):
3934 old_line_length = cpplint._line_length
3935 try:
3936 cpplint._line_length = 80
3937 self.TestLint(
Alex Vakulenko01e47232016-05-06 13:54:15 -07003938 '// H %s' % ('H' * 75),
erg@google.comab53edf2013-11-05 22:23:37 +00003939 '')
3940 self.TestLint(
Alex Vakulenko01e47232016-05-06 13:54:15 -07003941 '// H %s' % ('H' * 76),
erg@google.comab53edf2013-11-05 22:23:37 +00003942 'Lines should be <= 80 characters long'
3943 ' [whitespace/line_length] [2]')
3944 cpplint._line_length = 120
3945 self.TestLint(
Alex Vakulenko01e47232016-05-06 13:54:15 -07003946 '// H %s' % ('H' * 115),
erg@google.comab53edf2013-11-05 22:23:37 +00003947 '')
3948 self.TestLint(
Alex Vakulenko01e47232016-05-06 13:54:15 -07003949 '// H %s' % ('H' * 116),
erg@google.comab53edf2013-11-05 22:23:37 +00003950 'Lines should be <= 120 characters long'
3951 ' [whitespace/line_length] [2]')
3952 finally:
3953 cpplint._line_length = old_line_length
erg@google.com4e00b9a2009-01-12 23:05:11 +00003954
3955 def testFilter(self):
3956 old_filters = cpplint._cpplint_state.filters
3957 try:
3958 cpplint._cpplint_state.SetFilters('-,+whitespace,-whitespace/indent')
3959 self.TestLint(
3960 '// Hello there ',
3961 'Line ends in whitespace. Consider deleting these extra spaces.'
3962 ' [whitespace/end_of_line] [4]')
3963 self.TestLint('int a = (int)1.0;', '')
3964 self.TestLint(' weird opening space', '')
3965 finally:
3966 cpplint._cpplint_state.filters = old_filters
3967
erg@google.come35f7652009-06-19 20:52:09 +00003968 def testDefaultFilter(self):
3969 default_filters = cpplint._DEFAULT_FILTERS
3970 old_filters = cpplint._cpplint_state.filters
erg@google.com8a95ecc2011-09-08 00:45:54 +00003971 cpplint._DEFAULT_FILTERS = ['-whitespace']
erg@google.come35f7652009-06-19 20:52:09 +00003972 try:
3973 # Reset filters
3974 cpplint._cpplint_state.SetFilters('')
3975 self.TestLint('// Hello there ', '')
3976 cpplint._cpplint_state.SetFilters('+whitespace/end_of_line')
3977 self.TestLint(
3978 '// Hello there ',
3979 'Line ends in whitespace. Consider deleting these extra spaces.'
3980 ' [whitespace/end_of_line] [4]')
3981 self.TestLint(' weird opening space', '')
3982 finally:
3983 cpplint._cpplint_state.filters = old_filters
3984 cpplint._DEFAULT_FILTERS = default_filters
3985
avakulenko@google.com554223d2014-12-04 22:00:20 +00003986 def testDuplicateHeader(self):
3987 error_collector = ErrorCollector(self.assert_)
3988 cpplint.ProcessFileData('path/self.cc', 'cc',
3989 ['// Copyright 2014 Your Company. All Rights Reserved.',
3990 '#include "path/self.h"',
3991 '#include "path/duplicate.h"',
3992 '#include "path/duplicate.h"',
3993 '#ifdef MACRO',
3994 '#include "path/unique.h"',
3995 '#else',
3996 '#include "path/unique.h"',
Elliot Glaysherae118112016-09-30 15:34:26 -07003997 '#endif',
avakulenko@google.com554223d2014-12-04 22:00:20 +00003998 ''],
3999 error_collector)
4000 self.assertEquals(
4001 ['"path/duplicate.h" already included at path/self.cc:3 '
4002 '[build/include] [4]'],
4003 error_collector.ResultList())
4004
erg@google.com4e00b9a2009-01-12 23:05:11 +00004005 def testUnnamedNamespacesInHeaders(self):
4006 self.TestLanguageRulesCheck(
4007 'foo.h', 'namespace {',
4008 'Do not use unnamed namespaces in header files. See'
Ackermann Yuriy79692902016-04-01 21:41:34 +13004009 ' https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
erg@google.com4e00b9a2009-01-12 23:05:11 +00004010 ' for more information. [build/namespaces] [4]')
4011 # namespace registration macros are OK.
4012 self.TestLanguageRulesCheck('foo.h', 'namespace { \\', '')
4013 # named namespaces are OK.
4014 self.TestLanguageRulesCheck('foo.h', 'namespace foo {', '')
4015 self.TestLanguageRulesCheck('foo.h', 'namespace foonamespace {', '')
4016 self.TestLanguageRulesCheck('foo.cc', 'namespace {', '')
4017 self.TestLanguageRulesCheck('foo.cc', 'namespace foo {', '')
4018
4019 def testBuildClass(self):
4020 # Test that the linter can parse to the end of class definitions,
4021 # and that it will report when it can't.
4022 # Use multi-line linter because it performs the ClassState check.
4023 self.TestMultiLineLint(
4024 'class Foo {',
4025 'Failed to find complete declaration of class Foo'
4026 ' [build/class] [5]')
erg@google.com2aa59982013-10-28 19:09:25 +00004027 # Do the same for namespaces
4028 self.TestMultiLineLint(
4029 'namespace Foo {',
4030 'Failed to find complete declaration of namespace Foo'
4031 ' [build/namespaces] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004032 # Don't warn on forward declarations of various types.
4033 self.TestMultiLineLint(
4034 'class Foo;',
4035 '')
4036 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00004037 """struct Foo*
4038 foo = NewFoo();""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00004039 '')
erg@google.comd350fe52013-01-14 17:51:48 +00004040 # Test preprocessor.
4041 self.TestMultiLineLint(
4042 """#ifdef DERIVE_FROM_GOO
4043 struct Foo : public Goo {
4044 #else
4045 struct Foo : public Hoo {
Elliot Glaysherae118112016-09-30 15:34:26 -07004046 #endif
erg@google.comd350fe52013-01-14 17:51:48 +00004047 };""",
4048 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004049 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00004050 """
4051 class Foo
erg@google.com4e00b9a2009-01-12 23:05:11 +00004052 #ifdef DERIVE_FROM_GOO
4053 : public Goo {
4054 #else
4055 : public Hoo {
Elliot Glaysherae118112016-09-30 15:34:26 -07004056 #endif
erg@google.comfd5da632013-10-25 17:39:45 +00004057 };""",
erg@google.comd350fe52013-01-14 17:51:48 +00004058 '')
4059 # Test incomplete class
4060 self.TestMultiLineLint(
4061 'class Foo {',
erg@google.com4e00b9a2009-01-12 23:05:11 +00004062 'Failed to find complete declaration of class Foo'
4063 ' [build/class] [5]')
4064
4065 def testBuildEndComment(self):
4066 # The crosstool compiler we currently use will fail to compile the
4067 # code in this test, so we might consider removing the lint check.
erg@google.comd350fe52013-01-14 17:51:48 +00004068 self.TestMultiLineLint(
4069 """#if 0
4070 #endif Not a comment""",
4071 'Uncommented text after #endif is non-standard. Use a comment.'
4072 ' [build/endif_comment] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004073
4074 def testBuildForwardDecl(self):
4075 # The crosstool compiler we currently use will fail to compile the
4076 # code in this test, so we might consider removing the lint check.
4077 self.TestLint('class Foo::Goo;',
4078 'Inner-style forward declarations are invalid.'
4079 ' Remove this line.'
4080 ' [build/forward_decl] [5]')
4081
avakulenko@google.com554223d2014-12-04 22:00:20 +00004082 def GetBuildHeaderGuardPreprocessorSymbol(self, file_path):
4083 # Figure out the expected header guard by processing an empty file.
erg@google.com4e00b9a2009-01-12 23:05:11 +00004084 error_collector = ErrorCollector(self.assert_)
4085 cpplint.ProcessFileData(file_path, 'h', [], error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004086 for error in error_collector.ResultList():
avakulenko@google.com554223d2014-12-04 22:00:20 +00004087 matched = re.search(
Alex Vakulenko01e47232016-05-06 13:54:15 -07004088 'No #ifndef header guard found, suggested CPP variable is: '
4089 '([A-Z0-9_]+)',
avakulenko@google.com554223d2014-12-04 22:00:20 +00004090 error)
4091 if matched is not None:
4092 return matched.group(1)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004093
avakulenko@google.com554223d2014-12-04 22:00:20 +00004094 def testBuildHeaderGuard(self):
4095 file_path = 'mydir/foo.h'
4096 expected_guard = self.GetBuildHeaderGuardPreprocessorSymbol(file_path)
4097 self.assertTrue(re.search('MYDIR_FOO_H_$', expected_guard))
4098
4099 # No guard at all: expect one error.
4100 error_collector = ErrorCollector(self.assert_)
4101 cpplint.ProcessFileData(file_path, 'h', [], error_collector)
4102 self.assertEquals(
4103 1,
4104 error_collector.ResultList().count(
4105 'No #ifndef header guard found, suggested CPP variable is: %s'
4106 ' [build/header_guard] [5]' % expected_guard),
4107 error_collector.ResultList())
erg@google.com4e00b9a2009-01-12 23:05:11 +00004108
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004109 # No header guard, but the error is suppressed.
4110 error_collector = ErrorCollector(self.assert_)
4111 cpplint.ProcessFileData(file_path, 'h',
4112 ['// Copyright 2014 Your Company.',
4113 '// NOLINT(build/header_guard)', ''],
4114 error_collector)
4115 self.assertEquals([], error_collector.ResultList())
4116
erg@google.com4e00b9a2009-01-12 23:05:11 +00004117 # Wrong guard
4118 error_collector = ErrorCollector(self.assert_)
4119 cpplint.ProcessFileData(file_path, 'h',
4120 ['#ifndef FOO_H', '#define FOO_H'], error_collector)
4121 self.assertEquals(
4122 1,
4123 error_collector.ResultList().count(
4124 '#ifndef header guard has wrong style, please use: %s'
4125 ' [build/header_guard] [5]' % expected_guard),
4126 error_collector.ResultList())
4127
4128 # No define
4129 error_collector = ErrorCollector(self.assert_)
4130 cpplint.ProcessFileData(file_path, 'h',
4131 ['#ifndef %s' % expected_guard], error_collector)
4132 self.assertEquals(
4133 1,
4134 error_collector.ResultList().count(
avakulenko@google.com554223d2014-12-04 22:00:20 +00004135 'No #ifndef header guard found, suggested CPP variable is: %s'
erg@google.com4e00b9a2009-01-12 23:05:11 +00004136 ' [build/header_guard] [5]' % expected_guard),
4137 error_collector.ResultList())
4138
4139 # Mismatched define
4140 error_collector = ErrorCollector(self.assert_)
4141 cpplint.ProcessFileData(file_path, 'h',
4142 ['#ifndef %s' % expected_guard,
4143 '#define FOO_H'],
4144 error_collector)
4145 self.assertEquals(
4146 1,
4147 error_collector.ResultList().count(
avakulenko@google.com554223d2014-12-04 22:00:20 +00004148 'No #ifndef header guard found, suggested CPP variable is: %s'
erg@google.com4e00b9a2009-01-12 23:05:11 +00004149 ' [build/header_guard] [5]' % expected_guard),
4150 error_collector.ResultList())
4151
4152 # No endif
4153 error_collector = ErrorCollector(self.assert_)
4154 cpplint.ProcessFileData(file_path, 'h',
4155 ['#ifndef %s' % expected_guard,
avakulenko@google.com554223d2014-12-04 22:00:20 +00004156 '#define %s' % expected_guard,
4157 ''],
erg@google.com4e00b9a2009-01-12 23:05:11 +00004158 error_collector)
4159 self.assertEquals(
4160 1,
4161 error_collector.ResultList().count(
4162 '#endif line should be "#endif // %s"'
4163 ' [build/header_guard] [5]' % expected_guard),
4164 error_collector.ResultList())
4165
4166 # Commentless endif
4167 error_collector = ErrorCollector(self.assert_)
4168 cpplint.ProcessFileData(file_path, 'h',
4169 ['#ifndef %s' % expected_guard,
4170 '#define %s' % expected_guard,
4171 '#endif'],
4172 error_collector)
4173 self.assertEquals(
4174 1,
4175 error_collector.ResultList().count(
4176 '#endif line should be "#endif // %s"'
4177 ' [build/header_guard] [5]' % expected_guard),
4178 error_collector.ResultList())
4179
4180 # Commentless endif for old-style guard
4181 error_collector = ErrorCollector(self.assert_)
4182 cpplint.ProcessFileData(file_path, 'h',
4183 ['#ifndef %s_' % expected_guard,
4184 '#define %s_' % expected_guard,
4185 '#endif'],
4186 error_collector)
4187 self.assertEquals(
4188 1,
4189 error_collector.ResultList().count(
4190 '#endif line should be "#endif // %s"'
4191 ' [build/header_guard] [5]' % expected_guard),
4192 error_collector.ResultList())
4193
4194 # No header guard errors
4195 error_collector = ErrorCollector(self.assert_)
4196 cpplint.ProcessFileData(file_path, 'h',
4197 ['#ifndef %s' % expected_guard,
4198 '#define %s' % expected_guard,
4199 '#endif // %s' % expected_guard],
4200 error_collector)
4201 for line in error_collector.ResultList():
4202 if line.find('build/header_guard') != -1:
4203 self.fail('Unexpected error: %s' % line)
4204
4205 # No header guard errors for old-style guard
4206 error_collector = ErrorCollector(self.assert_)
4207 cpplint.ProcessFileData(file_path, 'h',
4208 ['#ifndef %s_' % expected_guard,
4209 '#define %s_' % expected_guard,
4210 '#endif // %s_' % expected_guard],
4211 error_collector)
4212 for line in error_collector.ResultList():
4213 if line.find('build/header_guard') != -1:
4214 self.fail('Unexpected error: %s' % line)
4215
4216 old_verbose_level = cpplint._cpplint_state.verbose_level
4217 try:
4218 cpplint._cpplint_state.verbose_level = 0
4219 # Warn on old-style guard if verbosity is 0.
4220 error_collector = ErrorCollector(self.assert_)
4221 cpplint.ProcessFileData(file_path, 'h',
4222 ['#ifndef %s_' % expected_guard,
4223 '#define %s_' % expected_guard,
4224 '#endif // %s_' % expected_guard],
4225 error_collector)
4226 self.assertEquals(
4227 1,
4228 error_collector.ResultList().count(
4229 '#ifndef header guard has wrong style, please use: %s'
4230 ' [build/header_guard] [0]' % expected_guard),
4231 error_collector.ResultList())
4232 finally:
4233 cpplint._cpplint_state.verbose_level = old_verbose_level
4234
4235 # Completely incorrect header guard
4236 error_collector = ErrorCollector(self.assert_)
4237 cpplint.ProcessFileData(file_path, 'h',
4238 ['#ifndef FOO',
4239 '#define FOO',
4240 '#endif // FOO'],
4241 error_collector)
4242 self.assertEquals(
4243 1,
4244 error_collector.ResultList().count(
4245 '#ifndef header guard has wrong style, please use: %s'
4246 ' [build/header_guard] [5]' % expected_guard),
4247 error_collector.ResultList())
4248 self.assertEquals(
4249 1,
4250 error_collector.ResultList().count(
4251 '#endif line should be "#endif // %s"'
4252 ' [build/header_guard] [5]' % expected_guard),
4253 error_collector.ResultList())
4254
erg@google.coma868d2d2009-10-09 21:18:45 +00004255 # incorrect header guard with nolint
4256 error_collector = ErrorCollector(self.assert_)
4257 cpplint.ProcessFileData(file_path, 'h',
4258 ['#ifndef FOO // NOLINT',
4259 '#define FOO',
4260 '#endif // FOO NOLINT'],
4261 error_collector)
4262 self.assertEquals(
4263 0,
4264 error_collector.ResultList().count(
4265 '#ifndef header guard has wrong style, please use: %s'
4266 ' [build/header_guard] [5]' % expected_guard),
4267 error_collector.ResultList())
4268 self.assertEquals(
4269 0,
4270 error_collector.ResultList().count(
4271 '#endif line should be "#endif // %s"'
4272 ' [build/header_guard] [5]' % expected_guard),
4273 error_collector.ResultList())
4274
erg+personal@google.com05189642010-04-30 20:43:03 +00004275 # Special case for flymake
erg@google.comd350fe52013-01-14 17:51:48 +00004276 for test_file in ['mydir/foo_flymake.h', 'mydir/.flymake/foo.h']:
4277 error_collector = ErrorCollector(self.assert_)
avakulenko@google.com554223d2014-12-04 22:00:20 +00004278 cpplint.ProcessFileData(test_file, 'h',
4279 ['// Copyright 2014 Your Company.', ''],
4280 error_collector)
erg@google.comd350fe52013-01-14 17:51:48 +00004281 self.assertEquals(
4282 1,
4283 error_collector.ResultList().count(
4284 'No #ifndef header guard found, suggested CPP variable is: %s'
4285 ' [build/header_guard] [5]' % expected_guard),
4286 error_collector.ResultList())
erg@google.coma868d2d2009-10-09 21:18:45 +00004287
erg@google.com4d70a882013-04-16 21:06:32 +00004288 def testBuildHeaderGuardWithRoot(self):
4289 file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
4290 'cpplint_test_header.h')
4291 file_info = cpplint.FileInfo(file_path)
4292 if file_info.FullName() == file_info.RepositoryName():
4293 # When FileInfo cannot deduce the root directory of the repository,
4294 # FileInfo.RepositoryName returns the same value as FileInfo.FullName.
4295 # This can happen when this source file was obtained without .svn or
4296 # .git directory. (e.g. using 'svn export' or 'git archive').
4297 # Skip this test in such a case because --root flag makes sense only
4298 # when the root directory of the repository is properly deduced.
4299 return
4300
4301 self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_',
4302 cpplint.GetHeaderGuardCPPVariable(file_path))
4303 cpplint._root = 'cpplint'
4304 self.assertEquals('CPPLINT_TEST_HEADER_H_',
4305 cpplint.GetHeaderGuardCPPVariable(file_path))
4306 # --root flag is ignored if an non-existent directory is specified.
4307 cpplint._root = 'NON_EXISTENT_DIR'
4308 self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_',
4309 cpplint.GetHeaderGuardCPPVariable(file_path))
4310
erg@google.com4e00b9a2009-01-12 23:05:11 +00004311 def testBuildInclude(self):
4312 # Test that include statements have slashes in them.
4313 self.TestLint('#include "foo.h"',
4314 'Include the directory when naming .h files'
4315 ' [build/include] [4]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004316 self.TestLint('#include "Python.h"', '')
4317 self.TestLint('#include "lua.h"', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004318
4319 def testBuildPrintfFormat(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004320 error_collector = ErrorCollector(self.assert_)
4321 cpplint.ProcessFileData(
4322 'foo.cc', 'cc',
4323 [r'printf("\%%d", value);',
4324 r'snprintf(buffer, sizeof(buffer), "\[%d", value);',
4325 r'fprintf(file, "\(%d", value);',
4326 r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);'],
4327 error_collector)
4328 self.assertEquals(
4329 4,
4330 error_collector.Results().count(
4331 '%, [, (, and { are undefined character escapes. Unescape them.'
4332 ' [build/printf_format] [3]'))
erg@google.com4e00b9a2009-01-12 23:05:11 +00004333
avakulenko@google.com02af6282014-06-04 18:53:25 +00004334 error_collector = ErrorCollector(self.assert_)
4335 cpplint.ProcessFileData(
4336 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004337 ['// Copyright 2014 Your Company.',
avakulenko@google.com02af6282014-06-04 18:53:25 +00004338 r'printf("\\%%%d", value);',
4339 r'printf(R"(\[)");',
4340 r'printf(R"(\[%s)", R"(\])");',
4341 ''],
4342 error_collector)
4343 self.assertEquals('', error_collector.Results())
erg@google.com4e00b9a2009-01-12 23:05:11 +00004344
4345 def testRuntimePrintfFormat(self):
4346 self.TestLint(
4347 r'fprintf(file, "%q", value);',
4348 '%q in format strings is deprecated. Use %ll instead.'
4349 ' [runtime/printf_format] [3]')
4350
4351 self.TestLint(
4352 r'aprintf(file, "The number is %12q", value);',
4353 '%q in format strings is deprecated. Use %ll instead.'
4354 ' [runtime/printf_format] [3]')
4355
4356 self.TestLint(
4357 r'printf(file, "The number is" "%-12q", value);',
4358 '%q in format strings is deprecated. Use %ll instead.'
4359 ' [runtime/printf_format] [3]')
4360
4361 self.TestLint(
4362 r'printf(file, "The number is" "%+12q", value);',
4363 '%q in format strings is deprecated. Use %ll instead.'
4364 ' [runtime/printf_format] [3]')
4365
4366 self.TestLint(
4367 r'printf(file, "The number is" "% 12q", value);',
4368 '%q in format strings is deprecated. Use %ll instead.'
4369 ' [runtime/printf_format] [3]')
4370
4371 self.TestLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00004372 r'snprintf(file, "Never mix %d and %1$d parameters!", value);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00004373 '%N$ formats are unconventional. Try rewriting to avoid them.'
4374 ' [runtime/printf_format] [2]')
4375
4376 def TestLintLogCodeOnError(self, code, expected_message):
4377 # Special TestLint which logs the input code on error.
4378 result = self.PerformSingleLineLint(code)
4379 if result != expected_message:
4380 self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"'
4381 % (code, result, expected_message))
4382
4383 def testBuildStorageClass(self):
4384 qualifiers = [None, 'const', 'volatile']
4385 signs = [None, 'signed', 'unsigned']
4386 types = ['void', 'char', 'int', 'float', 'double',
4387 'schar', 'int8', 'uint8', 'int16', 'uint16',
4388 'int32', 'uint32', 'int64', 'uint64']
erg@google.comd350fe52013-01-14 17:51:48 +00004389 storage_classes = ['extern', 'register', 'static', 'typedef']
erg@google.com4e00b9a2009-01-12 23:05:11 +00004390
4391 build_storage_class_error_message = (
Alex Vakulenko01e47232016-05-06 13:54:15 -07004392 'Storage-class specifier (static, extern, typedef, etc) should be '
4393 'at the beginning of the declaration. [build/storage_class] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004394
4395 # Some explicit cases. Legal in C++, deprecated in C99.
4396 self.TestLint('const int static foo = 5;',
4397 build_storage_class_error_message)
4398
4399 self.TestLint('char static foo;',
4400 build_storage_class_error_message)
4401
4402 self.TestLint('double const static foo = 2.0;',
4403 build_storage_class_error_message)
4404
4405 self.TestLint('uint64 typedef unsigned_long_long;',
4406 build_storage_class_error_message)
4407
4408 self.TestLint('int register foo = 0;',
4409 build_storage_class_error_message)
4410
4411 # Since there are a very large number of possibilities, randomly
4412 # construct declarations.
4413 # Make sure that the declaration is logged if there's an error.
4414 # Seed generator with an integer for absolute reproducibility.
4415 random.seed(25)
4416 for unused_i in range(10):
4417 # Build up random list of non-storage-class declaration specs.
4418 other_decl_specs = [random.choice(qualifiers), random.choice(signs),
4419 random.choice(types)]
4420 # remove None
erg@google.comc6671232013-10-25 21:44:03 +00004421 other_decl_specs = [x for x in other_decl_specs if x is not None]
erg@google.com4e00b9a2009-01-12 23:05:11 +00004422
4423 # shuffle
4424 random.shuffle(other_decl_specs)
4425
4426 # insert storage class after the first
4427 storage_class = random.choice(storage_classes)
4428 insertion_point = random.randint(1, len(other_decl_specs))
4429 decl_specs = (other_decl_specs[0:insertion_point]
4430 + [storage_class]
4431 + other_decl_specs[insertion_point:])
4432
4433 self.TestLintLogCodeOnError(
4434 ' '.join(decl_specs) + ';',
4435 build_storage_class_error_message)
4436
4437 # but no error if storage class is first
4438 self.TestLintLogCodeOnError(
4439 storage_class + ' ' + ' '.join(other_decl_specs),
4440 '')
4441
4442 def testLegalCopyright(self):
4443 legal_copyright_message = (
4444 'No copyright message found. '
4445 'You should have a line: "Copyright [year] <Copyright Owner>"'
4446 ' [legal/copyright] [5]')
4447
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004448 copyright_line = '// Copyright 2014 Google Inc. All Rights Reserved.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00004449
4450 file_path = 'mydir/googleclient/foo.cc'
4451
4452 # There should be a copyright message in the first 10 lines
4453 error_collector = ErrorCollector(self.assert_)
4454 cpplint.ProcessFileData(file_path, 'cc', [], error_collector)
4455 self.assertEquals(
4456 1,
4457 error_collector.ResultList().count(legal_copyright_message))
4458
4459 error_collector = ErrorCollector(self.assert_)
4460 cpplint.ProcessFileData(
4461 file_path, 'cc',
4462 ['' for unused_i in range(10)] + [copyright_line],
4463 error_collector)
4464 self.assertEquals(
4465 1,
4466 error_collector.ResultList().count(legal_copyright_message))
4467
4468 # Test that warning isn't issued if Copyright line appears early enough.
4469 error_collector = ErrorCollector(self.assert_)
4470 cpplint.ProcessFileData(file_path, 'cc', [copyright_line], error_collector)
4471 for message in error_collector.ResultList():
4472 if message.find('legal/copyright') != -1:
4473 self.fail('Unexpected error: %s' % message)
4474
4475 error_collector = ErrorCollector(self.assert_)
4476 cpplint.ProcessFileData(
4477 file_path, 'cc',
4478 ['' for unused_i in range(9)] + [copyright_line],
4479 error_collector)
4480 for message in error_collector.ResultList():
4481 if message.find('legal/copyright') != -1:
4482 self.fail('Unexpected error: %s' % message)
4483
erg@google.com36649102009-03-25 21:18:36 +00004484 def testInvalidIncrement(self):
4485 self.TestLint('*count++;',
4486 'Changing pointer instead of value (or unused value of '
4487 'operator*). [runtime/invalid_increment] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004488
erg@google.comd350fe52013-01-14 17:51:48 +00004489 def testSnprintfSize(self):
4490 self.TestLint('vsnprintf(NULL, 0, format)', '')
4491 self.TestLint('snprintf(fisk, 1, format)',
4492 'If you can, use sizeof(fisk) instead of 1 as the 2nd arg '
4493 'to snprintf. [runtime/printf] [3]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00004494class Cxx11Test(CpplintTestBase):
4495
4496 def Helper(self, package, extension, lines, count):
4497 filename = package + '/foo.' + extension
4498 lines = lines[:]
4499
4500 # Header files need to have an ifdef guard wrapped around their code.
4501 if extension == 'h':
4502 guard = filename.upper().replace('/', '_').replace('.', '_') + '_'
4503 lines.insert(0, '#ifndef ' + guard)
4504 lines.insert(1, '#define ' + guard)
4505 lines.append('#endif // ' + guard)
4506
4507 # All files need a final blank line.
4508 lines.append('')
4509
4510 # Process the file and check resulting error count.
4511 collector = ErrorCollector(self.assert_)
4512 cpplint.ProcessFileData(filename, extension, lines, collector)
4513 error_list = collector.ResultList()
4514 self.assertEquals(count, len(error_list), error_list)
4515
4516 def TestCxx11Feature(self, code, expected_error):
4517 lines = code.split('\n')
4518 collector = ErrorCollector(self.assert_)
4519 cpplint.RemoveMultiLineComments('foo.h', lines, collector)
4520 clean_lines = cpplint.CleansedLines(lines)
4521 cpplint.FlagCxx11Features('foo.cc', clean_lines, 0, collector)
4522 self.assertEquals(expected_error, collector.Results())
4523
4524 def testBlockedHeaders(self):
Alex Vakulenko01e47232016-05-06 13:54:15 -07004525 self.TestCxx11Feature('#include <tr1/regex>',
4526 'C++ TR1 headers such as <tr1/regex> are '
4527 'unapproved. [build/c++tr1] [5]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00004528 self.TestCxx11Feature('#include <mutex>',
4529 '<mutex> is an unapproved C++11 header.'
4530 ' [build/c++11] [5]')
4531
4532 def testBlockedClasses(self):
4533 self.TestCxx11Feature('std::alignment_of<T>',
4534 'std::alignment_of is an unapproved '
4535 'C++11 class or function. Send c-style an example '
4536 'of where it would make your code more readable, '
4537 'and they may let you use it.'
4538 ' [build/c++11] [5]')
4539 self.TestCxx11Feature('std::alignment_offer', '')
4540 self.TestCxx11Feature('mystd::alignment_of', '')
4541 self.TestCxx11Feature('std::binomial_distribution', '')
4542
4543 def testBlockedFunctions(self):
4544 self.TestCxx11Feature('std::alignment_of<int>',
4545 'std::alignment_of is an unapproved '
4546 'C++11 class or function. Send c-style an example '
4547 'of where it would make your code more readable, '
4548 'and they may let you use it.'
4549 ' [build/c++11] [5]')
4550 # Missed because of the lack of "std::". Compiles because ADL
4551 # looks in the namespace of my_shared_ptr, which (presumably) is
4552 # std::. But there will be a lint error somewhere in this file
4553 # since my_shared_ptr had to be defined.
4554 self.TestCxx11Feature('static_pointer_cast<Base>(my_shared_ptr)', '')
4555 self.TestCxx11Feature('std::declval<T>()', '')
erg@google.comd350fe52013-01-14 17:51:48 +00004556
4557 def testExplicitMakePair(self):
4558 self.TestLint('make_pair', '')
4559 self.TestLint('make_pair(42, 42)', '')
4560 self.TestLint('make_pair<',
4561 'For C++11-compatibility, omit template arguments from'
4562 ' make_pair OR use pair directly OR if appropriate,'
4563 ' construct a pair directly'
4564 ' [build/explicit_make_pair] [4]')
4565 self.TestLint('make_pair <',
4566 'For C++11-compatibility, omit template arguments from'
4567 ' make_pair OR use pair directly OR if appropriate,'
4568 ' construct a pair directly'
4569 ' [build/explicit_make_pair] [4]')
4570 self.TestLint('my_make_pair<int, int>', '')
4571
Alex Vakulenko01e47232016-05-06 13:54:15 -07004572class Cxx14Test(CpplintTestBase):
4573
4574 def TestCxx14Feature(self, code, expected_error):
4575 lines = code.split('\n')
4576 collector = ErrorCollector(self.assert_)
4577 cpplint.RemoveMultiLineComments('foo.h', lines, collector)
4578 clean_lines = cpplint.CleansedLines(lines)
4579 cpplint.FlagCxx14Features('foo.cc', clean_lines, 0, collector)
4580 self.assertEquals(expected_error, collector.Results())
4581
4582 def testBlockedHeaders(self):
4583 self.TestCxx14Feature('#include <scoped_allocator>',
4584 '<scoped_allocator> is an unapproved C++14 header.'
4585 ' [build/c++14] [5]')
4586 self.TestCxx14Feature('#include <shared_mutex>',
4587 '<shared_mutex> is an unapproved C++14 header.'
4588 ' [build/c++14] [5]')
4589
4590
erg@google.com4e00b9a2009-01-12 23:05:11 +00004591class CleansedLinesTest(unittest.TestCase):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004592
erg@google.com4e00b9a2009-01-12 23:05:11 +00004593 def testInit(self):
4594 lines = ['Line 1',
4595 'Line 2',
4596 'Line 3 // Comment test',
erg@google.comd7d27472011-09-07 17:36:35 +00004597 'Line 4 /* Comment test */',
4598 'Line 5 "foo"']
4599
erg@google.com4e00b9a2009-01-12 23:05:11 +00004600 clean_lines = cpplint.CleansedLines(lines)
4601 self.assertEquals(lines, clean_lines.raw_lines)
erg@google.comd7d27472011-09-07 17:36:35 +00004602 self.assertEquals(5, clean_lines.NumLines())
erg@google.com4e00b9a2009-01-12 23:05:11 +00004603
4604 self.assertEquals(['Line 1',
4605 'Line 2',
erg@google.comd7d27472011-09-07 17:36:35 +00004606 'Line 3',
4607 'Line 4',
4608 'Line 5 "foo"'],
erg@google.com4e00b9a2009-01-12 23:05:11 +00004609 clean_lines.lines)
4610
4611 self.assertEquals(['Line 1',
4612 'Line 2',
erg@google.comd7d27472011-09-07 17:36:35 +00004613 'Line 3',
4614 'Line 4',
4615 'Line 5 ""'],
erg@google.com4e00b9a2009-01-12 23:05:11 +00004616 clean_lines.elided)
4617
4618 def testInitEmpty(self):
4619 clean_lines = cpplint.CleansedLines([])
4620 self.assertEquals([], clean_lines.raw_lines)
4621 self.assertEquals(0, clean_lines.NumLines())
4622
4623 def testCollapseStrings(self):
4624 collapse = cpplint.CleansedLines._CollapseStrings
4625 self.assertEquals('""', collapse('""')) # "" (empty)
4626 self.assertEquals('"""', collapse('"""')) # """ (bad)
4627 self.assertEquals('""', collapse('"xyz"')) # "xyz" (string)
4628 self.assertEquals('""', collapse('"\\\""')) # "\"" (string)
4629 self.assertEquals('""', collapse('"\'"')) # "'" (string)
4630 self.assertEquals('"\"', collapse('"\"')) # "\" (bad)
4631 self.assertEquals('""', collapse('"\\\\"')) # "\\" (string)
4632 self.assertEquals('"', collapse('"\\\\\\"')) # "\\\" (bad)
4633 self.assertEquals('""', collapse('"\\\\\\\\"')) # "\\\\" (string)
4634
4635 self.assertEquals('\'\'', collapse('\'\'')) # '' (empty)
4636 self.assertEquals('\'\'', collapse('\'a\'')) # 'a' (char)
4637 self.assertEquals('\'\'', collapse('\'\\\'\'')) # '\'' (char)
4638 self.assertEquals('\'', collapse('\'\\\'')) # '\' (bad)
4639 self.assertEquals('', collapse('\\012')) # '\012' (char)
4640 self.assertEquals('', collapse('\\xfF0')) # '\xfF0' (char)
4641 self.assertEquals('', collapse('\\n')) # '\n' (char)
avakulenko@google.com02af6282014-06-04 18:53:25 +00004642 self.assertEquals(r'\#', collapse('\\#')) # '\#' (bad)
4643
4644 self.assertEquals('"" + ""', collapse('"\'" + "\'"'))
4645 self.assertEquals("'', ''", collapse("'\"', '\"'"))
4646 self.assertEquals('""[0b10]', collapse('"a\'b"[0b1\'0]'))
4647
4648 self.assertEquals('42', collapse("4'2"))
4649 self.assertEquals('0b0101', collapse("0b0'1'0'1"))
4650 self.assertEquals('1048576', collapse("1'048'576"))
4651 self.assertEquals('0X100000', collapse("0X10'0000"))
4652 self.assertEquals('0004000000', collapse("0'004'000'000"))
4653 self.assertEquals('1.602176565e-19', collapse("1.602'176'565e-19"))
4654 self.assertEquals('\'\' + 0xffff', collapse("'i' + 0xf'f'f'f"))
4655 self.assertEquals('sizeof\'\' == 1', collapse("sizeof'x' == 1"))
4656 self.assertEquals('0x.03p100', collapse('0x.0\'3p1\'0\'0'))
4657 self.assertEquals('123.45', collapse('1\'23.4\'5'))
erg@google.com4e00b9a2009-01-12 23:05:11 +00004658
4659 self.assertEquals('StringReplace(body, "", "");',
4660 collapse('StringReplace(body, "\\\\", "\\\\\\\\");'))
4661 self.assertEquals('\'\' ""',
4662 collapse('\'"\' "foo"'))
4663
4664
4665class OrderOfIncludesTest(CpplintTestBase):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004666
erg@google.com4e00b9a2009-01-12 23:05:11 +00004667 def setUp(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004668 CpplintTestBase.setUp(self)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004669 self.include_state = cpplint._IncludeState()
erg@google.com4e00b9a2009-01-12 23:05:11 +00004670 os.path.abspath = lambda value: value
4671
erg@google.com4e00b9a2009-01-12 23:05:11 +00004672 def testCheckNextIncludeOrder_OtherThenCpp(self):
4673 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4674 cpplint._OTHER_HEADER))
4675 self.assertEqual('Found C++ system header after other header',
4676 self.include_state.CheckNextIncludeOrder(
4677 cpplint._CPP_SYS_HEADER))
4678
4679 def testCheckNextIncludeOrder_CppThenC(self):
4680 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4681 cpplint._CPP_SYS_HEADER))
4682 self.assertEqual('Found C system header after C++ system header',
4683 self.include_state.CheckNextIncludeOrder(
4684 cpplint._C_SYS_HEADER))
4685
4686 def testCheckNextIncludeOrder_LikelyThenCpp(self):
4687 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4688 cpplint._LIKELY_MY_HEADER))
4689 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4690 cpplint._CPP_SYS_HEADER))
4691
4692 def testCheckNextIncludeOrder_PossibleThenCpp(self):
4693 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4694 cpplint._POSSIBLE_MY_HEADER))
4695 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4696 cpplint._CPP_SYS_HEADER))
4697
4698 def testCheckNextIncludeOrder_CppThenLikely(self):
4699 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4700 cpplint._CPP_SYS_HEADER))
4701 # This will eventually fail.
4702 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4703 cpplint._LIKELY_MY_HEADER))
4704
4705 def testCheckNextIncludeOrder_CppThenPossible(self):
4706 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4707 cpplint._CPP_SYS_HEADER))
4708 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4709 cpplint._POSSIBLE_MY_HEADER))
4710
4711 def testClassifyInclude(self):
4712 file_info = cpplint.FileInfo
4713 classify_include = cpplint._ClassifyInclude
4714 self.assertEqual(cpplint._C_SYS_HEADER,
4715 classify_include(file_info('foo/foo.cc'),
4716 'stdio.h',
4717 True))
4718 self.assertEqual(cpplint._CPP_SYS_HEADER,
4719 classify_include(file_info('foo/foo.cc'),
4720 'string',
4721 True))
4722 self.assertEqual(cpplint._CPP_SYS_HEADER,
4723 classify_include(file_info('foo/foo.cc'),
4724 'typeinfo',
4725 True))
4726 self.assertEqual(cpplint._OTHER_HEADER,
4727 classify_include(file_info('foo/foo.cc'),
4728 'string',
4729 False))
4730
4731 self.assertEqual(cpplint._LIKELY_MY_HEADER,
4732 classify_include(file_info('foo/foo.cc'),
4733 'foo/foo-inl.h',
4734 False))
4735 self.assertEqual(cpplint._LIKELY_MY_HEADER,
4736 classify_include(file_info('foo/internal/foo.cc'),
4737 'foo/public/foo.h',
4738 False))
4739 self.assertEqual(cpplint._POSSIBLE_MY_HEADER,
4740 classify_include(file_info('foo/internal/foo.cc'),
4741 'foo/other/public/foo.h',
4742 False))
4743 self.assertEqual(cpplint._OTHER_HEADER,
4744 classify_include(file_info('foo/internal/foo.cc'),
4745 'foo/other/public/foop.h',
4746 False))
4747
4748 def testTryDropCommonSuffixes(self):
4749 self.assertEqual('foo/foo', cpplint._DropCommonSuffixes('foo/foo-inl.h'))
4750 self.assertEqual('foo/bar/foo',
4751 cpplint._DropCommonSuffixes('foo/bar/foo_inl.h'))
4752 self.assertEqual('foo/foo', cpplint._DropCommonSuffixes('foo/foo.cc'))
4753 self.assertEqual('foo/foo_unusualinternal',
4754 cpplint._DropCommonSuffixes('foo/foo_unusualinternal.h'))
4755 self.assertEqual('',
4756 cpplint._DropCommonSuffixes('_test.cc'))
4757 self.assertEqual('test',
4758 cpplint._DropCommonSuffixes('test.cc'))
4759
4760 def testRegression(self):
4761 def Format(includes):
erg@google.comfd5da632013-10-25 17:39:45 +00004762 include_list = []
avakulenko@google.com554223d2014-12-04 22:00:20 +00004763 for item in includes:
4764 if item.startswith('"') or item.startswith('<'):
4765 include_list.append('#include %s\n' % item)
erg@google.comfd5da632013-10-25 17:39:45 +00004766 else:
avakulenko@google.com554223d2014-12-04 22:00:20 +00004767 include_list.append(item + '\n')
erg@google.comfd5da632013-10-25 17:39:45 +00004768 return ''.join(include_list)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004769
4770 # Test singleton cases first.
4771 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"foo/foo.h"']), '')
4772 self.TestLanguageRulesCheck('foo/foo.cc', Format(['<stdio.h>']), '')
4773 self.TestLanguageRulesCheck('foo/foo.cc', Format(['<string>']), '')
4774 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"foo/foo-inl.h"']), '')
4775 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"bar/bar-inl.h"']), '')
4776 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"bar/bar.h"']), '')
4777
4778 # Test everything in a good and new order.
4779 self.TestLanguageRulesCheck('foo/foo.cc',
4780 Format(['"foo/foo.h"',
4781 '"foo/foo-inl.h"',
4782 '<stdio.h>',
4783 '<string>',
avakulenko@google.com02af6282014-06-04 18:53:25 +00004784 '<unordered_map>',
erg@google.com4e00b9a2009-01-12 23:05:11 +00004785 '"bar/bar-inl.h"',
4786 '"bar/bar.h"']),
4787 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004788
4789 # Test bad orders.
4790 self.TestLanguageRulesCheck(
4791 'foo/foo.cc',
4792 Format(['<string>', '<stdio.h>']),
4793 'Found C system header after C++ system header.'
4794 ' Should be: foo.h, c system, c++ system, other.'
4795 ' [build/include_order] [4]')
4796 self.TestLanguageRulesCheck(
4797 'foo/foo.cc',
4798 Format(['"foo/bar-inl.h"',
4799 '"foo/foo-inl.h"']),
4800 '')
erg@google.comfd5da632013-10-25 17:39:45 +00004801 self.TestLanguageRulesCheck(
4802 'foo/foo.cc',
4803 Format(['"foo/e.h"',
4804 '"foo/b.h"', # warning here (e>b)
4805 '"foo/c.h"',
4806 '"foo/d.h"',
4807 '"foo/a.h"']), # warning here (d>a)
4808 ['Include "foo/b.h" not in alphabetical order'
4809 ' [build/include_alpha] [4]',
4810 'Include "foo/a.h" not in alphabetical order'
4811 ' [build/include_alpha] [4]'])
erg@google.com4e00b9a2009-01-12 23:05:11 +00004812 # -inl.h headers are no longer special.
4813 self.TestLanguageRulesCheck('foo/foo.cc',
4814 Format(['"foo/foo-inl.h"', '<string>']),
4815 '')
4816 self.TestLanguageRulesCheck('foo/foo.cc',
4817 Format(['"foo/bar.h"', '"foo/bar-inl.h"']),
4818 '')
4819 # Test componentized header. OK to have my header in ../public dir.
4820 self.TestLanguageRulesCheck('foo/internal/foo.cc',
4821 Format(['"foo/public/foo.h"', '<string>']),
4822 '')
4823 # OK to have my header in other dir (not stylistically, but
4824 # cpplint isn't as good as a human).
4825 self.TestLanguageRulesCheck('foo/internal/foo.cc',
4826 Format(['"foo/other/public/foo.h"',
4827 '<string>']),
4828 '')
erg@google.coma868d2d2009-10-09 21:18:45 +00004829 self.TestLanguageRulesCheck('foo/foo.cc',
4830 Format(['"foo/foo.h"',
4831 '<string>',
4832 '"base/google.h"',
4833 '"base/flags.h"']),
4834 'Include "base/flags.h" not in alphabetical '
4835 'order [build/include_alpha] [4]')
4836 # According to the style, -inl.h should come before .h, but we don't
4837 # complain about that.
4838 self.TestLanguageRulesCheck('foo/foo.cc',
4839 Format(['"foo/foo-inl.h"',
4840 '"foo/foo.h"',
4841 '"base/google.h"',
4842 '"base/google-inl.h"']),
4843 '')
erg@google.comfd5da632013-10-25 17:39:45 +00004844 # Allow project includes to be separated by blank lines
4845 self.TestLanguageRulesCheck('a/a.cc',
4846 Format(['"a/a.h"',
4847 '<string>',
4848 '"base/google.h"',
4849 '',
avakulenko@google.com554223d2014-12-04 22:00:20 +00004850 '"b/c.h"',
4851 '',
4852 'MACRO',
erg@google.comfd5da632013-10-25 17:39:45 +00004853 '"a/b.h"']),
4854 '')
4855 self.TestLanguageRulesCheck('a/a.cc',
4856 Format(['"a/a.h"',
4857 '<string>',
4858 '"base/google.h"',
4859 '"a/b.h"']),
4860 'Include "a/b.h" not in alphabetical '
4861 'order [build/include_alpha] [4]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004862
erg@google.com2aa59982013-10-28 19:09:25 +00004863 # Test conditional includes
4864 self.TestLanguageRulesCheck(
4865 'a/a.cc',
4866 ''.join(['#include <string.h>\n',
4867 '#include "base/port.h"\n',
4868 '#include <initializer_list>\n']),
4869 ('Found C++ system header after other header. '
4870 'Should be: a.h, c system, c++ system, other. '
4871 '[build/include_order] [4]'))
4872 self.TestLanguageRulesCheck(
4873 'a/a.cc',
4874 ''.join(['#include <string.h>\n',
4875 '#include "base/port.h"\n',
4876 '#ifdef LANG_CXX11\n',
4877 '#include <initializer_list>\n',
4878 '#endif // LANG_CXX11\n']),
4879 '')
4880 self.TestLanguageRulesCheck(
4881 'a/a.cc',
4882 ''.join(['#include <string.h>\n',
4883 '#ifdef LANG_CXX11\n',
4884 '#include "base/port.h"\n',
4885 '#include <initializer_list>\n',
4886 '#endif // LANG_CXX11\n']),
4887 ('Found C++ system header after other header. '
4888 'Should be: a.h, c system, c++ system, other. '
4889 '[build/include_order] [4]'))
4890
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004891 # Third party headers are exempt from order checks
4892 self.TestLanguageRulesCheck('foo/foo.cc',
4893 Format(['<string>', '"Python.h"', '<vector>']),
4894 '')
4895
erg@google.com4e00b9a2009-01-12 23:05:11 +00004896
4897class CheckForFunctionLengthsTest(CpplintTestBase):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004898
erg@google.com4e00b9a2009-01-12 23:05:11 +00004899 def setUp(self):
4900 # Reducing these thresholds for the tests speeds up tests significantly.
4901 self.old_normal_trigger = cpplint._FunctionState._NORMAL_TRIGGER
4902 self.old_test_trigger = cpplint._FunctionState._TEST_TRIGGER
4903
4904 cpplint._FunctionState._NORMAL_TRIGGER = 10
4905 cpplint._FunctionState._TEST_TRIGGER = 25
4906
4907 def tearDown(self):
4908 cpplint._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger
4909 cpplint._FunctionState._TEST_TRIGGER = self.old_test_trigger
4910
4911 def TestFunctionLengthsCheck(self, code, expected_message):
4912 """Check warnings for long function bodies are as expected.
4913
4914 Args:
4915 code: C++ source code expected to generate a warning message.
4916 expected_message: Message expected to be generated by the C++ code.
4917 """
4918 self.assertEquals(expected_message,
4919 self.PerformFunctionLengthsCheck(code))
4920
4921 def TriggerLines(self, error_level):
4922 """Return number of lines needed to trigger a function length warning.
4923
4924 Args:
4925 error_level: --v setting for cpplint.
4926
4927 Returns:
4928 Number of lines needed to trigger a function length warning.
4929 """
4930 return cpplint._FunctionState._NORMAL_TRIGGER * 2**error_level
4931
4932 def TestLines(self, error_level):
4933 """Return number of lines needed to trigger a test function length warning.
4934
4935 Args:
4936 error_level: --v setting for cpplint.
4937
4938 Returns:
4939 Number of lines needed to trigger a test function length warning.
4940 """
4941 return cpplint._FunctionState._TEST_TRIGGER * 2**error_level
4942
4943 def TestFunctionLengthCheckDefinition(self, lines, error_level):
4944 """Generate long function definition and check warnings are as expected.
4945
4946 Args:
4947 lines: Number of lines to generate.
4948 error_level: --v setting for cpplint.
4949 """
4950 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4951 self.TestFunctionLengthsCheck(
4952 'void test(int x)' + self.FunctionBody(lines),
4953 ('Small and focused functions are preferred: '
4954 'test() has %d non-comment lines '
4955 '(error triggered by exceeding %d lines).'
4956 ' [readability/fn_size] [%d]'
4957 % (lines, trigger_level, error_level)))
4958
4959 def TestFunctionLengthCheckDefinitionOK(self, lines):
4960 """Generate shorter function definition and check no warning is produced.
4961
4962 Args:
4963 lines: Number of lines to generate.
4964 """
4965 self.TestFunctionLengthsCheck(
4966 'void test(int x)' + self.FunctionBody(lines),
4967 '')
4968
4969 def TestFunctionLengthCheckAtErrorLevel(self, error_level):
4970 """Generate and check function at the trigger level for --v setting.
4971
4972 Args:
4973 error_level: --v setting for cpplint.
4974 """
4975 self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level),
4976 error_level)
4977
4978 def TestFunctionLengthCheckBelowErrorLevel(self, error_level):
4979 """Generate and check function just below the trigger level for --v setting.
4980
4981 Args:
4982 error_level: --v setting for cpplint.
4983 """
4984 self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level)-1,
4985 error_level-1)
4986
4987 def TestFunctionLengthCheckAboveErrorLevel(self, error_level):
4988 """Generate and check function just above the trigger level for --v setting.
4989
4990 Args:
4991 error_level: --v setting for cpplint.
4992 """
4993 self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level)+1,
4994 error_level)
4995
4996 def FunctionBody(self, number_of_lines):
4997 return ' {\n' + ' this_is_just_a_test();\n'*number_of_lines + '}'
4998
4999 def FunctionBodyWithBlankLines(self, number_of_lines):
5000 return ' {\n' + ' this_is_just_a_test();\n\n'*number_of_lines + '}'
5001
5002 def FunctionBodyWithNoLints(self, number_of_lines):
5003 return (' {\n' +
5004 ' this_is_just_a_test(); // NOLINT\n'*number_of_lines + '}')
5005
5006 # Test line length checks.
5007 def testFunctionLengthCheckDeclaration(self):
5008 self.TestFunctionLengthsCheck(
5009 'void test();', # Not a function definition
5010 '')
5011
5012 def testFunctionLengthCheckDeclarationWithBlockFollowing(self):
5013 self.TestFunctionLengthsCheck(
5014 ('void test();\n'
5015 + self.FunctionBody(66)), # Not a function definition
5016 '')
5017
5018 def testFunctionLengthCheckClassDefinition(self):
5019 self.TestFunctionLengthsCheck( # Not a function definition
5020 'class Test' + self.FunctionBody(66) + ';',
5021 '')
5022
5023 def testFunctionLengthCheckTrivial(self):
5024 self.TestFunctionLengthsCheck(
5025 'void test() {}', # Not counted
5026 '')
5027
5028 def testFunctionLengthCheckEmpty(self):
5029 self.TestFunctionLengthsCheck(
5030 'void test() {\n}',
5031 '')
5032
5033 def testFunctionLengthCheckDefinitionBelowSeverity0(self):
5034 old_verbosity = cpplint._SetVerboseLevel(0)
5035 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(0)-1)
5036 cpplint._SetVerboseLevel(old_verbosity)
5037
5038 def testFunctionLengthCheckDefinitionAtSeverity0(self):
5039 old_verbosity = cpplint._SetVerboseLevel(0)
5040 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(0))
5041 cpplint._SetVerboseLevel(old_verbosity)
5042
5043 def testFunctionLengthCheckDefinitionAboveSeverity0(self):
5044 old_verbosity = cpplint._SetVerboseLevel(0)
5045 self.TestFunctionLengthCheckAboveErrorLevel(0)
5046 cpplint._SetVerboseLevel(old_verbosity)
5047
5048 def testFunctionLengthCheckDefinitionBelowSeverity1v0(self):
5049 old_verbosity = cpplint._SetVerboseLevel(0)
5050 self.TestFunctionLengthCheckBelowErrorLevel(1)
5051 cpplint._SetVerboseLevel(old_verbosity)
5052
5053 def testFunctionLengthCheckDefinitionAtSeverity1v0(self):
5054 old_verbosity = cpplint._SetVerboseLevel(0)
5055 self.TestFunctionLengthCheckAtErrorLevel(1)
5056 cpplint._SetVerboseLevel(old_verbosity)
5057
5058 def testFunctionLengthCheckDefinitionBelowSeverity1(self):
5059 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(1)-1)
5060
5061 def testFunctionLengthCheckDefinitionAtSeverity1(self):
5062 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(1))
5063
5064 def testFunctionLengthCheckDefinitionAboveSeverity1(self):
5065 self.TestFunctionLengthCheckAboveErrorLevel(1)
5066
5067 def testFunctionLengthCheckDefinitionSeverity1PlusBlanks(self):
5068 error_level = 1
5069 error_lines = self.TriggerLines(error_level) + 1
5070 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
5071 self.TestFunctionLengthsCheck(
5072 'void test_blanks(int x)' + self.FunctionBody(error_lines),
5073 ('Small and focused functions are preferred: '
5074 'test_blanks() has %d non-comment lines '
5075 '(error triggered by exceeding %d lines).'
5076 ' [readability/fn_size] [%d]')
5077 % (error_lines, trigger_level, error_level))
5078
5079 def testFunctionLengthCheckComplexDefinitionSeverity1(self):
5080 error_level = 1
5081 error_lines = self.TriggerLines(error_level) + 1
5082 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
5083 self.TestFunctionLengthsCheck(
5084 ('my_namespace::my_other_namespace::MyVeryLongTypeName*\n'
5085 'my_namespace::my_other_namespace::MyFunction(int arg1, char* arg2)'
5086 + self.FunctionBody(error_lines)),
5087 ('Small and focused functions are preferred: '
5088 'my_namespace::my_other_namespace::MyFunction()'
5089 ' has %d non-comment lines '
5090 '(error triggered by exceeding %d lines).'
5091 ' [readability/fn_size] [%d]')
5092 % (error_lines, trigger_level, error_level))
5093
5094 def testFunctionLengthCheckDefinitionSeverity1ForTest(self):
5095 error_level = 1
5096 error_lines = self.TestLines(error_level) + 1
5097 trigger_level = self.TestLines(cpplint._VerboseLevel())
5098 self.TestFunctionLengthsCheck(
5099 'TEST_F(Test, Mutator)' + self.FunctionBody(error_lines),
5100 ('Small and focused functions are preferred: '
5101 'TEST_F(Test, Mutator) has %d non-comment lines '
5102 '(error triggered by exceeding %d lines).'
5103 ' [readability/fn_size] [%d]')
5104 % (error_lines, trigger_level, error_level))
5105
5106 def testFunctionLengthCheckDefinitionSeverity1ForSplitLineTest(self):
5107 error_level = 1
5108 error_lines = self.TestLines(error_level) + 1
5109 trigger_level = self.TestLines(cpplint._VerboseLevel())
5110 self.TestFunctionLengthsCheck(
5111 ('TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,\n'
5112 ' FixGoogleUpdate_AllValues_MachineApp)' # note: 4 spaces
5113 + self.FunctionBody(error_lines)),
5114 ('Small and focused functions are preferred: '
5115 'TEST_F(GoogleUpdateRecoveryRegistryProtectedTest, ' # 1 space
5116 'FixGoogleUpdate_AllValues_MachineApp) has %d non-comment lines '
5117 '(error triggered by exceeding %d lines).'
5118 ' [readability/fn_size] [%d]')
5119 % (error_lines+1, trigger_level, error_level))
5120
5121 def testFunctionLengthCheckDefinitionSeverity1ForBadTestDoesntBreak(self):
5122 error_level = 1
5123 error_lines = self.TestLines(error_level) + 1
5124 trigger_level = self.TestLines(cpplint._VerboseLevel())
5125 self.TestFunctionLengthsCheck(
5126 ('TEST_F('
5127 + self.FunctionBody(error_lines)),
5128 ('Small and focused functions are preferred: '
5129 'TEST_F has %d non-comment lines '
5130 '(error triggered by exceeding %d lines).'
5131 ' [readability/fn_size] [%d]')
5132 % (error_lines, trigger_level, error_level))
5133
5134 def testFunctionLengthCheckDefinitionSeverity1WithEmbeddedNoLints(self):
5135 error_level = 1
5136 error_lines = self.TriggerLines(error_level)+1
5137 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
5138 self.TestFunctionLengthsCheck(
5139 'void test(int x)' + self.FunctionBodyWithNoLints(error_lines),
5140 ('Small and focused functions are preferred: '
5141 'test() has %d non-comment lines '
5142 '(error triggered by exceeding %d lines).'
5143 ' [readability/fn_size] [%d]')
5144 % (error_lines, trigger_level, error_level))
5145
5146 def testFunctionLengthCheckDefinitionSeverity1WithNoLint(self):
5147 self.TestFunctionLengthsCheck(
5148 ('void test(int x)' + self.FunctionBody(self.TriggerLines(1))
5149 + ' // NOLINT -- long function'),
5150 '')
5151
5152 def testFunctionLengthCheckDefinitionBelowSeverity2(self):
5153 self.TestFunctionLengthCheckBelowErrorLevel(2)
5154
5155 def testFunctionLengthCheckDefinitionSeverity2(self):
5156 self.TestFunctionLengthCheckAtErrorLevel(2)
5157
5158 def testFunctionLengthCheckDefinitionAboveSeverity2(self):
5159 self.TestFunctionLengthCheckAboveErrorLevel(2)
5160
5161 def testFunctionLengthCheckDefinitionBelowSeverity3(self):
5162 self.TestFunctionLengthCheckBelowErrorLevel(3)
5163
5164 def testFunctionLengthCheckDefinitionSeverity3(self):
5165 self.TestFunctionLengthCheckAtErrorLevel(3)
5166
5167 def testFunctionLengthCheckDefinitionAboveSeverity3(self):
5168 self.TestFunctionLengthCheckAboveErrorLevel(3)
5169
5170 def testFunctionLengthCheckDefinitionBelowSeverity4(self):
5171 self.TestFunctionLengthCheckBelowErrorLevel(4)
5172
5173 def testFunctionLengthCheckDefinitionSeverity4(self):
5174 self.TestFunctionLengthCheckAtErrorLevel(4)
5175
5176 def testFunctionLengthCheckDefinitionAboveSeverity4(self):
5177 self.TestFunctionLengthCheckAboveErrorLevel(4)
5178
5179 def testFunctionLengthCheckDefinitionBelowSeverity5(self):
5180 self.TestFunctionLengthCheckBelowErrorLevel(5)
5181
5182 def testFunctionLengthCheckDefinitionAtSeverity5(self):
5183 self.TestFunctionLengthCheckAtErrorLevel(5)
5184
5185 def testFunctionLengthCheckDefinitionAboveSeverity5(self):
5186 self.TestFunctionLengthCheckAboveErrorLevel(5)
5187
5188 def testFunctionLengthCheckDefinitionHugeLines(self):
5189 # 5 is the limit
5190 self.TestFunctionLengthCheckDefinition(self.TriggerLines(10), 5)
5191
5192 def testFunctionLengthNotDeterminable(self):
erg@google.com4e00b9a2009-01-12 23:05:11 +00005193 # Macro invocation without terminating semicolon.
5194 self.TestFunctionLengthsCheck(
5195 'MACRO(arg)',
5196 '')
5197
5198 # Macro with underscores
5199 self.TestFunctionLengthsCheck(
5200 'MACRO_WITH_UNDERSCORES(arg1, arg2, arg3)',
5201 '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00005202
erg@google.com4e00b9a2009-01-12 23:05:11 +00005203 self.TestFunctionLengthsCheck(
5204 'NonMacro(arg)',
5205 'Lint failed to find start of function body.'
5206 ' [readability/fn_size] [5]')
5207
Alex Vakulenko01e47232016-05-06 13:54:15 -07005208 def testFunctionLengthCheckWithNamespace(self):
5209 old_verbosity = cpplint._SetVerboseLevel(1)
5210 self.TestFunctionLengthsCheck(
5211 ('namespace {\n'
5212 'void CodeCoverageCL35256059() {\n' +
5213 (' X++;\n' * 3000) +
5214 '}\n'
5215 '} // namespace\n'),
5216 ('Small and focused functions are preferred: '
5217 'CodeCoverageCL35256059() has 3000 non-comment lines '
5218 '(error triggered by exceeding 20 lines).'
5219 ' [readability/fn_size] [5]'))
5220 cpplint._SetVerboseLevel(old_verbosity)
5221
avakulenko@google.com02af6282014-06-04 18:53:25 +00005222
5223def TrimExtraIndent(text_block):
5224 """Trim a uniform amount of whitespace off of each line in a string.
5225
5226 Compute the minimum indent on all non blank lines and trim that from each, so
5227 that the block of text has no extra indentation.
5228
5229 Args:
5230 text_block: a multiline string
5231
5232 Returns:
5233 text_block with the common whitespace indent of each line removed.
5234 """
5235
5236 def CountLeadingWhitespace(s):
5237 count = 0
5238 for c in s:
5239 if not c.isspace():
5240 break
5241 count += 1
5242 return count
5243 # find the minimum indent (except for blank lines)
5244 min_indent = min([CountLeadingWhitespace(line)
5245 for line in text_block.split('\n') if line])
5246 return '\n'.join([line[min_indent:] for line in text_block.split('\n')])
5247
5248
5249class CloseExpressionTest(unittest.TestCase):
5250
erg@google.comd350fe52013-01-14 17:51:48 +00005251 def setUp(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00005252 self.lines = cpplint.CleansedLines(
5253 # 1 2 3 4 5
5254 # 0123456789012345678901234567890123456789012345678901234567890
5255 ['// Line 0',
5256 'inline RCULocked<X>::ReadPtr::ReadPtr(const RCULocked* rcu) {',
5257 ' DCHECK(!(data & kFlagMask)) << "Error";',
5258 '}',
5259 '// Line 4',
5260 'RCULocked<X>::WritePtr::WritePtr(RCULocked* rcu)',
5261 ' : lock_(&rcu_->mutex_) {',
5262 '}',
5263 '// Line 8',
5264 'template <typename T, typename... A>',
5265 'typename std::enable_if<',
5266 ' std::is_array<T>::value && (std::extent<T>::value > 0)>::type',
5267 'MakeUnique(A&&... a) = delete;',
5268 '// Line 13',
5269 'auto x = []() {};',
5270 '// Line 15',
5271 'template <typename U>',
5272 'friend bool operator==(const reffed_ptr& a,',
5273 ' const reffed_ptr<U>& b) {',
5274 ' return a.get() == b.get();',
5275 '}',
5276 '// Line 21'])
5277
5278 def testCloseExpression(self):
5279 # List of positions to test:
5280 # (start line, start position, end line, end position + 1)
5281 positions = [(1, 16, 1, 19),
5282 (1, 37, 1, 59),
5283 (1, 60, 3, 1),
5284 (2, 8, 2, 29),
5285 (2, 30, 22, -1), # Left shift operator
5286 (9, 9, 9, 36),
5287 (10, 23, 11, 59),
5288 (11, 54, 22, -1), # Greater than operator
5289 (14, 9, 14, 11),
5290 (14, 11, 14, 13),
5291 (14, 14, 14, 16),
5292 (17, 22, 18, 46),
5293 (18, 47, 20, 1)]
5294 for p in positions:
5295 (_, line, column) = cpplint.CloseExpression(self.lines, p[0], p[1])
5296 self.assertEquals((p[2], p[3]), (line, column))
5297
5298 def testReverseCloseExpression(self):
5299 # List of positions to test:
5300 # (end line, end position, start line, start position)
5301 positions = [(1, 18, 1, 16),
5302 (1, 58, 1, 37),
5303 (2, 27, 2, 10),
5304 (2, 28, 2, 8),
5305 (6, 18, 0, -1), # -> operator
5306 (9, 35, 9, 9),
5307 (11, 54, 0, -1), # Greater than operator
5308 (11, 57, 11, 31),
5309 (14, 10, 14, 9),
5310 (14, 12, 14, 11),
5311 (14, 15, 14, 14),
5312 (18, 45, 17, 22),
5313 (20, 0, 18, 47)]
5314 for p in positions:
5315 (_, line, column) = cpplint.ReverseCloseExpression(self.lines, p[0], p[1])
5316 self.assertEquals((p[2], p[3]), (line, column))
5317
5318
5319class NestingStateTest(unittest.TestCase):
5320
5321 def setUp(self):
5322 self.nesting_state = cpplint.NestingState()
erg@google.comd350fe52013-01-14 17:51:48 +00005323 self.error_collector = ErrorCollector(self.assert_)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005324
erg@google.comd350fe52013-01-14 17:51:48 +00005325 def UpdateWithLines(self, lines):
5326 clean_lines = cpplint.CleansedLines(lines)
5327 for line in xrange(clean_lines.NumLines()):
5328 self.nesting_state.Update('test.cc',
5329 clean_lines, line, self.error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005330
erg@google.comd350fe52013-01-14 17:51:48 +00005331 def testEmpty(self):
5332 self.UpdateWithLines([])
5333 self.assertEquals(self.nesting_state.stack, [])
erg@google.com4e00b9a2009-01-12 23:05:11 +00005334
erg@google.comd350fe52013-01-14 17:51:48 +00005335 def testNamespace(self):
5336 self.UpdateWithLines(['namespace {'])
5337 self.assertEquals(len(self.nesting_state.stack), 1)
5338 self.assertTrue(isinstance(self.nesting_state.stack[0],
5339 cpplint._NamespaceInfo))
5340 self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
5341 self.assertEquals(self.nesting_state.stack[0].name, '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005342
erg@google.comd350fe52013-01-14 17:51:48 +00005343 self.UpdateWithLines(['namespace outer { namespace inner'])
5344 self.assertEquals(len(self.nesting_state.stack), 3)
5345 self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
5346 self.assertTrue(self.nesting_state.stack[1].seen_open_brace)
5347 self.assertFalse(self.nesting_state.stack[2].seen_open_brace)
5348 self.assertEquals(self.nesting_state.stack[0].name, '')
5349 self.assertEquals(self.nesting_state.stack[1].name, 'outer')
5350 self.assertEquals(self.nesting_state.stack[2].name, 'inner')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005351
erg@google.comd350fe52013-01-14 17:51:48 +00005352 self.UpdateWithLines(['{'])
5353 self.assertTrue(self.nesting_state.stack[2].seen_open_brace)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005354
erg@google.comd350fe52013-01-14 17:51:48 +00005355 self.UpdateWithLines(['}', '}}'])
5356 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005357
erg@google.comd350fe52013-01-14 17:51:48 +00005358 def testClass(self):
5359 self.UpdateWithLines(['class A {'])
5360 self.assertEquals(len(self.nesting_state.stack), 1)
5361 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5362 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5363 self.assertFalse(self.nesting_state.stack[0].is_derived)
erg@google.comfd5da632013-10-25 17:39:45 +00005364 self.assertEquals(self.nesting_state.stack[0].class_indent, 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005365
erg@google.comd350fe52013-01-14 17:51:48 +00005366 self.UpdateWithLines(['};',
5367 'struct B : public A {'])
5368 self.assertEquals(len(self.nesting_state.stack), 1)
5369 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5370 self.assertEquals(self.nesting_state.stack[0].name, 'B')
5371 self.assertTrue(self.nesting_state.stack[0].is_derived)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005372
erg@google.comd350fe52013-01-14 17:51:48 +00005373 self.UpdateWithLines(['};',
5374 'class C',
5375 ': public A {'])
5376 self.assertEquals(len(self.nesting_state.stack), 1)
5377 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5378 self.assertEquals(self.nesting_state.stack[0].name, 'C')
5379 self.assertTrue(self.nesting_state.stack[0].is_derived)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005380
erg@google.comd350fe52013-01-14 17:51:48 +00005381 self.UpdateWithLines(['};',
5382 'template<T>'])
5383 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005384
erg@google.comfd5da632013-10-25 17:39:45 +00005385 self.UpdateWithLines(['class D {', ' class E {'])
erg@google.comd350fe52013-01-14 17:51:48 +00005386 self.assertEquals(len(self.nesting_state.stack), 2)
5387 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5388 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5389 self.assertFalse(self.nesting_state.stack[0].is_derived)
5390 self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5391 self.assertEquals(self.nesting_state.stack[1].name, 'E')
5392 self.assertFalse(self.nesting_state.stack[1].is_derived)
erg@google.comfd5da632013-10-25 17:39:45 +00005393 self.assertEquals(self.nesting_state.stack[1].class_indent, 2)
erg@google.comd350fe52013-01-14 17:51:48 +00005394 self.assertEquals(self.nesting_state.InnermostClass().name, 'E')
erg@google.comd7d27472011-09-07 17:36:35 +00005395
erg@google.comd350fe52013-01-14 17:51:48 +00005396 self.UpdateWithLines(['}', '}'])
5397 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.comd7d27472011-09-07 17:36:35 +00005398
erg@google.comd350fe52013-01-14 17:51:48 +00005399 def testClassAccess(self):
5400 self.UpdateWithLines(['class A {'])
5401 self.assertEquals(len(self.nesting_state.stack), 1)
5402 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5403 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.comd7d27472011-09-07 17:36:35 +00005404
erg@google.comd350fe52013-01-14 17:51:48 +00005405 self.UpdateWithLines([' public:'])
5406 self.assertEquals(self.nesting_state.stack[0].access, 'public')
5407 self.UpdateWithLines([' protracted:'])
5408 self.assertEquals(self.nesting_state.stack[0].access, 'public')
5409 self.UpdateWithLines([' protected:'])
5410 self.assertEquals(self.nesting_state.stack[0].access, 'protected')
5411 self.UpdateWithLines([' private:'])
5412 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005413
erg@google.comd350fe52013-01-14 17:51:48 +00005414 self.UpdateWithLines([' struct B {'])
5415 self.assertEquals(len(self.nesting_state.stack), 2)
5416 self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5417 self.assertEquals(self.nesting_state.stack[1].access, 'public')
5418 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005419
erg@google.comd350fe52013-01-14 17:51:48 +00005420 self.UpdateWithLines([' protected :'])
5421 self.assertEquals(self.nesting_state.stack[1].access, 'protected')
5422 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005423
erg@google.comd350fe52013-01-14 17:51:48 +00005424 self.UpdateWithLines([' }', '}'])
5425 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005426
erg@google.comd350fe52013-01-14 17:51:48 +00005427 def testStruct(self):
5428 self.UpdateWithLines(['struct A {'])
5429 self.assertEquals(len(self.nesting_state.stack), 1)
5430 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5431 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5432 self.assertFalse(self.nesting_state.stack[0].is_derived)
erg@google.com4e00b9a2009-01-12 23:05:11 +00005433
erg@google.comd350fe52013-01-14 17:51:48 +00005434 self.UpdateWithLines(['}',
5435 'void Func(struct B arg) {'])
5436 self.assertEquals(len(self.nesting_state.stack), 1)
5437 self.assertFalse(isinstance(self.nesting_state.stack[0],
5438 cpplint._ClassInfo))
erg@google.com4e00b9a2009-01-12 23:05:11 +00005439
erg@google.comd350fe52013-01-14 17:51:48 +00005440 self.UpdateWithLines(['}'])
5441 self.assertEquals(len(self.nesting_state.stack), 0)
erg+personal@google.com05189642010-04-30 20:43:03 +00005442
erg@google.comd350fe52013-01-14 17:51:48 +00005443 def testPreprocessor(self):
5444 self.assertEquals(len(self.nesting_state.pp_stack), 0)
5445 self.UpdateWithLines(['#if MACRO1'])
5446 self.assertEquals(len(self.nesting_state.pp_stack), 1)
5447 self.UpdateWithLines(['#endif'])
5448 self.assertEquals(len(self.nesting_state.pp_stack), 0)
5449
5450 self.UpdateWithLines(['#ifdef MACRO2'])
5451 self.assertEquals(len(self.nesting_state.pp_stack), 1)
5452 self.UpdateWithLines(['#else'])
5453 self.assertEquals(len(self.nesting_state.pp_stack), 1)
5454 self.UpdateWithLines(['#ifdef MACRO3'])
5455 self.assertEquals(len(self.nesting_state.pp_stack), 2)
5456 self.UpdateWithLines(['#elif MACRO4'])
5457 self.assertEquals(len(self.nesting_state.pp_stack), 2)
5458 self.UpdateWithLines(['#endif'])
5459 self.assertEquals(len(self.nesting_state.pp_stack), 1)
5460 self.UpdateWithLines(['#endif'])
5461 self.assertEquals(len(self.nesting_state.pp_stack), 0)
5462
5463 self.UpdateWithLines(['#ifdef MACRO5',
5464 'class A {',
5465 '#elif MACRO6',
5466 'class B {',
5467 '#else',
5468 'class C {',
5469 '#endif'])
5470 self.assertEquals(len(self.nesting_state.pp_stack), 0)
5471 self.assertEquals(len(self.nesting_state.stack), 1)
5472 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5473 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5474 self.UpdateWithLines(['};'])
5475 self.assertEquals(len(self.nesting_state.stack), 0)
5476
5477 self.UpdateWithLines(['class D',
5478 '#ifdef MACRO7'])
5479 self.assertEquals(len(self.nesting_state.pp_stack), 1)
5480 self.assertEquals(len(self.nesting_state.stack), 1)
5481 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5482 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5483 self.assertFalse(self.nesting_state.stack[0].is_derived)
5484
5485 self.UpdateWithLines(['#elif MACRO8',
5486 ': public E'])
5487 self.assertEquals(len(self.nesting_state.stack), 1)
5488 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5489 self.assertTrue(self.nesting_state.stack[0].is_derived)
5490 self.assertFalse(self.nesting_state.stack[0].seen_open_brace)
5491
5492 self.UpdateWithLines(['#else',
5493 '{'])
5494 self.assertEquals(len(self.nesting_state.stack), 1)
5495 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5496 self.assertFalse(self.nesting_state.stack[0].is_derived)
5497 self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
5498
5499 self.UpdateWithLines(['#endif'])
5500 self.assertEquals(len(self.nesting_state.pp_stack), 0)
5501 self.assertEquals(len(self.nesting_state.stack), 1)
5502 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5503 self.assertFalse(self.nesting_state.stack[0].is_derived)
5504 self.assertFalse(self.nesting_state.stack[0].seen_open_brace)
5505
5506 self.UpdateWithLines([';'])
5507 self.assertEquals(len(self.nesting_state.stack), 0)
5508
5509 def testTemplate(self):
5510 self.UpdateWithLines(['template <T,',
5511 ' class Arg1 = tmpl<T> >'])
5512 self.assertEquals(len(self.nesting_state.stack), 0)
5513 self.UpdateWithLines(['class A {'])
5514 self.assertEquals(len(self.nesting_state.stack), 1)
5515 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5516 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5517
5518 self.UpdateWithLines(['};',
5519 'template <T,',
5520 ' template <typename, typename> class B>',
5521 'class C'])
5522 self.assertEquals(len(self.nesting_state.stack), 1)
5523 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5524 self.assertEquals(self.nesting_state.stack[0].name, 'C')
5525 self.UpdateWithLines([';'])
5526 self.assertEquals(len(self.nesting_state.stack), 0)
5527
5528 self.UpdateWithLines(['class D : public Tmpl<E>'])
5529 self.assertEquals(len(self.nesting_state.stack), 1)
5530 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5531 self.assertEquals(self.nesting_state.stack[0].name, 'D')
5532
avakulenko@google.com02af6282014-06-04 18:53:25 +00005533 self.UpdateWithLines(['{', '};'])
5534 self.assertEquals(len(self.nesting_state.stack), 0)
5535
5536 self.UpdateWithLines(['template <class F,',
5537 ' class G,',
5538 ' class H,',
5539 ' typename I>',
5540 'static void Func() {'])
5541 self.assertEquals(len(self.nesting_state.stack), 1)
5542 self.assertFalse(isinstance(self.nesting_state.stack[0],
5543 cpplint._ClassInfo))
5544 self.UpdateWithLines(['}',
5545 'template <class J> class K {'])
5546 self.assertEquals(len(self.nesting_state.stack), 1)
5547 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5548 self.assertEquals(self.nesting_state.stack[0].name, 'K')
5549
erg@google.comfd5da632013-10-25 17:39:45 +00005550 def testTemplateInnerClass(self):
5551 self.UpdateWithLines(['class A {',
5552 ' public:'])
5553 self.assertEquals(len(self.nesting_state.stack), 1)
5554 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5555
5556 self.UpdateWithLines([' template <class B>',
5557 ' class C<alloc<B> >',
5558 ' : public A {'])
5559 self.assertEquals(len(self.nesting_state.stack), 2)
5560 self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5561
erg@google.comd350fe52013-01-14 17:51:48 +00005562 def testArguments(self):
5563 self.UpdateWithLines(['class A {'])
5564 self.assertEquals(len(self.nesting_state.stack), 1)
5565 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5566 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5567 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5568
5569 self.UpdateWithLines([' void Func(',
5570 ' struct X arg1,'])
5571 self.assertEquals(len(self.nesting_state.stack), 1)
5572 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5573 self.UpdateWithLines([' struct X *arg2);'])
5574 self.assertEquals(len(self.nesting_state.stack), 1)
5575 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5576
5577 self.UpdateWithLines(['};'])
5578 self.assertEquals(len(self.nesting_state.stack), 0)
5579
5580 self.UpdateWithLines(['struct B {'])
5581 self.assertEquals(len(self.nesting_state.stack), 1)
5582 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5583 self.assertEquals(self.nesting_state.stack[0].name, 'B')
5584
5585 self.UpdateWithLines(['#ifdef MACRO',
5586 ' void Func(',
5587 ' struct X arg1'])
5588 self.assertEquals(len(self.nesting_state.stack), 1)
5589 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5590 self.UpdateWithLines(['#else'])
5591
5592 self.assertEquals(len(self.nesting_state.stack), 1)
5593 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5594 self.UpdateWithLines([' void Func(',
5595 ' struct X arg1'])
5596 self.assertEquals(len(self.nesting_state.stack), 1)
5597 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5598
5599 self.UpdateWithLines(['#endif'])
5600 self.assertEquals(len(self.nesting_state.stack), 1)
5601 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5602 self.UpdateWithLines([' struct X *arg2);'])
5603 self.assertEquals(len(self.nesting_state.stack), 1)
5604 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5605
5606 self.UpdateWithLines(['};'])
5607 self.assertEquals(len(self.nesting_state.stack), 0)
5608
5609 def testInlineAssembly(self):
5610 self.UpdateWithLines(['void CopyRow_SSE2(const uint8* src, uint8* dst,',
5611 ' int count) {'])
5612 self.assertEquals(len(self.nesting_state.stack), 1)
5613 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5614 self.assertEquals(self.nesting_state.stack[-1].inline_asm, cpplint._NO_ASM)
5615
5616 self.UpdateWithLines([' asm volatile ('])
5617 self.assertEquals(len(self.nesting_state.stack), 1)
5618 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5619 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5620 cpplint._INSIDE_ASM)
5621
5622 self.UpdateWithLines([' "sub %0,%1 \\n"',
5623 ' "1: \\n"',
5624 ' "movdqa (%0),%%xmm0 \\n"',
5625 ' "movdqa 0x10(%0),%%xmm1 \\n"',
5626 ' "movdqa %%xmm0,(%0,%1) \\n"',
5627 ' "movdqa %%xmm1,0x10(%0,%1) \\n"',
5628 ' "lea 0x20(%0),%0 \\n"',
5629 ' "sub $0x20,%2 \\n"',
5630 ' "jg 1b \\n"',
5631 ' : "+r"(src), // %0',
5632 ' "+r"(dst), // %1',
5633 ' "+r"(count) // %2',
5634 ' :',
5635 ' : "memory", "cc"'])
5636 self.assertEquals(len(self.nesting_state.stack), 1)
5637 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5638 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5639 cpplint._INSIDE_ASM)
5640
5641 self.UpdateWithLines(['#if defined(__SSE2__)',
5642 ' , "xmm0", "xmm1"'])
5643 self.assertEquals(len(self.nesting_state.stack), 1)
5644 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5645 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5646 cpplint._INSIDE_ASM)
5647
5648 self.UpdateWithLines(['#endif'])
5649 self.assertEquals(len(self.nesting_state.stack), 1)
5650 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5651 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5652 cpplint._INSIDE_ASM)
5653
5654 self.UpdateWithLines([' );'])
5655 self.assertEquals(len(self.nesting_state.stack), 1)
5656 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5657 self.assertEquals(self.nesting_state.stack[-1].inline_asm, cpplint._END_ASM)
5658
5659 self.UpdateWithLines(['__asm {'])
5660 self.assertEquals(len(self.nesting_state.stack), 2)
5661 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5662 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5663 cpplint._BLOCK_ASM)
5664
5665 self.UpdateWithLines(['}'])
5666 self.assertEquals(len(self.nesting_state.stack), 1)
5667
5668 self.UpdateWithLines(['}'])
5669 self.assertEquals(len(self.nesting_state.stack), 0)
5670
erg+personal@google.com05189642010-04-30 20:43:03 +00005671
erg@google.coma868d2d2009-10-09 21:18:45 +00005672# pylint: disable-msg=C6409
5673def setUp():
erg@google.com8a95ecc2011-09-08 00:45:54 +00005674 """Runs before all tests are executed.
erg@google.coma868d2d2009-10-09 21:18:45 +00005675 """
5676 # Enable all filters, so we don't miss anything that is off by default.
5677 cpplint._DEFAULT_FILTERS = []
5678 cpplint._cpplint_state.SetFilters('')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005679
erg@google.coma868d2d2009-10-09 21:18:45 +00005680
5681# pylint: disable-msg=C6409
erg@google.com4e00b9a2009-01-12 23:05:11 +00005682def tearDown():
5683 """A global check to make sure all error-categories have been tested.
5684
5685 The main tearDown() routine is the only code we can guarantee will be
5686 run after all other tests have been executed.
5687 """
5688 try:
5689 if _run_verifyallcategoriesseen:
5690 ErrorCollector(None).VerifyAllCategoriesAreSeen()
5691 except NameError:
5692 # If nobody set the global _run_verifyallcategoriesseen, then
avakulenko@google.com554223d2014-12-04 22:00:20 +00005693 # we assume we should silently not run the test
erg@google.com4e00b9a2009-01-12 23:05:11 +00005694 pass
5695
erg@google.coma868d2d2009-10-09 21:18:45 +00005696
erg@google.com4e00b9a2009-01-12 23:05:11 +00005697if __name__ == '__main__':
erg@google.com4e00b9a2009-01-12 23:05:11 +00005698 # We don't want to run the VerifyAllCategoriesAreSeen() test unless
5699 # we're running the full test suite: if we only run one test,
5700 # obviously we're not going to see all the error categories. So we
5701 # only run VerifyAllCategoriesAreSeen() when no commandline flags
5702 # are passed in.
5703 global _run_verifyallcategoriesseen
5704 _run_verifyallcategoriesseen = (len(sys.argv) == 1)
5705
erg@google.coma868d2d2009-10-09 21:18:45 +00005706 setUp()
erg@google.com4e00b9a2009-01-12 23:05:11 +00005707 unittest.main()
erg@google.coma868d2d2009-10-09 21:18:45 +00005708 tearDown()