blob: c380696c9a343b3858d3c24a19d0c26715fb43f8 [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
253 # Test get line width.
254 def testGetLineWidth(self):
255 self.assertEquals(0, cpplint.GetLineWidth(''))
256 self.assertEquals(10, cpplint.GetLineWidth(u'x' * 10))
257 self.assertEquals(16, cpplint.GetLineWidth(u'都|道|府|県|支庁'))
258
erg@google.com8a95ecc2011-09-08 00:45:54 +0000259 def testGetTextInside(self):
260 self.assertEquals('', cpplint._GetTextInside('fun()', r'fun\('))
261 self.assertEquals('x, y', cpplint._GetTextInside('f(x, y)', r'f\('))
262 self.assertEquals('a(), b(c())', cpplint._GetTextInside(
263 'printf(a(), b(c()))', r'printf\('))
264 self.assertEquals('x, y{}', cpplint._GetTextInside('f[x, y{}]', r'f\['))
265 self.assertEquals(None, cpplint._GetTextInside('f[a, b(}]', r'f\['))
266 self.assertEquals(None, cpplint._GetTextInside('f[x, y]', r'f\('))
267 self.assertEquals('y, h(z, (a + b))', cpplint._GetTextInside(
268 'f(x, g(y, h(z, (a + b))))', r'g\('))
269 self.assertEquals('f(f(x))', cpplint._GetTextInside('f(f(f(x)))', r'f\('))
270 # Supports multiple lines.
271 self.assertEquals('\n return loop(x);\n',
272 cpplint._GetTextInside(
273 'int loop(int x) {\n return loop(x);\n}\n', r'\{'))
avakulenko@google.com02af6282014-06-04 18:53:25 +0000274 # '^' matches the beginning of each line.
erg@google.com8a95ecc2011-09-08 00:45:54 +0000275 self.assertEquals('x, y',
276 cpplint._GetTextInside(
277 '#include "inl.h" // skip #define\n'
278 '#define A2(x, y) a_inl_(x, y, __LINE__)\n'
279 '#define A(x) a_inl_(x, "", __LINE__)\n',
280 r'^\s*#define\s*\w+\('))
281
erg@google.com4e00b9a2009-01-12 23:05:11 +0000282 def testFindNextMultiLineCommentStart(self):
283 self.assertEquals(1, cpplint.FindNextMultiLineCommentStart([''], 0))
284
285 lines = ['a', 'b', '/* c']
286 self.assertEquals(2, cpplint.FindNextMultiLineCommentStart(lines, 0))
287
288 lines = ['char a[] = "/*";'] # not recognized as comment.
289 self.assertEquals(1, cpplint.FindNextMultiLineCommentStart(lines, 0))
290
291 def testFindNextMultiLineCommentEnd(self):
292 self.assertEquals(1, cpplint.FindNextMultiLineCommentEnd([''], 0))
293 lines = ['a', 'b', ' c */']
294 self.assertEquals(2, cpplint.FindNextMultiLineCommentEnd(lines, 0))
295
296 def testRemoveMultiLineCommentsFromRange(self):
297 lines = ['a', ' /* comment ', ' * still comment', ' comment */ ', 'b']
298 cpplint.RemoveMultiLineCommentsFromRange(lines, 1, 4)
299 self.assertEquals(['a', '// dummy', '// dummy', '// dummy', 'b'], lines)
300
301 def testSpacesAtEndOfLine(self):
302 self.TestLint(
303 '// Hello there ',
304 'Line ends in whitespace. Consider deleting these extra spaces.'
305 ' [whitespace/end_of_line] [4]')
306
307 # Test line length check.
308 def testLineLengthCheck(self):
309 self.TestLint(
310 '// Hello',
311 '')
312 self.TestLint(
313 '// ' + 'x' * 80,
314 'Lines should be <= 80 characters long'
315 ' [whitespace/line_length] [2]')
316 self.TestLint(
317 '// ' + 'x' * 100,
318 'Lines should very rarely be longer than 100 characters'
319 ' [whitespace/line_length] [4]')
erg@google.coma87abb82009-02-24 01:41:01 +0000320 self.TestLint(
321 '// http://g' + ('o' * 100) + 'gle.com/',
322 '')
323 self.TestLint(
324 '// https://g' + ('o' * 100) + 'gle.com/',
325 '')
326 self.TestLint(
327 '// https://g' + ('o' * 60) + 'gle.com/ and some comments',
328 'Lines should be <= 80 characters long'
329 ' [whitespace/line_length] [2]')
erg@google.com36649102009-03-25 21:18:36 +0000330 self.TestLint(
331 '// Read https://g' + ('o' * 60) + 'gle.com/' ,
332 '')
erg@google.comd7d27472011-09-07 17:36:35 +0000333 self.TestLint(
334 '// $Id: g' + ('o' * 80) + 'gle.cc#1 $',
335 '')
336 self.TestLint(
337 '// $Id: g' + ('o' * 80) + 'gle.cc#1',
338 'Lines should be <= 80 characters long'
339 ' [whitespace/line_length] [2]')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000340 self.TestMultiLineLint(
341 'static const char kCStr[] = "g' + ('o' * 50) + 'gle";\n',
342 'Lines should be <= 80 characters long'
343 ' [whitespace/line_length] [2]')
344 self.TestMultiLineLint(
345 'static const char kRawStr[] = R"(g' + ('o' * 50) + 'gle)";\n',
346 '') # no warning because raw string content is elided
347 self.TestMultiLineLint(
348 'static const char kMultiLineRawStr[] = R"(\n'
349 'g' + ('o' * 80) + 'gle\n'
350 ')";',
351 '')
352 self.TestMultiLineLint(
353 'static const char kL' + ('o' * 50) + 'ngIdentifier[] = R"()";\n',
354 'Lines should be <= 80 characters long'
355 ' [whitespace/line_length] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000356
erg+personal@google.com05189642010-04-30 20:43:03 +0000357 # Test error suppression annotations.
358 def testErrorSuppression(self):
359 # Two errors on same line:
360 self.TestLint(
361 'long a = (int64) 65;',
362 ['Using C-style cast. Use static_cast<int64>(...) instead'
363 ' [readability/casting] [4]',
364 'Use int16/int64/etc, rather than the C type long'
365 ' [runtime/int] [4]',
erg@google.com8a95ecc2011-09-08 00:45:54 +0000366 ])
erg+personal@google.com05189642010-04-30 20:43:03 +0000367 # One category of error suppressed:
368 self.TestLint(
369 'long a = (int64) 65; // NOLINT(runtime/int)',
370 'Using C-style cast. Use static_cast<int64>(...) instead'
371 ' [readability/casting] [4]')
372 # All categories suppressed: (two aliases)
373 self.TestLint('long a = (int64) 65; // NOLINT', '')
374 self.TestLint('long a = (int64) 65; // NOLINT(*)', '')
375 # Malformed NOLINT directive:
376 self.TestLint(
377 'long a = 65; // NOLINT(foo)',
erg@google.com8a95ecc2011-09-08 00:45:54 +0000378 ['Unknown NOLINT error category: foo'
379 ' [readability/nolint] [5]',
380 'Use int16/int64/etc, rather than the C type long [runtime/int] [4]',
381 ])
erg+personal@google.com05189642010-04-30 20:43:03 +0000382 # Irrelevant NOLINT directive has no effect:
383 self.TestLint(
384 'long a = 65; // NOLINT(readability/casting)',
erg@google.com8a95ecc2011-09-08 00:45:54 +0000385 'Use int16/int64/etc, rather than the C type long'
avakulenko@google.com02af6282014-06-04 18:53:25 +0000386 ' [runtime/int] [4]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000387 # NOLINTNEXTLINE silences warning for the next line instead of current line
388 error_collector = ErrorCollector(self.assert_)
389 cpplint.ProcessFileData('test.cc', 'cc',
390 ['// Copyright 2014 Your Company.',
391 '// NOLINTNEXTLINE(whitespace/line_length)',
392 '// ./command' + (' -verbose' * 80),
393 ''],
394 error_collector)
395 self.assertEquals('', error_collector.Results())
erg+personal@google.com05189642010-04-30 20:43:03 +0000396
erg@google.com4e00b9a2009-01-12 23:05:11 +0000397 # Test Variable Declarations.
398 def testVariableDeclarations(self):
399 self.TestLint(
400 'long a = 65;',
401 'Use int16/int64/etc, rather than the C type long'
402 ' [runtime/int] [4]')
403 self.TestLint(
404 'long double b = 65.0;',
405 '')
406 self.TestLint(
407 'long long aa = 6565;',
408 'Use int16/int64/etc, rather than the C type long'
409 ' [runtime/int] [4]')
410
411 # Test C-style cast cases.
412 def testCStyleCast(self):
413 self.TestLint(
414 'int a = (int)1.0;',
415 'Using C-style cast. Use static_cast<int>(...) instead'
416 ' [readability/casting] [4]')
417 self.TestLint(
erg@google.com8f91ab22011-09-06 21:04:45 +0000418 'int *a = (int *)NULL;',
erg@google.com4e00b9a2009-01-12 23:05:11 +0000419 'Using C-style cast. Use reinterpret_cast<int *>(...) instead'
420 ' [readability/casting] [4]')
421
422 self.TestLint(
423 'uint16 a = (uint16)1.0;',
424 'Using C-style cast. Use static_cast<uint16>(...) instead'
425 ' [readability/casting] [4]')
426 self.TestLint(
427 'int32 a = (int32)1.0;',
428 'Using C-style cast. Use static_cast<int32>(...) instead'
429 ' [readability/casting] [4]')
430 self.TestLint(
431 'uint64 a = (uint64)1.0;',
432 'Using C-style cast. Use static_cast<uint64>(...) instead'
433 ' [readability/casting] [4]')
434
435 # These shouldn't be recognized casts.
436 self.TestLint('u a = (u)NULL;', '')
437 self.TestLint('uint a = (uint)NULL;', '')
erg@google.comc6671232013-10-25 21:44:03 +0000438 self.TestLint('typedef MockCallback<int(int)> CallbackType;', '')
439 self.TestLint('scoped_ptr< MockCallback<int(int)> > callback_value;', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000440 self.TestLint('std::function<int(bool)>', '')
441 self.TestLint('x = sizeof(int)', '')
442 self.TestLint('x = alignof(int)', '')
443 self.TestLint('alignas(int) char x[42]', '')
444 self.TestLint('alignas(alignof(x)) char y[42]', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000445
446 # Test taking address of casts (runtime/casting)
447 def testRuntimeCasting(self):
erg@google.comc6671232013-10-25 21:44:03 +0000448 error_msg = ('Are you taking an address of a cast? '
449 'This is dangerous: could be a temp var. '
450 'Take the address before doing the cast, rather than after'
451 ' [runtime/casting] [4]')
452 self.TestLint('int* x = &static_cast<int*>(foo);', error_msg)
453 self.TestLint('int* x = &reinterpret_cast<int *>(foo);', error_msg)
454 self.TestLint('int* x = &(int*)foo;',
455 ['Using C-style cast. Use reinterpret_cast<int*>(...) '
456 'instead [readability/casting] [4]',
457 error_msg])
erg@google.com4e00b9a2009-01-12 23:05:11 +0000458
avakulenko@google.com02af6282014-06-04 18:53:25 +0000459 # Alternative error message
460 alt_error_msg = ('Are you taking an address of something dereferenced '
461 'from a cast? Wrapping the dereferenced expression in '
462 'parentheses will make the binding more obvious'
463 ' [readability/casting] [4]')
464 self.TestLint('int* x = &down_cast<Obj*>(obj)->member_;', alt_error_msg)
465 self.TestLint('int* x = &down_cast<Obj*>(obj)[index];', alt_error_msg)
466 self.TestLint('int* x = &(down_cast<Obj*>(obj)->member_);', '')
467 self.TestLint('int* x = &(down_cast<Obj*>(obj)[index]);', '')
468 self.TestLint('int* x = &down_cast<Obj*>(obj)\n->member_;', alt_error_msg)
469 self.TestLint('int* x = &(down_cast<Obj*>(obj)\n->member_);', '')
470
erg@google.com4e00b9a2009-01-12 23:05:11 +0000471 # It's OK to cast an address.
erg@google.comc6671232013-10-25 21:44:03 +0000472 self.TestLint('int* x = reinterpret_cast<int *>(&foo);', '')
473
474 # Function pointers returning references should not be confused
475 # with taking address of old-style casts.
476 self.TestLint('auto x = implicit_cast<string &(*)(int)>(&foo);', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000477
478 def testRuntimeSelfinit(self):
479 self.TestLint(
480 'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }',
481 'You seem to be initializing a member variable with itself.'
482 ' [runtime/init] [4]')
483 self.TestLint(
484 'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }',
485 '')
486 self.TestLint(
487 'Foo::Foo(Bar r) : r_(r), l_(r_), ll_(l_) { }',
488 '')
489
erg@google.com4e00b9a2009-01-12 23:05:11 +0000490 # Test for unnamed arguments in a method.
491 def testCheckForUnnamedParams(self):
492 message = ('All parameters should be named in a function'
493 ' [readability/function] [3]')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000494 self.TestLint('virtual void Func(int*) const;', message)
495 self.TestLint('virtual void Func(int*);', message)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000496 self.TestLint('void Method(char*) {', message)
497 self.TestLint('void Method(char*);', message)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000498 self.TestLint('static void operator delete[](void*) throw();', message)
avakulenko@google.com02af6282014-06-04 18:53:25 +0000499 self.TestLint('int Method(int);', message)
erg@google.com4e00b9a2009-01-12 23:05:11 +0000500
avakulenko@google.com02af6282014-06-04 18:53:25 +0000501 self.TestLint('virtual void Func(int* p);', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000502 self.TestLint('void operator delete(void* x) throw();', '')
503 self.TestLint('void Method(char* x) {', '')
504 self.TestLint('void Method(char* /*x*/) {', '')
505 self.TestLint('void Method(char* x);', '')
506 self.TestLint('typedef void (*Method)(int32 x);', '')
507 self.TestLint('static void operator delete[](void* x) throw();', '')
508 self.TestLint('static void operator delete[](void* /*x*/) throw();', '')
509
erg@google.comd350fe52013-01-14 17:51:48 +0000510 self.TestLint('X operator++(int);', '')
511 self.TestLint('X operator++(int) {', '')
512 self.TestLint('X operator--(int);', '')
513 self.TestLint('X operator--(int /*unused*/) {', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000514 self.TestLint('MACRO(int);', '')
erg@google.comd350fe52013-01-14 17:51:48 +0000515
erg@google.comc6671232013-10-25 21:44:03 +0000516 self.TestLint('void (*func)(void*);', '')
517 self.TestLint('void Func((*func)(void*)) {}', '')
518 self.TestLint('template <void Func(void*)> void func();', '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000519 self.TestLint('virtual void f(int /*unused*/) {', '')
520 self.TestLint('void f(int /*unused*/) override {', '')
521 self.TestLint('void f(int /*unused*/) final {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000522
523 # Test deprecated casts such as int(d)
524 def testDeprecatedCast(self):
525 self.TestLint(
526 'int a = int(2.2);',
527 'Using deprecated casting style. '
528 'Use static_cast<int>(...) instead'
529 ' [readability/casting] [4]')
erg@google.com8a95ecc2011-09-08 00:45:54 +0000530
531 self.TestLint(
532 '(char *) "foo"',
533 'Using C-style cast. '
534 'Use const_cast<char *>(...) instead'
535 ' [readability/casting] [4]')
536
537 self.TestLint(
538 '(int*)foo',
539 'Using C-style cast. '
540 'Use reinterpret_cast<int*>(...) instead'
541 ' [readability/casting] [4]')
542
erg@google.com4e00b9a2009-01-12 23:05:11 +0000543 # Checks for false positives...
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000544 self.TestLint('int a = int();', '') # constructor
545 self.TestLint('X::X() : a(int()) {}', '') # default constructor
546 self.TestLint('operator bool();', '') # Conversion operator
547 self.TestLint('new int64(123);', '') # "new" operator on basic type
548 self.TestLint('new int64(123);', '') # "new" operator on basic type
549 self.TestLint('using a = bool(int arg);', '') # C++11 alias-declaration
550 self.TestLint('x = bit_cast<double(*)[3]>(y);', '') # array of array
551 self.TestLint('void F(const char(&src)[N]);', '') # array of references
552
553 # Placement new
avakulenko@google.com02af6282014-06-04 18:53:25 +0000554 self.TestLint(
555 'new(field_ptr) int(field->default_value_enum()->number());',
556 '')
557
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000558 # C++11 function wrappers
559 self.TestLint('std::function<int(bool)>', '')
560 self.TestLint('std::function<const int(bool)>', '')
561 self.TestLint('std::function< int(bool) >', '')
562 self.TestLint('mfunction<int(bool)>', '')
563
avakulenko@google.com02af6282014-06-04 18:53:25 +0000564 error_collector = ErrorCollector(self.assert_)
565 cpplint.ProcessFileData(
566 'test.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000567 ['// Copyright 2014 Your Company. All Rights Reserved.',
avakulenko@google.com02af6282014-06-04 18:53:25 +0000568 'typedef std::function<',
569 ' bool(int)> F;',
570 ''],
571 error_collector)
572 self.assertEquals('', error_collector.Results())
erg@google.comc6671232013-10-25 21:44:03 +0000573
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000574 # Return types for function pointers
575 self.TestLint('typedef bool(FunctionPointer)();', '')
576 self.TestLint('typedef bool(FunctionPointer)(int param);', '')
577 self.TestLint('typedef bool(MyClass::*MemberFunctionPointer)();', '')
578 self.TestLint('typedef bool(MyClass::* MemberFunctionPointer)();', '')
579 self.TestLint('typedef bool(MyClass::*MemberFunctionPointer)() const;', '')
580 self.TestLint('void Function(bool(FunctionPointerArg)());', '')
581 self.TestLint('void Function(bool(FunctionPointerArg)()) {}', '')
582 self.TestLint('typedef set<int64, bool(*)(int64, int64)> SortedIdSet', '')
erg@google.comc6671232013-10-25 21:44:03 +0000583 self.TestLint(
584 'bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *t)) {}',
585 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000586
587 # The second parameter to a gMock method definition is a function signature
588 # that often looks like a bad cast but should not picked up by lint.
589 def testMockMethod(self):
590 self.TestLint(
591 'MOCK_METHOD0(method, int());',
592 '')
593 self.TestLint(
594 'MOCK_CONST_METHOD1(method, float(string));',
595 '')
596 self.TestLint(
597 'MOCK_CONST_METHOD2_T(method, double(float, float));',
598 '')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000599 self.TestLint(
600 'MOCK_CONST_METHOD1(method, SomeType(int));',
601 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000602
erg@google.comd350fe52013-01-14 17:51:48 +0000603 error_collector = ErrorCollector(self.assert_)
604 cpplint.ProcessFileData('mock.cc', 'cc',
605 ['MOCK_METHOD1(method1,',
erg@google.comc6671232013-10-25 21:44:03 +0000606 ' bool(int));',
607 'MOCK_METHOD1(',
608 ' method2,',
609 ' bool(int));',
610 'MOCK_CONST_METHOD2(',
611 ' method3, bool(int,',
612 ' int));',
613 'MOCK_METHOD1(method4, int(bool));',
erg@google.comd350fe52013-01-14 17:51:48 +0000614 'const int kConstant = int(42);'], # true positive
615 error_collector)
616 self.assertEquals(
617 0,
618 error_collector.Results().count(
619 ('Using deprecated casting style. '
620 'Use static_cast<bool>(...) instead '
621 '[readability/casting] [4]')))
622 self.assertEquals(
623 1,
624 error_collector.Results().count(
625 ('Using deprecated casting style. '
626 'Use static_cast<int>(...) instead '
627 '[readability/casting] [4]')))
628
erg@google.comd7d27472011-09-07 17:36:35 +0000629 # Like gMock method definitions, MockCallback instantiations look very similar
630 # to bad casts.
631 def testMockCallback(self):
632 self.TestLint(
633 'MockCallback<bool(int)>',
634 '')
635 self.TestLint(
636 'MockCallback<int(float, char)>',
637 '')
638
erg@google.come35f7652009-06-19 20:52:09 +0000639 # Test false errors that happened with some include file names
640 def testIncludeFilenameFalseError(self):
641 self.TestLint(
642 '#include "foo/long-foo.h"',
643 '')
644 self.TestLint(
645 '#include "foo/sprintf.h"',
646 '')
647
erg@google.com4e00b9a2009-01-12 23:05:11 +0000648 # Test typedef cases. There was a bug that cpplint misidentified
649 # typedef for pointer to function as C-style cast and produced
650 # false-positive error messages.
651 def testTypedefForPointerToFunction(self):
652 self.TestLint(
653 'typedef void (*Func)(int x);',
654 '')
655 self.TestLint(
656 'typedef void (*Func)(int *x);',
657 '')
658 self.TestLint(
659 'typedef void Func(int x);',
660 '')
661 self.TestLint(
662 'typedef void Func(int *x);',
663 '')
664
665 def testIncludeWhatYouUseNoImplementationFiles(self):
666 code = 'std::vector<int> foo;'
667 self.assertEquals('Add #include <vector> for vector<>'
668 ' [build/include_what_you_use] [4]',
669 self.PerformIncludeWhatYouUse(code, 'foo.h'))
670 self.assertEquals('',
671 self.PerformIncludeWhatYouUse(code, 'foo.cc'))
672
673 def testIncludeWhatYouUse(self):
674 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000675 """#include <vector>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000676 std::vector<int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000677 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000678 '')
679 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000680 """#include <map>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000681 std::pair<int,int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000682 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000683 'Add #include <utility> for pair<>'
684 ' [build/include_what_you_use] [4]')
685 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000686 """#include <multimap>
687 std::pair<int,int> foo;
688 """,
689 'Add #include <utility> for pair<>'
690 ' [build/include_what_you_use] [4]')
691 self.TestIncludeWhatYouUse(
692 """#include <hash_map>
693 std::pair<int,int> foo;
694 """,
695 'Add #include <utility> for pair<>'
696 ' [build/include_what_you_use] [4]')
697 self.TestIncludeWhatYouUse(
698 """#include <utility>
699 std::pair<int,int> foo;
700 """,
701 '')
702 self.TestIncludeWhatYouUse(
703 """#include <vector>
704 DECLARE_string(foobar);
705 """,
706 '')
707 self.TestIncludeWhatYouUse(
708 """#include <vector>
709 DEFINE_string(foobar, "", "");
710 """,
711 '')
712 self.TestIncludeWhatYouUse(
713 """#include <vector>
714 std::pair<int,int> foo;
715 """,
716 'Add #include <utility> for pair<>'
717 ' [build/include_what_you_use] [4]')
718 self.TestIncludeWhatYouUse(
719 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000720 std::vector<int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000721 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000722 'Add #include <vector> for vector<>'
723 ' [build/include_what_you_use] [4]')
724 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000725 """#include <vector>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000726 std::set<int> foo;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000727 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000728 'Add #include <set> for set<>'
729 ' [build/include_what_you_use] [4]')
730 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000731 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000732 hash_map<int, int> foobar;
erg@google.com8a95ecc2011-09-08 00:45:54 +0000733 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000734 'Add #include <hash_map> for hash_map<>'
735 ' [build/include_what_you_use] [4]')
736 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000737 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000738 bool foobar = std::less<int>(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000739 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000740 'Add #include <functional> for less<>'
741 ' [build/include_what_you_use] [4]')
742 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000743 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000744 bool foobar = min<int>(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000745 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000746 'Add #include <algorithm> for min [build/include_what_you_use] [4]')
747 self.TestIncludeWhatYouUse(
748 'void a(const string &foobar);',
749 'Add #include <string> for string [build/include_what_you_use] [4]')
750 self.TestIncludeWhatYouUse(
erg+personal@google.com05189642010-04-30 20:43:03 +0000751 'void a(const std::string &foobar);',
752 'Add #include <string> for string [build/include_what_you_use] [4]')
753 self.TestIncludeWhatYouUse(
754 'void a(const my::string &foobar);',
755 '') # Avoid false positives on strings in other namespaces.
756 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000757 """#include "base/foobar.h"
erg@google.com4e00b9a2009-01-12 23:05:11 +0000758 bool foobar = swap(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000759 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000760 'Add #include <algorithm> for swap [build/include_what_you_use] [4]')
761 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000762 """#include "base/foobar.h"
erg@google.coma87abb82009-02-24 01:41:01 +0000763 bool foobar = transform(a.begin(), a.end(), b.start(), Foo);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000764 """,
erg@google.coma87abb82009-02-24 01:41:01 +0000765 'Add #include <algorithm> for transform '
766 '[build/include_what_you_use] [4]')
767 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000768 """#include "base/foobar.h"
erg@google.coma87abb82009-02-24 01:41:01 +0000769 bool foobar = min_element(a.begin(), a.end());
erg@google.com8a95ecc2011-09-08 00:45:54 +0000770 """,
erg@google.coma87abb82009-02-24 01:41:01 +0000771 'Add #include <algorithm> for min_element '
772 '[build/include_what_you_use] [4]')
773 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000774 """foo->swap(0,1);
erg@google.com4e00b9a2009-01-12 23:05:11 +0000775 foo.swap(0,1);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000776 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000777 '')
778 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000779 """#include <string>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000780 void a(const std::multimap<int,string> &foobar);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000781 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000782 'Add #include <map> for multimap<>'
783 ' [build/include_what_you_use] [4]')
784 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000785 """#include <queue>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000786 void a(const std::priority_queue<int> &foobar);
erg@google.com8a95ecc2011-09-08 00:45:54 +0000787 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000788 '')
789 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000790 """#include <assert.h>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000791 #include <string>
792 #include <vector>
793 #include "base/basictypes.h"
794 #include "base/port.h"
erg@google.com8a95ecc2011-09-08 00:45:54 +0000795 vector<string> hajoa;""", '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000796 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000797 """#include <string>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000798 int i = numeric_limits<int>::max()
erg@google.com8a95ecc2011-09-08 00:45:54 +0000799 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000800 'Add #include <limits> for numeric_limits<>'
801 ' [build/include_what_you_use] [4]')
802 self.TestIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000803 """#include <limits>
erg@google.com4e00b9a2009-01-12 23:05:11 +0000804 int i = numeric_limits<int>::max()
erg@google.com8a95ecc2011-09-08 00:45:54 +0000805 """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000806 '')
807
erg@google.come35f7652009-06-19 20:52:09 +0000808 # Test the UpdateIncludeState code path.
809 mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"']
810 message = self.PerformIncludeWhatYouUse(
811 '#include "blah/a.h"',
812 filename='blah/a.cc',
813 io=MockIo(mock_header_contents))
814 self.assertEquals(message, '')
815
816 mock_header_contents = ['#include <set>']
817 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000818 """#include "blah/a.h"
819 std::set<int> foo;""",
erg@google.come35f7652009-06-19 20:52:09 +0000820 filename='blah/a.cc',
821 io=MockIo(mock_header_contents))
822 self.assertEquals(message, '')
823
824 # Make sure we can find the correct header file if the cc file seems to be
825 # a temporary file generated by Emacs's flymake.
826 mock_header_contents = ['']
827 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000828 """#include "blah/a.h"
829 std::set<int> foo;""",
erg@google.come35f7652009-06-19 20:52:09 +0000830 filename='blah/a_flymake.cc',
831 io=MockIo(mock_header_contents))
832 self.assertEquals(message, 'Add #include <set> for set<> '
erg@google.com8a95ecc2011-09-08 00:45:54 +0000833 '[build/include_what_you_use] [4]')
erg@google.come35f7652009-06-19 20:52:09 +0000834
835 # If there's just a cc and the header can't be found then it's ok.
836 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000837 """#include "blah/a.h"
838 std::set<int> foo;""",
erg@google.come35f7652009-06-19 20:52:09 +0000839 filename='blah/a.cc')
840 self.assertEquals(message, '')
841
842 # Make sure we find the headers with relative paths.
843 mock_header_contents = ['']
844 message = self.PerformIncludeWhatYouUse(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000845 """#include "%s/a.h"
846 std::set<int> foo;""" % os.path.basename(os.getcwd()),
erg@google.come35f7652009-06-19 20:52:09 +0000847 filename='a.cc',
848 io=MockIo(mock_header_contents))
849 self.assertEquals(message, 'Add #include <set> for set<> '
erg@google.com8a95ecc2011-09-08 00:45:54 +0000850 '[build/include_what_you_use] [4]')
erg@google.come35f7652009-06-19 20:52:09 +0000851
852 def testFilesBelongToSameModule(self):
853 f = cpplint.FilesBelongToSameModule
854 self.assertEquals((True, ''), f('a.cc', 'a.h'))
855 self.assertEquals((True, ''), f('base/google.cc', 'base/google.h'))
856 self.assertEquals((True, ''), f('base/google_test.cc', 'base/google.h'))
857 self.assertEquals((True, ''),
858 f('base/google_unittest.cc', 'base/google.h'))
859 self.assertEquals((True, ''),
860 f('base/internal/google_unittest.cc',
861 'base/public/google.h'))
862 self.assertEquals((True, 'xxx/yyy/'),
863 f('xxx/yyy/base/internal/google_unittest.cc',
864 'base/public/google.h'))
865 self.assertEquals((True, 'xxx/yyy/'),
866 f('xxx/yyy/base/google_unittest.cc',
867 'base/public/google.h'))
868 self.assertEquals((True, ''),
869 f('base/google_unittest.cc', 'base/google-inl.h'))
870 self.assertEquals((True, '/home/build/google3/'),
871 f('/home/build/google3/base/google.cc', 'base/google.h'))
872
873 self.assertEquals((False, ''),
874 f('/home/build/google3/base/google.cc', 'basu/google.h'))
875 self.assertEquals((False, ''), f('a.cc', 'b.h'))
876
erg@google.com4e00b9a2009-01-12 23:05:11 +0000877 def testCleanseLine(self):
erg@google.comd7d27472011-09-07 17:36:35 +0000878 self.assertEquals('int foo = 0;',
erg@google.com4e00b9a2009-01-12 23:05:11 +0000879 cpplint.CleanseComments('int foo = 0; // danger!'))
880 self.assertEquals('int o = 0;',
881 cpplint.CleanseComments('int /* foo */ o = 0;'))
882 self.assertEquals('foo(int a, int b);',
883 cpplint.CleanseComments('foo(int a /* abc */, int b);'))
884 self.assertEqual('f(a, b);',
885 cpplint.CleanseComments('f(a, /* name */ b);'))
886 self.assertEqual('f(a, b);',
erg@google.com2aa59982013-10-28 19:09:25 +0000887 cpplint.CleanseComments('f(a /* name */, b);'))
erg@google.com4e00b9a2009-01-12 23:05:11 +0000888 self.assertEqual('f(a, b);',
889 cpplint.CleanseComments('f(a, /* name */b);'))
avakulenko@google.com02af6282014-06-04 18:53:25 +0000890 self.assertEqual('f(a, b, c);',
891 cpplint.CleanseComments('f(a, /**/b, /**/c);'))
892 self.assertEqual('f(a, b, c);',
893 cpplint.CleanseComments('f(a, /**/b/**/, c);'))
erg@google.com4e00b9a2009-01-12 23:05:11 +0000894
erg@google.com2aa59982013-10-28 19:09:25 +0000895 def testRawStrings(self):
896 self.TestMultiLineLint(
897 """
898 void Func() {
899 static const char kString[] = R"(
900 #endif <- invalid preprocessor should be ignored
901 */ <- invalid comment should be ignored too
902 )";
903 }""",
904 '')
905 self.TestMultiLineLint(
906 """
907 void Func() {
908 string s = R"TrueDelimiter(
909 )"
910 )FalseDelimiter"
911 )TrueDelimiter";
912 }""",
913 '')
914 self.TestMultiLineLint(
915 """
916 void Func() {
917 char char kString[] = R"( ";" )";
918 }""",
919 '')
920 self.TestMultiLineLint(
921 """
922 static const char kRawString[] = R"(
923 \tstatic const int kLineWithTab = 1;
924 static const int kLineWithTrailingWhiteSpace = 1;\x20
925
926 void WeirdNumberOfSpacesAtLineStart() {
927 string x;
928 x += StrCat("Use StrAppend instead");
929 }
930
931 void BlankLineAtEndOfBlock() {
932 // TODO incorrectly formatted
933 //Badly formatted comment
934
935 }
936
937 )";""",
938 '')
avakulenko@google.com02af6282014-06-04 18:53:25 +0000939 self.TestMultiLineLint(
940 """
941 void Func() {
942 string s = StrCat(R"TrueDelimiter(
943 )"
944 )FalseDelimiter"
945 )TrueDelimiter", R"TrueDelimiter2(
946 )"
947 )FalseDelimiter2"
948 )TrueDelimiter2");
949 }""",
950 '')
951 self.TestMultiLineLint(
952 """
953 static SomeStruct kData = {
954 {0, R"(line1
955 line2
956 )"}
957 };""",
958 '')
erg@google.com2aa59982013-10-28 19:09:25 +0000959
erg@google.com4e00b9a2009-01-12 23:05:11 +0000960 def testMultiLineComments(self):
961 # missing explicit is bad
962 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000963 r"""int a = 0;
erg@google.com4e00b9a2009-01-12 23:05:11 +0000964 /* multi-liner
965 class Foo {
966 Foo(int f); // should cause a lint warning in code
967 }
erg@google.com8a95ecc2011-09-08 00:45:54 +0000968 */ """,
erg@google.com4e00b9a2009-01-12 23:05:11 +0000969 '')
970 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +0000971 r"""/* int a = 0; multi-liner
972 static const int b = 0;""",
erg@google.com4e00b9a2009-01-12 23:05:11 +0000973 'Could not find end of multi-line comment'
974 ' [readability/multiline_comment] [5]')
erg@google.com8a95ecc2011-09-08 00:45:54 +0000975 self.TestMultiLineLint(r""" /* multi-line comment""",
erg@google.com4e00b9a2009-01-12 23:05:11 +0000976 'Could not find end of multi-line comment'
977 ' [readability/multiline_comment] [5]')
erg@google.com8a95ecc2011-09-08 00:45:54 +0000978 self.TestMultiLineLint(r""" // /* comment, but not multi-line""", '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +0000979 self.TestMultiLineLint(r"""/**********
980 */""", '')
erg@google.com4e00b9a2009-01-12 23:05:11 +0000981
982 def testMultilineStrings(self):
983 multiline_string_error_message = (
984 'Multi-line string ("...") found. This lint script doesn\'t '
erg@google.com2aa59982013-10-28 19:09:25 +0000985 'do well with such strings, and may give bogus warnings. '
986 'Use C++11 raw strings or concatenation instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +0000987 ' [readability/multiline_string] [5]')
988
989 file_path = 'mydir/foo.cc'
990
991 error_collector = ErrorCollector(self.assert_)
992 cpplint.ProcessFileData(file_path, 'cc',
993 ['const char* str = "This is a\\',
994 ' multiline string.";'],
995 error_collector)
996 self.assertEquals(
997 2, # One per line.
998 error_collector.ResultList().count(multiline_string_error_message))
999
1000 # Test non-explicit single-argument constructors
1001 def testExplicitSingleArgumentConstructors(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001002 old_verbose_level = cpplint._cpplint_state.verbose_level
1003 cpplint._cpplint_state.verbose_level = 0
1004
1005 try:
1006 # missing explicit is bad
1007 self.TestMultiLineLint(
1008 """
1009 class Foo {
1010 Foo(int f);
1011 };""",
1012 'Single-parameter constructors should be marked explicit.'
1013 ' [runtime/explicit] [5]')
1014 # missing explicit is bad, even with whitespace
1015 self.TestMultiLineLint(
1016 """
1017 class Foo {
1018 Foo (int f);
1019 };""",
1020 ['Extra space before ( in function call [whitespace/parens] [4]',
1021 'Single-parameter constructors should be marked explicit.'
1022 ' [runtime/explicit] [5]'])
1023 # missing explicit, with distracting comment, is still bad
1024 self.TestMultiLineLint(
1025 """
1026 class Foo {
1027 Foo(int f); // simpler than Foo(blargh, blarg)
1028 };""",
1029 'Single-parameter constructors should be marked explicit.'
1030 ' [runtime/explicit] [5]')
1031 # missing explicit, with qualified classname
1032 self.TestMultiLineLint(
1033 """
1034 class Qualifier::AnotherOne::Foo {
1035 Foo(int f);
1036 };""",
1037 'Single-parameter constructors should be marked explicit.'
1038 ' [runtime/explicit] [5]')
1039 # missing explicit for inline constructors is bad as well
1040 self.TestMultiLineLint(
1041 """
1042 class Foo {
1043 inline Foo(int f);
1044 };""",
1045 'Single-parameter constructors should be marked explicit.'
1046 ' [runtime/explicit] [5]')
1047 # structs are caught as well.
1048 self.TestMultiLineLint(
1049 """
1050 struct Foo {
1051 Foo(int f);
1052 };""",
1053 'Single-parameter constructors should be marked explicit.'
1054 ' [runtime/explicit] [5]')
1055 # Templatized classes are caught as well.
1056 self.TestMultiLineLint(
1057 """
1058 template<typename T> class Foo {
1059 Foo(int f);
1060 };""",
1061 'Single-parameter constructors should be marked explicit.'
1062 ' [runtime/explicit] [5]')
1063 # inline case for templatized classes.
1064 self.TestMultiLineLint(
1065 """
1066 template<typename T> class Foo {
1067 inline Foo(int f);
1068 };""",
1069 'Single-parameter constructors should be marked explicit.'
1070 ' [runtime/explicit] [5]')
1071 # constructors with a default argument should still be marked explicit
1072 self.TestMultiLineLint(
1073 """
1074 class Foo {
1075 Foo(int f = 0);
1076 };""",
1077 'Constructors callable with one argument should be marked explicit.'
1078 ' [runtime/explicit] [5]')
1079 # multi-argument constructors with all but one default argument should be
1080 # marked explicit
1081 self.TestMultiLineLint(
1082 """
1083 class Foo {
1084 Foo(int f, int g = 0);
1085 };""",
1086 'Constructors callable with one argument should be marked explicit.'
1087 ' [runtime/explicit] [5]')
1088 # multi-argument constructors with all default arguments should be marked
1089 # explicit
1090 self.TestMultiLineLint(
1091 """
1092 class Foo {
1093 Foo(int f = 0, int g = 0);
1094 };""",
1095 'Constructors callable with one argument should be marked explicit.'
1096 ' [runtime/explicit] [5]')
1097 # explicit no-argument constructors are bad
1098 self.TestMultiLineLint(
1099 """
1100 class Foo {
1101 explicit Foo();
1102 };""",
1103 'Zero-parameter constructors should not be marked explicit.'
1104 ' [runtime/explicit] [5]')
1105 # void constructors are considered no-argument
1106 self.TestMultiLineLint(
1107 """
1108 class Foo {
1109 explicit Foo(void);
1110 };""",
1111 'Zero-parameter constructors should not be marked explicit.'
1112 ' [runtime/explicit] [5]')
1113 # Warn explicit multi-argument constructors at lowest severity
1114 self.TestMultiLineLint(
1115 """
1116 class Foo {
1117 explicit Foo(int f, int g);
1118 };""",
1119 'Constructors that require multiple arguments '
1120 'should not be marked explicit. [runtime/explicit] [0]')
1121 # but explicit multi-argument constructors with only one non-default
1122 # argument are OK
1123 self.TestMultiLineLint(
1124 """
1125 class Foo {
1126 explicit Foo(int f, int g = 0);
1127 };""",
1128 '')
1129 # single-argument constructors that take a function that takes multiple
1130 # arguments should be explicit
1131 self.TestMultiLineLint(
1132 """
1133 class Foo {
1134 Foo(void (*f)(int f, int g));
1135 };""",
1136 'Single-parameter constructors should be marked explicit.'
1137 ' [runtime/explicit] [5]')
1138 # single-argument constructors that take a single template argument with
1139 # multiple parameters should be explicit
1140 self.TestMultiLineLint(
1141 """
1142 template <typename T, typename S>
1143 class Foo {
1144 Foo(Bar<T, S> b);
1145 };""",
1146 'Single-parameter constructors should be marked explicit.'
1147 ' [runtime/explicit] [5]')
1148 # but copy constructors that take multiple template parameters are OK
1149 self.TestMultiLineLint(
1150 """
1151 template <typename T, S>
1152 class Foo {
1153 Foo(Foo<T, S>& f);
1154 };""",
1155 '')
1156 # proper style is okay
1157 self.TestMultiLineLint(
1158 """
1159 class Foo {
1160 explicit Foo(int f);
1161 };""",
1162 '')
1163 # two argument constructor is okay
1164 self.TestMultiLineLint(
1165 """
1166 class Foo {
1167 Foo(int f, int b);
1168 };""",
1169 '')
1170 # two argument constructor, across two lines, is okay
1171 self.TestMultiLineLint(
1172 """
1173 class Foo {
1174 Foo(int f,
1175 int b);
1176 };""",
1177 '')
1178 # non-constructor (but similar name), is okay
1179 self.TestMultiLineLint(
1180 """
1181 class Foo {
1182 aFoo(int f);
1183 };""",
1184 '')
1185 # constructor with void argument is okay
1186 self.TestMultiLineLint(
1187 """
1188 class Foo {
1189 Foo(void);
1190 };""",
1191 '')
1192 # single argument method is okay
1193 self.TestMultiLineLint(
1194 """
1195 class Foo {
1196 Bar(int b);
1197 };""",
1198 '')
1199 # comments should be ignored
1200 self.TestMultiLineLint(
1201 """
1202 class Foo {
1203 // Foo(int f);
1204 };""",
1205 '')
1206 # single argument function following class definition is okay
1207 # (okay, it's not actually valid, but we don't want a false positive)
1208 self.TestMultiLineLint(
1209 """
1210 class Foo {
1211 Foo(int f, int b);
1212 };
1213 Foo(int f);""",
1214 '')
1215 # single argument function is okay
1216 self.TestMultiLineLint(
1217 """static Foo(int f);""",
1218 '')
1219 # single argument copy constructor is okay.
1220 self.TestMultiLineLint(
1221 """
1222 class Foo {
1223 Foo(const Foo&);
1224 };""",
1225 '')
1226 self.TestMultiLineLint(
1227 """
1228 class Foo {
1229 Foo(Foo const&);
1230 };""",
1231 '')
1232 self.TestMultiLineLint(
1233 """
1234 class Foo {
1235 Foo(Foo&);
1236 };""",
1237 '')
1238 # templatized copy constructor is okay.
1239 self.TestMultiLineLint(
1240 """
1241 template<typename T> class Foo {
1242 Foo(const Foo<T>&);
1243 };""",
1244 '')
1245 # Special case for std::initializer_list
1246 self.TestMultiLineLint(
1247 """
1248 class Foo {
1249 Foo(std::initializer_list<T> &arg) {}
1250 };""",
1251 '')
1252 # Anything goes inside an assembly block
1253 error_collector = ErrorCollector(self.assert_)
1254 cpplint.ProcessFileData('foo.cc', 'cc',
1255 ['void Func() {',
1256 ' __asm__ (',
1257 ' "hlt"',
1258 ' );',
1259 ' asm {',
1260 ' movdqa [edx + 32], xmm2',
1261 ' }',
1262 '}'],
1263 error_collector)
1264 self.assertEquals(
1265 0,
1266 error_collector.ResultList().count(
1267 'Extra space before ( in function call [whitespace/parens] [4]'))
1268 self.assertEquals(
1269 0,
1270 error_collector.ResultList().count(
1271 'Closing ) should be moved to the previous line '
1272 '[whitespace/parens] [2]'))
1273 self.assertEquals(
1274 0,
1275 error_collector.ResultList().count(
1276 'Extra space before [ [whitespace/braces] [5]'))
1277 finally:
1278 cpplint._cpplint_state.verbose_level = old_verbose_level
erg@google.com4e00b9a2009-01-12 23:05:11 +00001279
1280 def testSlashStarCommentOnSingleLine(self):
1281 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001282 """/* static */ Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001283 '')
1284 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001285 """/*/ static */ Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001286 '')
1287 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001288 """/*/ static Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001289 'Could not find end of multi-line comment'
1290 ' [readability/multiline_comment] [5]')
1291 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001292 """ /*/ static Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001293 'Could not find end of multi-line comment'
1294 ' [readability/multiline_comment] [5]')
1295 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001296 """ /**/ static Foo(int f);""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001297 '')
1298
1299 # Test suspicious usage of "if" like this:
1300 # if (a == b) {
1301 # DoSomething();
1302 # } if (a == c) { // Should be "else if".
1303 # DoSomething(); // This gets called twice if a == b && a == c.
1304 # }
1305 def testSuspiciousUsageOfIf(self):
1306 self.TestLint(
1307 ' if (a == b) {',
1308 '')
1309 self.TestLint(
1310 ' } if (a == b) {',
1311 'Did you mean "else if"? If not, start a new line for "if".'
1312 ' [readability/braces] [4]')
1313
1314 # Test suspicious usage of memset. Specifically, a 0
1315 # as the final argument is almost certainly an error.
1316 def testSuspiciousUsageOfMemset(self):
1317 # Normal use is okay.
1318 self.TestLint(
1319 ' memset(buf, 0, sizeof(buf))',
1320 '')
1321
1322 # A 0 as the final argument is almost certainly an error.
1323 self.TestLint(
1324 ' memset(buf, sizeof(buf), 0)',
1325 'Did you mean "memset(buf, 0, sizeof(buf))"?'
1326 ' [runtime/memset] [4]')
1327 self.TestLint(
1328 ' memset(buf, xsize * ysize, 0)',
1329 'Did you mean "memset(buf, 0, xsize * ysize)"?'
1330 ' [runtime/memset] [4]')
1331
1332 # There is legitimate test code that uses this form.
1333 # This is okay since the second argument is a literal.
1334 self.TestLint(
1335 " memset(buf, 'y', 0)",
1336 '')
1337 self.TestLint(
1338 ' memset(buf, 4, 0)',
1339 '')
1340 self.TestLint(
1341 ' memset(buf, -1, 0)',
1342 '')
1343 self.TestLint(
1344 ' memset(buf, 0xF1, 0)',
1345 '')
1346 self.TestLint(
1347 ' memset(buf, 0xcd, 0)',
1348 '')
1349
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001350 def testRedundantVirtual(self):
1351 self.TestLint('virtual void F()', '')
1352 self.TestLint('virtual void F();', '')
1353 self.TestLint('virtual void F() {}', '')
1354
1355 message_template = ('"%s" is redundant since function is already '
1356 'declared as "%s" [readability/inheritance] [4]')
1357 for virt_specifier in ['override', 'final']:
1358 error_message = message_template % ('virtual', virt_specifier)
1359 self.TestLint('virtual int F() %s' % virt_specifier, error_message)
1360 self.TestLint('virtual int F() %s;' % virt_specifier, error_message)
1361 self.TestLint('virtual int F() %s {' % virt_specifier, error_message)
1362
1363 error_collector = ErrorCollector(self.assert_)
1364 cpplint.ProcessFileData(
1365 'foo.cc', 'cc',
1366 ['// Copyright 2014 Your Company.',
1367 'virtual void F(int a,',
1368 ' int b) ' + virt_specifier + ';',
1369 'virtual void F(int a,',
1370 ' int b) LOCKS_EXCLUDED(lock) ' + virt_specifier + ';',
1371 'virtual void F(int a,',
1372 ' int b)',
1373 ' LOCKS_EXCLUDED(lock) ' + virt_specifier + ';',
1374 ''],
1375 error_collector)
1376 self.assertEquals(
1377 [error_message, error_message, error_message],
1378 error_collector.Results())
1379
1380 error_message = message_template % ('override', 'final')
1381 self.TestLint('int F() override final', error_message)
1382 self.TestLint('int F() override final;', error_message)
1383 self.TestLint('int F() override final {}', error_message)
1384 self.TestLint('int F() final override', error_message)
1385 self.TestLint('int F() final override;', error_message)
1386 self.TestLint('int F() final override {}', error_message)
1387
erg@google.com4e00b9a2009-01-12 23:05:11 +00001388 def testCheckDeprecated(self):
1389 self.TestLanguageRulesCheck('foo.cc', '#include <iostream>',
1390 'Streams are highly discouraged.'
1391 ' [readability/streams] [3]')
1392 self.TestLanguageRulesCheck('foo_test.cc', '#include <iostream>', '')
1393 self.TestLanguageRulesCheck('foo_unittest.cc', '#include <iostream>', '')
1394
1395 def testCheckPosixThreading(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00001396 self.TestLint('var = sctime_r()', '')
1397 self.TestLint('var = strtok_r()', '')
1398 self.TestLint('var = strtok_r(foo, ba, r)', '')
1399 self.TestLint('var = brand()', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001400 self.TestLint('_rand()', '')
1401 self.TestLint('.rand()', '')
erg@google.comd350fe52013-01-14 17:51:48 +00001402 self.TestLint('->rand()', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00001403 self.TestLint('ACMRandom rand(seed)', '')
1404 self.TestLint('ISAACRandom rand()', '')
1405 self.TestLint('var = rand()',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001406 'Consider using rand_r(...) instead of rand(...)'
1407 ' for improved thread safety.'
1408 ' [runtime/threadsafe_fn] [2]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00001409 self.TestLint('var = strtok(str, delim)',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001410 'Consider using strtok_r(...) '
1411 'instead of strtok(...)'
1412 ' for improved thread safety.'
1413 ' [runtime/threadsafe_fn] [2]')
1414
erg@google.com2aa59982013-10-28 19:09:25 +00001415 def testVlogMisuse(self):
1416 self.TestLint('VLOG(1)', '')
1417 self.TestLint('VLOG(99)', '')
1418 self.TestLint('LOG(ERROR)', '')
1419 self.TestLint('LOG(INFO)', '')
1420 self.TestLint('LOG(WARNING)', '')
1421 self.TestLint('LOG(FATAL)', '')
1422 self.TestLint('LOG(DFATAL)', '')
1423 self.TestLint('VLOG(SOMETHINGWEIRD)', '')
1424 self.TestLint('MYOWNVLOG(ERROR)', '')
1425 errmsg = ('VLOG() should be used with numeric verbosity level. '
1426 'Use LOG() if you want symbolic severity levels.'
1427 ' [runtime/vlog] [5]')
1428 self.TestLint('VLOG(ERROR)', errmsg)
1429 self.TestLint('VLOG(INFO)', errmsg)
1430 self.TestLint('VLOG(WARNING)', errmsg)
1431 self.TestLint('VLOG(FATAL)', errmsg)
1432 self.TestLint('VLOG(DFATAL)', errmsg)
1433 self.TestLint(' VLOG(ERROR)', errmsg)
1434 self.TestLint(' VLOG(INFO)', errmsg)
1435 self.TestLint(' VLOG(WARNING)', errmsg)
1436 self.TestLint(' VLOG(FATAL)', errmsg)
1437 self.TestLint(' VLOG(DFATAL)', errmsg)
1438
1439
erg@google.com4e00b9a2009-01-12 23:05:11 +00001440 # Test potential format string bugs like printf(foo).
1441 def testFormatStrings(self):
1442 self.TestLint('printf("foo")', '')
1443 self.TestLint('printf("foo: %s", foo)', '')
1444 self.TestLint('DocidForPrintf(docid)', '') # Should not trigger.
erg@google.com8a95ecc2011-09-08 00:45:54 +00001445 self.TestLint('printf(format, value)', '') # Should not trigger.
erg@google.comd350fe52013-01-14 17:51:48 +00001446 self.TestLint('printf(__VA_ARGS__)', '') # Should not trigger.
erg@google.com8a95ecc2011-09-08 00:45:54 +00001447 self.TestLint('printf(format.c_str(), value)', '') # Should not trigger.
1448 self.TestLint('printf(format(index).c_str(), value)', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001449 self.TestLint(
1450 'printf(foo)',
1451 'Potential format string bug. Do printf("%s", foo) instead.'
1452 ' [runtime/printf] [4]')
1453 self.TestLint(
1454 'printf(foo.c_str())',
1455 'Potential format string bug. '
1456 'Do printf("%s", foo.c_str()) instead.'
1457 ' [runtime/printf] [4]')
1458 self.TestLint(
1459 'printf(foo->c_str())',
1460 'Potential format string bug. '
1461 'Do printf("%s", foo->c_str()) instead.'
1462 ' [runtime/printf] [4]')
1463 self.TestLint(
1464 'StringPrintf(foo)',
1465 'Potential format string bug. Do StringPrintf("%s", foo) instead.'
1466 ''
1467 ' [runtime/printf] [4]')
1468
erg@google.coma868d2d2009-10-09 21:18:45 +00001469 # Test disallowed use of operator& and other operators.
1470 def testIllegalOperatorOverloading(self):
1471 errmsg = ('Unary operator& is dangerous. Do not use it.'
1472 ' [runtime/operator] [4]')
1473 self.TestLint('void operator=(const Myclass&)', '')
1474 self.TestLint('void operator&(int a, int b)', '') # binary operator& ok
1475 self.TestLint('void operator&() { }', errmsg)
1476 self.TestLint('void operator & ( ) { }',
avakulenko@google.com02af6282014-06-04 18:53:25 +00001477 ['Extra space after ( [whitespace/parens] [2]', errmsg])
erg@google.coma868d2d2009-10-09 21:18:45 +00001478
1479 # const string reference members are dangerous..
1480 def testConstStringReferenceMembers(self):
1481 errmsg = ('const string& members are dangerous. It is much better to use '
1482 'alternatives, such as pointers or simple constants.'
1483 ' [runtime/member_string_references] [2]')
1484
1485 members_declarations = ['const string& church',
1486 'const string &turing',
1487 'const string & godel']
1488 # TODO(unknown): Enable also these tests if and when we ever
1489 # decide to check for arbitrary member references.
1490 # "const Turing & a",
1491 # "const Church& a",
1492 # "const vector<int>& a",
1493 # "const Kurt::Godel & godel",
1494 # "const Kazimierz::Kuratowski& kk" ]
1495
1496 # The Good.
1497
1498 self.TestLint('void f(const string&)', '')
1499 self.TestLint('const string& f(const string& a, const string& b)', '')
1500 self.TestLint('typedef const string& A;', '')
1501
1502 for decl in members_declarations:
1503 self.TestLint(decl + ' = b;', '')
1504 self.TestLint(decl + ' =', '')
1505
1506 # The Bad.
1507
1508 for decl in members_declarations:
1509 self.TestLint(decl + ';', errmsg)
1510
erg@google.com4e00b9a2009-01-12 23:05:11 +00001511 # Variable-length arrays are not permitted.
1512 def testVariableLengthArrayDetection(self):
1513 errmsg = ('Do not use variable-length arrays. Use an appropriately named '
1514 "('k' followed by CamelCase) compile-time constant for the size."
1515 ' [runtime/arrays] [1]')
1516
1517 self.TestLint('int a[any_old_variable];', errmsg)
1518 self.TestLint('int doublesize[some_var * 2];', errmsg)
1519 self.TestLint('int a[afunction()];', errmsg)
1520 self.TestLint('int a[function(kMaxFooBars)];', errmsg)
1521 self.TestLint('bool a_list[items_->size()];', errmsg)
1522 self.TestLint('namespace::Type buffer[len+1];', errmsg)
1523
1524 self.TestLint('int a[64];', '')
1525 self.TestLint('int a[0xFF];', '')
1526 self.TestLint('int first[256], second[256];', '')
1527 self.TestLint('int array_name[kCompileTimeConstant];', '')
1528 self.TestLint('char buf[somenamespace::kBufSize];', '')
1529 self.TestLint('int array_name[ALL_CAPS];', '')
1530 self.TestLint('AClass array1[foo::bar::ALL_CAPS];', '')
1531 self.TestLint('int a[kMaxStrLen + 1];', '')
1532 self.TestLint('int a[sizeof(foo)];', '')
1533 self.TestLint('int a[sizeof(*foo)];', '')
1534 self.TestLint('int a[sizeof foo];', '')
1535 self.TestLint('int a[sizeof(struct Foo)];', '')
1536 self.TestLint('int a[128 - sizeof(const bar)];', '')
1537 self.TestLint('int a[(sizeof(foo) * 4)];', '')
1538 self.TestLint('int a[(arraysize(fixed_size_array)/2) << 1];', '')
1539 self.TestLint('delete a[some_var];', '')
1540 self.TestLint('return a[some_var];', '')
1541
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001542 # DISALLOW_COPY_AND_ASSIGN and DISALLOW_IMPLICIT_CONSTRUCTORS should be at
1543 # end of class if present.
1544 def testDisallowMacrosAtEnd(self):
erg@google.com4e00b9a2009-01-12 23:05:11 +00001545 for macro_name in (
erg@google.com4e00b9a2009-01-12 23:05:11 +00001546 'DISALLOW_COPY_AND_ASSIGN',
1547 'DISALLOW_IMPLICIT_CONSTRUCTORS'):
1548 self.TestLanguageRulesCheck(
1549 'some_class.h',
erg@google.com8a95ecc2011-09-08 00:45:54 +00001550 """%s(SomeClass);
erg@google.com4e00b9a2009-01-12 23:05:11 +00001551 int foo_;
erg@google.com8a95ecc2011-09-08 00:45:54 +00001552 };""" % macro_name,
erg@google.com4e00b9a2009-01-12 23:05:11 +00001553 ('%s should be the last thing in the class' % macro_name) +
1554 ' [readability/constructors] [3]')
1555 self.TestLanguageRulesCheck(
1556 'some_class.h',
erg@google.com8a95ecc2011-09-08 00:45:54 +00001557 """%s(SomeClass);
1558 };""" % macro_name,
1559 '')
1560 self.TestLanguageRulesCheck(
1561 'some_class.h',
1562 """%s(SomeClass);
1563 int foo_;
1564 } instance, *pointer_to_instance;""" % macro_name,
1565 ('%s should be the last thing in the class' % macro_name) +
1566 ' [readability/constructors] [3]')
1567 self.TestLanguageRulesCheck(
1568 'some_class.h',
1569 """%s(SomeClass);
1570 } instance, *pointer_to_instance;""" % macro_name,
erg@google.com4e00b9a2009-01-12 23:05:11 +00001571 '')
1572
erg@google.comd350fe52013-01-14 17:51:48 +00001573 # DISALLOW* macros should be in the private: section.
1574 def testMisplacedDisallowMacros(self):
1575 for macro_name in (
erg@google.comd350fe52013-01-14 17:51:48 +00001576 'DISALLOW_COPY_AND_ASSIGN',
1577 'DISALLOW_IMPLICIT_CONSTRUCTORS'):
1578 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001579 """
1580 class A {'
erg@google.comd350fe52013-01-14 17:51:48 +00001581 public:
1582 %s(A);
1583 };""" % macro_name,
1584 ('%s must be in the private: section' % macro_name) +
1585 ' [readability/constructors] [3]')
1586
1587 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001588 """
1589 struct B {'
erg@google.comd350fe52013-01-14 17:51:48 +00001590 %s(B);
1591 };""" % macro_name,
1592 ('%s must be in the private: section' % macro_name) +
1593 ' [readability/constructors] [3]')
1594
1595 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001596 """
1597 class Outer1 {'
erg@google.comd350fe52013-01-14 17:51:48 +00001598 private:
1599 struct Inner1 {
1600 %s(Inner1);
1601 };
1602 %s(Outer1);
1603 };""" % (macro_name, macro_name),
1604 ('%s must be in the private: section' % macro_name) +
1605 ' [readability/constructors] [3]')
1606
1607 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001608 """
1609 class Outer2 {'
erg@google.comd350fe52013-01-14 17:51:48 +00001610 private:
1611 class Inner2 {
1612 %s(Inner2);
1613 };
1614 %s(Outer2);
1615 };""" % (macro_name, macro_name),
1616 '')
1617 # Extra checks to make sure that nested classes are handled
1618 # correctly. Use different macros for inner and outer classes so
1619 # that we can tell the error messages apart.
1620 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001621 """
1622 class Outer3 {
erg@google.comd350fe52013-01-14 17:51:48 +00001623 struct Inner3 {
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001624 DISALLOW_COPY_AND_ASSIGN(Inner3);
erg@google.comd350fe52013-01-14 17:51:48 +00001625 };
1626 DISALLOW_IMPLICIT_CONSTRUCTORS(Outer3);
1627 };""",
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001628 ('DISALLOW_COPY_AND_ASSIGN must be in the private: section'
erg@google.comd350fe52013-01-14 17:51:48 +00001629 ' [readability/constructors] [3]'))
1630 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00001631 """
1632 struct Outer4 {
erg@google.comd350fe52013-01-14 17:51:48 +00001633 class Inner4 {
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001634 DISALLOW_COPY_AND_ASSIGN(Inner4);
erg@google.comd350fe52013-01-14 17:51:48 +00001635 };
1636 DISALLOW_IMPLICIT_CONSTRUCTORS(Outer4);
1637 };""",
1638 ('DISALLOW_IMPLICIT_CONSTRUCTORS must be in the private: section'
1639 ' [readability/constructors] [3]'))
1640
erg@google.com4e00b9a2009-01-12 23:05:11 +00001641 # Brace usage
1642 def testBraces(self):
1643 # Braces shouldn't be followed by a ; unless they're defining a struct
1644 # or initializing an array
1645 self.TestLint('int a[3] = { 1, 2, 3 };', '')
1646 self.TestLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001647 """const int foo[] =
1648 {1, 2, 3 };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001649 '')
1650 # For single line, unmatched '}' with a ';' is ignored (not enough context)
1651 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001652 """int a[3] = { 1,
erg@google.com4e00b9a2009-01-12 23:05:11 +00001653 2,
erg@google.com8a95ecc2011-09-08 00:45:54 +00001654 3 };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001655 '')
1656 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001657 """int a[2][3] = { { 1, 2 },
1658 { 3, 4 } };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001659 '')
1660 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00001661 """int a[2][3] =
erg@google.com4e00b9a2009-01-12 23:05:11 +00001662 { { 1, 2 },
erg@google.com8a95ecc2011-09-08 00:45:54 +00001663 { 3, 4 } };""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00001664 '')
1665
1666 # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements
1667 def testCheckCheck(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001668 self.TestLint('CHECK(x == 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001669 'Consider using CHECK_EQ instead of CHECK(a == b)'
1670 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001671 self.TestLint('CHECK(x != 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001672 'Consider using CHECK_NE instead of CHECK(a != b)'
1673 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001674 self.TestLint('CHECK(x >= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001675 'Consider using CHECK_GE instead of CHECK(a >= b)'
1676 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001677 self.TestLint('CHECK(x > 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001678 'Consider using CHECK_GT instead of CHECK(a > b)'
1679 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001680 self.TestLint('CHECK(x <= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001681 'Consider using CHECK_LE instead of CHECK(a <= b)'
1682 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001683 self.TestLint('CHECK(x < 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001684 'Consider using CHECK_LT instead of CHECK(a < b)'
1685 ' [readability/check] [2]')
1686
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001687 self.TestLint('DCHECK(x == 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001688 'Consider using DCHECK_EQ instead of DCHECK(a == b)'
1689 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001690 self.TestLint('DCHECK(x != 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001691 'Consider using DCHECK_NE instead of DCHECK(a != b)'
1692 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001693 self.TestLint('DCHECK(x >= 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001694 'Consider using DCHECK_GE instead of DCHECK(a >= b)'
1695 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001696 self.TestLint('DCHECK(x > 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001697 'Consider using DCHECK_GT instead of DCHECK(a > b)'
1698 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001699 self.TestLint('DCHECK(x <= 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001700 'Consider using DCHECK_LE instead of DCHECK(a <= b)'
1701 ' [readability/check] [2]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001702 self.TestLint('DCHECK(x < 42);',
erg@google.come35f7652009-06-19 20:52:09 +00001703 'Consider using DCHECK_LT instead of DCHECK(a < b)'
1704 ' [readability/check] [2]')
1705
erg@google.com4e00b9a2009-01-12 23:05:11 +00001706 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001707 'EXPECT_TRUE("42" == x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001708 'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)'
1709 ' [readability/check] [2]')
1710 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001711 'EXPECT_TRUE("42" != x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001712 'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)'
1713 ' [readability/check] [2]')
1714 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001715 'EXPECT_TRUE(+42 >= x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001716 'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)'
1717 ' [readability/check] [2]')
1718 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001719 'EXPECT_TRUE_M(-42 > x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001720 'Consider using EXPECT_GT_M instead of EXPECT_TRUE_M(a > b)'
1721 ' [readability/check] [2]')
1722 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001723 'EXPECT_TRUE_M(42U <= x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001724 'Consider using EXPECT_LE_M instead of EXPECT_TRUE_M(a <= b)'
1725 ' [readability/check] [2]')
1726 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001727 'EXPECT_TRUE_M(42L < x);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001728 'Consider using EXPECT_LT_M instead of EXPECT_TRUE_M(a < b)'
1729 ' [readability/check] [2]')
1730
1731 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001732 'EXPECT_FALSE(x == 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001733 'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)'
1734 ' [readability/check] [2]')
1735 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001736 'EXPECT_FALSE(x != 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001737 'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)'
1738 ' [readability/check] [2]')
1739 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001740 'EXPECT_FALSE(x >= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001741 'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)'
1742 ' [readability/check] [2]')
1743 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001744 'ASSERT_FALSE(x > 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001745 'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)'
1746 ' [readability/check] [2]')
1747 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001748 'ASSERT_FALSE(x <= 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001749 'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)'
1750 ' [readability/check] [2]')
1751 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001752 'ASSERT_FALSE_M(x < 42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001753 'Consider using ASSERT_GE_M instead of ASSERT_FALSE_M(a < b)'
1754 ' [readability/check] [2]')
1755
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001756 self.TestLint('CHECK(x<42);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001757 ['Missing spaces around <'
1758 ' [whitespace/operators] [3]',
1759 'Consider using CHECK_LT instead of CHECK(a < b)'
1760 ' [readability/check] [2]'])
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001761 self.TestLint('CHECK(x>42);',
erg@google.comd350fe52013-01-14 17:51:48 +00001762 ['Missing spaces around >'
1763 ' [whitespace/operators] [3]',
1764 'Consider using CHECK_GT instead of CHECK(a > b)'
1765 ' [readability/check] [2]'])
erg@google.com4e00b9a2009-01-12 23:05:11 +00001766
erg@google.com0075d142013-11-05 22:28:07 +00001767 self.TestLint('using some::namespace::operator<<;', '')
1768 self.TestLint('using some::namespace::operator>>;', '')
erg@google.comc6671232013-10-25 21:44:03 +00001769
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001770 self.TestLint('CHECK(x->y == 42);',
erg@google.comc6671232013-10-25 21:44:03 +00001771 'Consider using CHECK_EQ instead of CHECK(a == b)'
1772 ' [readability/check] [2]')
1773
erg@google.com4e00b9a2009-01-12 23:05:11 +00001774 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001775 ' EXPECT_TRUE(42 < x); // Random comment.',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001776 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1777 ' [readability/check] [2]')
1778 self.TestLint(
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001779 'EXPECT_TRUE( 42 < x );',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001780 ['Extra space after ( in function call'
1781 ' [whitespace/parens] [4]',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001782 'Extra space before ) [whitespace/parens] [2]',
erg@google.com4e00b9a2009-01-12 23:05:11 +00001783 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1784 ' [readability/check] [2]'])
erg@google.com4e00b9a2009-01-12 23:05:11 +00001785
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001786 self.TestLint('CHECK(4\'2 == x);',
avakulenko@google.com02af6282014-06-04 18:53:25 +00001787 'Consider using CHECK_EQ instead of CHECK(a == b)'
1788 ' [readability/check] [2]')
1789
1790 def testCheckCheckFalsePositives(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001791 self.TestLint('CHECK(some_iterator == obj.end());', '')
1792 self.TestLint('EXPECT_TRUE(some_iterator == obj.end());', '')
1793 self.TestLint('EXPECT_FALSE(some_iterator == obj.end());', '')
1794 self.TestLint('CHECK(some_pointer != NULL);', '')
1795 self.TestLint('EXPECT_TRUE(some_pointer != NULL);', '')
1796 self.TestLint('EXPECT_FALSE(some_pointer != NULL);', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00001797
1798 self.TestLint('CHECK(CreateTestFile(dir, (1 << 20)));', '')
1799 self.TestLint('CHECK(CreateTestFile(dir, (1 >> 20)));', '')
1800
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001801 self.TestLint('CHECK(x ^ (y < 42));', '')
1802 self.TestLint('CHECK((x > 42) ^ (x < 54));', '')
1803 self.TestLint('CHECK(a && b < 42);', '')
1804 self.TestLint('CHECK(42 < a && a < b);', '')
1805 self.TestLint('SOFT_CHECK(x > 42);', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00001806
1807 self.TestMultiLineLint(
1808 """_STLP_DEFINE_BINARY_OP_CHECK(==, _OP_EQUAL);
1809 _STLP_DEFINE_BINARY_OP_CHECK(!=, _OP_NOT_EQUAL);
1810 _STLP_DEFINE_BINARY_OP_CHECK(<, _OP_LESS_THAN);
1811 _STLP_DEFINE_BINARY_OP_CHECK(<=, _OP_LESS_EQUAL);
1812 _STLP_DEFINE_BINARY_OP_CHECK(>, _OP_GREATER_THAN);
1813 _STLP_DEFINE_BINARY_OP_CHECK(>=, _OP_GREATER_EQUAL);
1814 _STLP_DEFINE_BINARY_OP_CHECK(+, _OP_PLUS);
1815 _STLP_DEFINE_BINARY_OP_CHECK(*, _OP_TIMES);
1816 _STLP_DEFINE_BINARY_OP_CHECK(/, _OP_DIVIDE);
1817 _STLP_DEFINE_BINARY_OP_CHECK(-, _OP_SUBTRACT);
1818 _STLP_DEFINE_BINARY_OP_CHECK(%, _OP_MOD);""",
1819 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001820
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001821 self.TestLint('CHECK(x < 42) << "Custom error message";', '')
1822
erg@google.comd350fe52013-01-14 17:51:48 +00001823 # Alternative token to punctuation operator replacements
1824 def testCheckAltTokens(self):
1825 self.TestLint('true or true',
1826 'Use operator || instead of or'
1827 ' [readability/alt_tokens] [2]')
1828 self.TestLint('true and true',
1829 'Use operator && instead of and'
1830 ' [readability/alt_tokens] [2]')
1831 self.TestLint('if (not true)',
1832 'Use operator ! instead of not'
1833 ' [readability/alt_tokens] [2]')
1834 self.TestLint('1 bitor 1',
1835 'Use operator | instead of bitor'
1836 ' [readability/alt_tokens] [2]')
1837 self.TestLint('1 xor 1',
1838 'Use operator ^ instead of xor'
1839 ' [readability/alt_tokens] [2]')
1840 self.TestLint('1 bitand 1',
1841 'Use operator & instead of bitand'
1842 ' [readability/alt_tokens] [2]')
1843 self.TestLint('x = compl 1',
1844 'Use operator ~ instead of compl'
1845 ' [readability/alt_tokens] [2]')
1846 self.TestLint('x and_eq y',
1847 'Use operator &= instead of and_eq'
1848 ' [readability/alt_tokens] [2]')
1849 self.TestLint('x or_eq y',
1850 'Use operator |= instead of or_eq'
1851 ' [readability/alt_tokens] [2]')
1852 self.TestLint('x xor_eq y',
1853 'Use operator ^= instead of xor_eq'
1854 ' [readability/alt_tokens] [2]')
1855 self.TestLint('x not_eq y',
1856 'Use operator != instead of not_eq'
1857 ' [readability/alt_tokens] [2]')
1858 self.TestLint('line_continuation or',
1859 'Use operator || instead of or'
1860 ' [readability/alt_tokens] [2]')
1861 self.TestLint('if(true and(parentheses',
1862 'Use operator && instead of and'
1863 ' [readability/alt_tokens] [2]')
1864
1865 self.TestLint('#include "base/false-and-false.h"', '')
1866 self.TestLint('#error false or false', '')
1867 self.TestLint('false nor false', '')
1868 self.TestLint('false nand false', '')
1869
erg@google.com4e00b9a2009-01-12 23:05:11 +00001870 # Passing and returning non-const references
1871 def testNonConstReference(self):
1872 # Passing a non-const reference as function parameter is forbidden.
1873 operand_error_message = ('Is this a non-const reference? '
erg@google.comfd5da632013-10-25 17:39:45 +00001874 'If so, make const or use a pointer: %s'
erg@google.com4e00b9a2009-01-12 23:05:11 +00001875 ' [runtime/references] [2]')
1876 # Warn of use of a non-const reference in operators and functions
erg@google.comfd5da632013-10-25 17:39:45 +00001877 self.TestLint('bool operator>(Foo& s, Foo& f);',
1878 [operand_error_message % 'Foo& s',
1879 operand_error_message % 'Foo& f'])
1880 self.TestLint('bool operator+(Foo& s, Foo& f);',
1881 [operand_error_message % 'Foo& s',
1882 operand_error_message % 'Foo& f'])
1883 self.TestLint('int len(Foo& s);', operand_error_message % 'Foo& s')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001884 # Allow use of non-const references in a few specific cases
1885 self.TestLint('stream& operator>>(stream& s, Foo& f);', '')
1886 self.TestLint('stream& operator<<(stream& s, Foo& f);', '')
1887 self.TestLint('void swap(Bar& a, Bar& b);', '')
1888 # Returning a non-const reference from a function is OK.
1889 self.TestLint('int& g();', '')
1890 # Passing a const reference to a struct (using the struct keyword) is OK.
1891 self.TestLint('void foo(const struct tm& tm);', '')
1892 # Passing a const reference to a typename is OK.
1893 self.TestLint('void foo(const typename tm& tm);', '')
erg@google.comfd5da632013-10-25 17:39:45 +00001894 # Const reference to a pointer type is OK.
1895 self.TestLint('void foo(const Bar* const& p) {', '')
1896 self.TestLint('void foo(Bar const* const& p) {', '')
1897 self.TestLint('void foo(Bar* const& p) {', '')
1898 # Const reference to a templated type is OK.
1899 self.TestLint('void foo(const std::vector<std::string>& v);', '')
1900 # Non-const reference to a pointer type is not OK.
1901 self.TestLint('void foo(Bar*& p);',
1902 operand_error_message % 'Bar*& p')
1903 self.TestLint('void foo(const Bar*& p);',
1904 operand_error_message % 'const Bar*& p')
1905 self.TestLint('void foo(Bar const*& p);',
1906 operand_error_message % 'Bar const*& p')
1907 self.TestLint('void foo(struct Bar*& p);',
1908 operand_error_message % 'struct Bar*& p')
1909 self.TestLint('void foo(const struct Bar*& p);',
1910 operand_error_message % 'const struct Bar*& p')
1911 self.TestLint('void foo(struct Bar const*& p);',
1912 operand_error_message % 'struct Bar const*& p')
1913 # Non-const reference to a templated type is not OK.
1914 self.TestLint('void foo(std::vector<int>& p);',
1915 operand_error_message % 'std::vector<int>& p')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001916 # Returning an address of something is not prohibited.
1917 self.TestLint('return &something;', '')
erg@google.comd7d27472011-09-07 17:36:35 +00001918 self.TestLint('if (condition) {return &something; }', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00001919 self.TestLint('if (condition) return &something;', '')
1920 self.TestLint('if (condition) address = &something;', '')
1921 self.TestLint('if (condition) result = lhs&rhs;', '')
1922 self.TestLint('if (condition) result = lhs & rhs;', '')
1923 self.TestLint('a = (b+c) * sizeof &f;', '')
1924 self.TestLint('a = MySize(b) * sizeof &f;', '')
erg@google.comd350fe52013-01-14 17:51:48 +00001925 # We don't get confused by C++11 range-based for loops.
1926 self.TestLint('for (const string& s : c)', '')
1927 self.TestLint('for (auto& r : c)', '')
1928 self.TestLint('for (typename Type& a : b)', '')
erg@google.comfd5da632013-10-25 17:39:45 +00001929 # We don't get confused by some other uses of '&'.
1930 self.TestLint('T& operator=(const T& t);', '')
1931 self.TestLint('int g() { return (a & b); }', '')
1932 self.TestLint('T& r = (T&)*(vp());', '')
1933 self.TestLint('T& r = v', '')
1934 self.TestLint('static_assert((kBits & kMask) == 0, "text");', '')
1935 self.TestLint('COMPILE_ASSERT((kBits & kMask) == 0, text);', '')
erg@google.com2aa59982013-10-28 19:09:25 +00001936 # Spaces before template arguments. This is poor style, but
1937 # happens 0.15% of the time.
1938 self.TestLint('void Func(const vector <int> &const_x, '
1939 'vector <int> &nonconst_x) {',
1940 operand_error_message % 'vector<int> &nonconst_x')
erg@google.comfd5da632013-10-25 17:39:45 +00001941
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001942 # Derived member functions are spared from override check
1943 self.TestLint('void Func(X& x);', operand_error_message % 'X& x')
1944 self.TestLint('void Func(X& x) {}', operand_error_message % 'X& x')
1945 self.TestLint('void Func(X& x) override;', '')
1946 self.TestLint('void Func(X& x) override {', '')
1947 self.TestLint('void Func(X& x) const override;', '')
1948 self.TestLint('void Func(X& x) const override {', '')
1949
avakulenko@google.com02af6282014-06-04 18:53:25 +00001950 # Other potential false positives. These need full parser
erg@google.comfd5da632013-10-25 17:39:45 +00001951 # state to reproduce as opposed to just TestLint.
1952 error_collector = ErrorCollector(self.assert_)
1953 cpplint.ProcessFileData(
1954 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001955 ['// Copyright 2014 Your Company. All Rights Reserved.',
erg@google.comfd5da632013-10-25 17:39:45 +00001956 'void swap(int &x,',
1957 ' int &y) {',
1958 '}',
1959 'void swap(',
1960 ' sparsegroup<T, GROUP_SIZE, Alloc> &x,',
1961 ' sparsegroup<T, GROUP_SIZE, Alloc> &y) {',
1962 '}',
1963 'ostream& operator<<(',
1964 ' ostream& out',
1965 ' const dense_hash_set<Value, Hash, Equals, Alloc>& seq) {',
1966 '}',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001967 'void Derived::Function(',
1968 ' string &x) override {',
1969 '}',
avakulenko@google.com02af6282014-06-04 18:53:25 +00001970 '#define UNSUPPORTED_MASK(_mask) \\',
1971 ' if (flags & _mask) { \\',
1972 ' LOG(FATAL) << "Unsupported flag: " << #_mask; \\',
1973 ' }',
1974 'Constructor::Constructor()',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001975 ' : initializer1_(a1 & b1),',
1976 ' initializer2_(a2 & b2) {',
avakulenko@google.com02af6282014-06-04 18:53:25 +00001977 '}',
1978 'Constructor::Constructor()',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001979 ' : initializer1_{a3 & b3},',
1980 ' initializer2_(a4 & b4) {',
avakulenko@google.com02af6282014-06-04 18:53:25 +00001981 '}',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001982 'Constructor::Constructor()',
1983 ' : initializer1_{a5 & b5},',
1984 ' initializer2_(a6 & b6) {}',
erg@google.comfd5da632013-10-25 17:39:45 +00001985 ''],
1986 error_collector)
1987 self.assertEquals('', error_collector.Results())
erg@google.com4e00b9a2009-01-12 23:05:11 +00001988
erg@google.comc6671232013-10-25 21:44:03 +00001989 # Multi-line references
avakulenko@google.com02af6282014-06-04 18:53:25 +00001990 error_collector = ErrorCollector(self.assert_)
erg@google.comc6671232013-10-25 21:44:03 +00001991 cpplint.ProcessFileData(
1992 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00001993 ['// Copyright 2014 Your Company. All Rights Reserved.',
erg@google.comc6671232013-10-25 21:44:03 +00001994 'void Func(const Outer::',
1995 ' Inner& const_x,',
1996 ' const Outer',
1997 ' ::Inner& const_y,',
erg@google.com2aa59982013-10-28 19:09:25 +00001998 ' const Outer<',
1999 ' int>::Inner& const_z,',
erg@google.comc6671232013-10-25 21:44:03 +00002000 ' Outer::',
2001 ' Inner& nonconst_x,',
2002 ' Outer',
erg@google.com2aa59982013-10-28 19:09:25 +00002003 ' ::Inner& nonconst_y,',
2004 ' Outer<',
2005 ' int>::Inner& nonconst_z) {',
erg@google.comc6671232013-10-25 21:44:03 +00002006 '}',
2007 ''],
2008 error_collector)
2009 self.assertEquals(
2010 [operand_error_message % 'Outer::Inner& nonconst_x',
erg@google.com2aa59982013-10-28 19:09:25 +00002011 operand_error_message % 'Outer::Inner& nonconst_y',
2012 operand_error_message % 'Outer<int>::Inner& nonconst_z'],
erg@google.comc6671232013-10-25 21:44:03 +00002013 error_collector.Results())
2014
avakulenko@google.com02af6282014-06-04 18:53:25 +00002015 # A peculiar false positive due to bad template argument parsing
2016 error_collector = ErrorCollector(self.assert_)
2017 cpplint.ProcessFileData(
2018 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002019 ['// Copyright 2014 Your Company. All Rights Reserved.',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002020 'inline RCULocked<X>::ReadPtr::ReadPtr(const RCULocked* rcu) {',
2021 ' DCHECK(!(data & kFlagMask)) << "Error";',
2022 '}',
2023 '',
2024 'RCULocked<X>::WritePtr::WritePtr(RCULocked* rcu)',
2025 ' : lock_(&rcu_->mutex_) {',
2026 '}',
2027 ''],
2028 error_collector.Results())
2029 self.assertEquals('', error_collector.Results())
2030
erg@google.com4e00b9a2009-01-12 23:05:11 +00002031 def testBraceAtBeginOfLine(self):
2032 self.TestLint('{',
2033 '{ should almost always be at the end of the previous line'
2034 ' [whitespace/braces] [4]')
2035
erg@google.comd350fe52013-01-14 17:51:48 +00002036 error_collector = ErrorCollector(self.assert_)
2037 cpplint.ProcessFileData('foo.cc', 'cc',
2038 ['int function()',
2039 '{', # warning here
2040 ' MutexLock l(&mu);',
2041 '}',
2042 'int variable;'
2043 '{', # no warning
2044 ' MutexLock l(&mu);',
2045 '}',
erg@google.comc6671232013-10-25 21:44:03 +00002046 'MyType m = {',
2047 ' {value1, value2},',
2048 ' {', # no warning
2049 ' loooong_value1, looooong_value2',
2050 ' }',
2051 '};',
erg@google.comd350fe52013-01-14 17:51:48 +00002052 '#if PREPROCESSOR',
2053 '{', # no warning
2054 ' MutexLock l(&mu);',
2055 '}',
2056 '#endif'],
2057 error_collector)
2058 self.assertEquals(1, error_collector.Results().count(
2059 '{ should almost always be at the end of the previous line'
2060 ' [whitespace/braces] [4]'))
2061
erg@google.com2aa59982013-10-28 19:09:25 +00002062 self.TestMultiLineLint(
2063 """
2064 foo(
2065 {
2066 loooooooooooooooong_value,
2067 });""",
2068 '')
2069
erg@google.com4e00b9a2009-01-12 23:05:11 +00002070 def testMismatchingSpacesInParens(self):
2071 self.TestLint('if (foo ) {', 'Mismatching spaces inside () in if'
2072 ' [whitespace/parens] [5]')
2073 self.TestLint('switch ( foo) {', 'Mismatching spaces inside () in switch'
2074 ' [whitespace/parens] [5]')
erg@google.come35f7652009-06-19 20:52:09 +00002075 self.TestLint('for (foo; ba; bar ) {', 'Mismatching spaces inside () in for'
2076 ' [whitespace/parens] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002077 self.TestLint('for (; foo; bar) {', '')
2078 self.TestLint('for ( ; foo; bar) {', '')
2079 self.TestLint('for ( ; foo; bar ) {', '')
erg@google.come35f7652009-06-19 20:52:09 +00002080 self.TestLint('for (foo; bar; ) {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002081 self.TestLint('while ( foo ) {', 'Should have zero or one spaces inside'
2082 ' ( and ) in while [whitespace/parens] [5]')
2083
2084 def testSpacingForFncall(self):
2085 self.TestLint('if (foo) {', '')
erg@google.comd7d27472011-09-07 17:36:35 +00002086 self.TestLint('for (foo; bar; baz) {', '')
2087 self.TestLint('for (;;) {', '')
erg@google.comc6671232013-10-25 21:44:03 +00002088 # Space should be allowed in placement new operators.
2089 self.TestLint('Something* p = new (place) Something();', '')
erg@google.comd7d27472011-09-07 17:36:35 +00002090 # Test that there is no warning when increment statement is empty.
2091 self.TestLint('for (foo; baz;) {', '')
2092 self.TestLint('for (foo;bar;baz) {', 'Missing space after ;'
2093 ' [whitespace/semicolon] [3]')
2094 # we don't warn about this semicolon, at least for now
2095 self.TestLint('if (condition) {return &something; }',
2096 '')
2097 # seen in some macros
2098 self.TestLint('DoSth();\\', '')
2099 # Test that there is no warning about semicolon here.
2100 self.TestLint('abc;// this is abc',
2101 'At least two spaces is best between code'
2102 ' and comments [whitespace/comments] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002103 self.TestLint('while (foo) {', '')
2104 self.TestLint('switch (foo) {', '')
2105 self.TestLint('foo( bar)', 'Extra space after ( in function call'
2106 ' [whitespace/parens] [4]')
erg@google.comd7d27472011-09-07 17:36:35 +00002107 self.TestLint('foo( // comment', '')
2108 self.TestLint('foo( // comment',
2109 'At least two spaces is best between code'
2110 ' and comments [whitespace/comments] [2]')
erg@google.com36649102009-03-25 21:18:36 +00002111 self.TestLint('foobar( \\', '')
2112 self.TestLint('foobar( \\', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002113 self.TestLint('( a + b)', 'Extra space after ('
2114 ' [whitespace/parens] [2]')
2115 self.TestLint('((a+b))', '')
2116 self.TestLint('foo (foo)', 'Extra space before ( in function call'
2117 ' [whitespace/parens] [4]')
erg@google.comfd5da632013-10-25 17:39:45 +00002118 self.TestLint('} catch (const Foo& ex) {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002119 self.TestLint('typedef foo (*foo)(foo)', '')
2120 self.TestLint('typedef foo (*foo12bar_)(foo)', '')
2121 self.TestLint('typedef foo (Foo::*bar)(foo)', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002122 self.TestLint('using foo = type (Foo::*bar)(foo)', '')
2123 self.TestLint('using foo = type (Foo::*bar)(', '')
2124 self.TestLint('using foo = type (Foo::*)(', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002125 self.TestLint('foo (Foo::*bar)(', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002126 self.TestLint('foo (x::y::*z)(', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002127 self.TestLint('foo (Foo::bar)(',
erg@google.com4e00b9a2009-01-12 23:05:11 +00002128 'Extra space before ( in function call'
2129 ' [whitespace/parens] [4]')
erg@google.comd350fe52013-01-14 17:51:48 +00002130 self.TestLint('foo (*bar)(', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002131 self.TestLint('typedef foo (Foo::*bar)(', '')
2132 self.TestLint('(foo)(bar)', '')
2133 self.TestLint('Foo (*foo)(bar)', '')
2134 self.TestLint('Foo (*foo)(Bar bar,', '')
2135 self.TestLint('char (*p)[sizeof(foo)] = &foo', '')
2136 self.TestLint('char (&ref)[sizeof(foo)] = &foo', '')
2137 self.TestLint('const char32 (*table[])[6];', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002138 # The sizeof operator is often written as if it were a function call, with
2139 # an opening parenthesis directly following the operator name, but it can
2140 # also be written like any other operator, with a space following the
2141 # operator name, and the argument optionally in parentheses.
2142 self.TestLint('sizeof(foo)', '')
2143 self.TestLint('sizeof foo', '')
2144 self.TestLint('sizeof (foo)', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002145
2146 def testSpacingBeforeBraces(self):
2147 self.TestLint('if (foo){', 'Missing space before {'
2148 ' [whitespace/braces] [5]')
2149 self.TestLint('for{', 'Missing space before {'
2150 ' [whitespace/braces] [5]')
2151 self.TestLint('for {', '')
2152 self.TestLint('EXPECT_DEBUG_DEATH({', '')
2153
erg@google.comfd5da632013-10-25 17:39:45 +00002154 def testSemiColonAfterBraces(self):
2155 self.TestLint('if (cond) {};',
2156 'You don\'t need a ; after a } [readability/braces] [4]')
erg@google.com2aa59982013-10-28 19:09:25 +00002157 self.TestLint('void Func() {};',
2158 'You don\'t need a ; after a } [readability/braces] [4]')
2159 self.TestLint('void Func() const {};',
2160 'You don\'t need a ; after a } [readability/braces] [4]')
erg@google.comfd5da632013-10-25 17:39:45 +00002161 self.TestLint('class X {};', '')
2162 self.TestLint('struct X {};', '')
2163 self.TestLint('union {} x;', '')
2164 self.TestLint('union {};', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002165
2166 self.TestLint('class X : public Y {};', '')
2167 self.TestLint('class X : public MACRO() {};', '')
2168 self.TestLint('DEFINE_FACADE(PCQueue::Watcher, PCQueue) {};', '')
2169 self.TestLint('VCLASS(XfaTest, XfaContextTest) {};', '')
2170 self.TestLint('TEST(TestCase, TestName) {};',
2171 'You don\'t need a ; after a } [readability/braces] [4]')
2172 self.TestLint('TEST_F(TestCase, TestName) {};',
2173 'You don\'t need a ; after a } [readability/braces] [4]')
2174
2175 self.TestLint('file_tocs_[i] = (FileToc) {a, b, c};', '')
2176 self.TestMultiLineLint('class X : public Y,\npublic Z {};', '')
2177
avakulenko@google.com02af6282014-06-04 18:53:25 +00002178 def testLambda(self):
2179 self.TestLint('auto x = []() {};', '')
2180 self.TestLint('return []() {};', '')
2181 self.TestMultiLineLint('auto x = []() {\n};\n', '')
2182 self.TestLint('int operator[](int x) {};',
2183 'You don\'t need a ; after a } [readability/braces] [4]')
2184
2185 self.TestMultiLineLint('auto x = [&a,\nb]() {};', '')
2186 self.TestMultiLineLint('auto x = [&a,\nb]\n() {};', '')
2187 self.TestMultiLineLint('auto x = [&a,\n'
2188 ' b](\n'
2189 ' int a,\n'
2190 ' int b) {\n'
2191 ' return a +\n'
2192 ' b;\n'
2193 '};\n',
2194 '')
2195
2196 for lambda_with_default_capture in ('void f() { [=]{}; }',
2197 'void f() { [=](int i) {}; }',
2198 'void f() { [=, &x]{}; }',
2199 'void f() { [&]{}; }',
2200 'void f() { [ & ]{}; }',
2201 'void f() { [&, y]{}; }'):
2202 self.TestLint(lambda_with_default_capture,
2203 'Default lambda captures are an unapproved C++ feature. '
2204 '[build/c++11] [4]')
2205
2206 # "[&...]" isn't necessarily a default capture, though "[=...]" always is.
2207 self.TestLint('void f() { [&variable]{}; }', '')
2208
2209 # Avoid false positives with operator[]
2210 self.TestLint('table_to_children[&*table].push_back(dependent);', '')
2211
erg@google.com2aa59982013-10-28 19:09:25 +00002212 def testBraceInitializerList(self):
2213 self.TestLint('MyStruct p = {1, 2};', '')
2214 self.TestLint('MyStruct p{1, 2};', '')
2215 self.TestLint('vector<int> p = {1, 2};', '')
2216 self.TestLint('vector<int> p{1, 2};', '')
2217 self.TestLint('x = vector<int>{1, 2};', '')
2218 self.TestLint('x = (struct in_addr){ 0 };', '')
2219 self.TestLint('Func(vector<int>{1, 2})', '')
2220 self.TestLint('Func((struct in_addr){ 0 })', '')
2221 self.TestLint('Func(vector<int>{1, 2}, 3)', '')
2222 self.TestLint('Func((struct in_addr){ 0 }, 3)', '')
2223 self.TestLint('LOG(INFO) << char{7};', '')
2224 self.TestLint('LOG(INFO) << char{7} << "!";', '')
2225 self.TestLint('int p[2] = {1, 2};', '')
2226 self.TestLint('return {1, 2};', '')
2227 self.TestLint('std::unique_ptr<Foo> foo{new Foo{}};', '')
2228 self.TestLint('auto foo = std::unique_ptr<Foo>{new Foo{}};', '')
2229 self.TestLint('static_assert(Max7String{}.IsValid(), "");', '')
2230 self.TestLint('map_of_pairs[{1, 2}] = 3;', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002231 self.TestLint('ItemView{has_offer() ? new Offer{offer()} : nullptr', '')
2232 self.TestLint('template <class T, EnableIf<::std::is_const<T>{}> = 0>', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002233
2234 self.TestMultiLineLint('std::unique_ptr<Foo> foo{\n'
2235 ' new Foo{}\n'
2236 '};\n', '')
2237 self.TestMultiLineLint('std::unique_ptr<Foo> foo{\n'
2238 ' new Foo{\n'
2239 ' new Bar{}\n'
2240 ' }\n'
2241 '};\n', '')
2242 self.TestMultiLineLint('if (true) {\n'
2243 ' if (false){}\n'
2244 '}\n',
2245 'Missing space before { [whitespace/braces] [5]')
2246 self.TestMultiLineLint('MyClass::MyClass()\n'
2247 ' : initializer_{\n'
2248 ' Func()} {\n'
2249 '}\n', '')
erg@google.comfd5da632013-10-25 17:39:45 +00002250
erg@google.com4e00b9a2009-01-12 23:05:11 +00002251 def testSpacingAroundElse(self):
2252 self.TestLint('}else {', 'Missing space before else'
2253 ' [whitespace/braces] [5]')
2254 self.TestLint('} else{', 'Missing space before {'
2255 ' [whitespace/braces] [5]')
2256 self.TestLint('} else {', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002257 self.TestLint('} else if (foo) {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002258
erg@google.com8a95ecc2011-09-08 00:45:54 +00002259 def testSpacingWithInitializerLists(self):
2260 self.TestLint('int v[1][3] = {{1, 2, 3}};', '')
2261 self.TestLint('int v[1][1] = {{0}};', '')
2262
erg@google.com4e00b9a2009-01-12 23:05:11 +00002263 def testSpacingForBinaryOps(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00002264 self.TestLint('if (foo||bar) {', 'Missing spaces around ||'
2265 ' [whitespace/operators] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002266 self.TestLint('if (foo<=bar) {', 'Missing spaces around <='
2267 ' [whitespace/operators] [3]')
2268 self.TestLint('if (foo<bar) {', 'Missing spaces around <'
2269 ' [whitespace/operators] [3]')
erg@google.comd350fe52013-01-14 17:51:48 +00002270 self.TestLint('if (foo>bar) {', 'Missing spaces around >'
2271 ' [whitespace/operators] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002272 self.TestLint('if (foo<bar->baz) {', 'Missing spaces around <'
2273 ' [whitespace/operators] [3]')
2274 self.TestLint('if (foo<bar->bar) {', 'Missing spaces around <'
2275 ' [whitespace/operators] [3]')
erg@google.comd350fe52013-01-14 17:51:48 +00002276 self.TestLint('template<typename T = double>', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002277 self.TestLint('std::unique_ptr<No<Spaces>>', '')
2278 self.TestLint('typedef hash_map<Foo, Bar>', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002279 self.TestLint('10<<20', '')
2280 self.TestLint('10<<a',
2281 'Missing spaces around << [whitespace/operators] [3]')
2282 self.TestLint('a<<20',
2283 'Missing spaces around << [whitespace/operators] [3]')
2284 self.TestLint('a<<b',
2285 'Missing spaces around << [whitespace/operators] [3]')
2286 self.TestLint('10ULL<<20', '')
2287 self.TestLint('a>>b',
2288 'Missing spaces around >> [whitespace/operators] [3]')
2289 self.TestLint('10>>b',
2290 'Missing spaces around >> [whitespace/operators] [3]')
2291 self.TestLint('LOG(ERROR)<<*foo',
2292 'Missing spaces around << [whitespace/operators] [3]')
2293 self.TestLint('LOG(ERROR)<<&foo',
2294 'Missing spaces around << [whitespace/operators] [3]')
2295 self.TestLint('StringCoder<vector<string>>::ToString()', '')
2296 self.TestLint('map<pair<int, int>, map<int, int>>::iterator', '')
2297 self.TestLint('func<int, pair<int, pair<int, int>>>()', '')
2298 self.TestLint('MACRO1(list<list<int>>)', '')
2299 self.TestLint('MACRO2(list<list<int>>, 42)', '')
2300 self.TestLint('void DoFoo(const set<vector<string>>& arg1);', '')
2301 self.TestLint('void SetFoo(set<vector<string>>* arg1);', '')
2302 self.TestLint('foo = new set<vector<string>>;', '')
2303 self.TestLint('reinterpret_cast<set<vector<string>>*>(a);', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002304 self.TestLint('MACRO(<<)', '')
2305 self.TestLint('MACRO(<<, arg)', '')
2306 self.TestLint('MACRO(<<=)', '')
2307 self.TestLint('MACRO(<<=, arg)', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002308
avakulenko@google.com02af6282014-06-04 18:53:25 +00002309 self.TestLint('using Vector3<T>::operator==;', '')
2310 self.TestLint('using Vector3<T>::operator!=;', '')
2311
2312 def testRvalueReference(self):
2313 space_error = 'Missing spaces around && [whitespace/operators] [3]'
2314 rvalue_error = ('RValue references are an unapproved C++ feature.'
2315 ' [build/c++11] [3]')
2316
2317 # Places where lack of space are allowed
2318 self.TestLint('DEFINE_BINARY_OPERATOR(&&)', '')
2319 self.TestLint('bool operator&&(A b) {}', '')
2320 self.TestLint('bool operator&&(A b) {', '')
2321 self.TestLint('bool operator&&(A b);', '')
2322
2323 # Assignment expressions
2324 self.TestLint('a = b && c;', '')
2325 self.TestLint('a = b&& c;', space_error)
2326 self.TestLint('a = b &&c;', space_error)
2327 self.TestLint('a = (b&& c);', space_error)
2328 self.TestLint('a = (b &&c);', space_error)
2329 self.TestLint('a&& b = c;', rvalue_error)
2330 self.TestLint('a<b>&& c = d;', rvalue_error)
2331 self.TestLint('auto&& a = b;', rvalue_error)
2332 self.TestLint('const a&& b = c;', rvalue_error)
2333 self.TestLint('struct a&& b = c;', rvalue_error)
2334 self.TestLint('decltype(a)&& b = c;', rvalue_error)
2335
2336 # Cast expressions
2337 self.TestLint('a = const_cast<b&&>(c);', rvalue_error)
2338 self.TestLint('a = const_cast<const b&&>(c);', rvalue_error)
2339 self.TestLint('a = static_cast<b&&>(c);', rvalue_error)
2340 self.TestLint('a = static_cast<const b&&>(c);', rvalue_error)
2341 self.TestLint('a = dynamic_cast<b&&>(c);', rvalue_error)
2342 self.TestLint('a = dynamic_cast<const b&&>(c);', rvalue_error)
2343 self.TestLint('a = reinterpret_cast<b&&>(c);', rvalue_error)
2344 self.TestLint('a = reinterpret_cast<const b&&>(c);', rvalue_error)
2345 self.TestLint('a = cast < b&& c;', space_error)
2346
2347 # Function parameters
2348 for head in ['void Func', 'vector<int> Func', 'vector<int>\nFunc',
2349 'Constructor', 'Constructor::Constructor',
2350 'operator=', 'operator =', 'operator = ']:
2351 for body in [' {}', ' {', ';']:
2352 self.TestMultiLineLint(head + '(A&& b)' + body, rvalue_error)
2353 self.TestMultiLineLint(head + '(A &&b)' + body, rvalue_error)
2354 self.TestMultiLineLint(head + '(A&&... b)' + body, rvalue_error)
2355 self.TestMultiLineLint(head + '(A<B>&& c)' + body, rvalue_error)
2356 self.TestMultiLineLint(head + '(A<B> &&c)' + body, rvalue_error)
2357
2358 # Function templates
2359 self.TestLint('std::conditional<A, B&, C&&>::type', rvalue_error)
2360 self.TestLint('std::conditional<A, B&&, C&>::type', rvalue_error)
2361
2362 # Template functions
2363 self.TestLint('template <typename T> R&& F()', rvalue_error)
2364 self.TestLint('template <typename T> R&& F() {', rvalue_error)
2365 self.TestMultiLineLint('template <typename T>\nR&& F()', rvalue_error)
2366 self.TestMultiLineLint('template <typename T>\nR&& F() {', rvalue_error)
2367
2368 # For loops
2369 self.TestLint('for (a&& b;;)', rvalue_error)
2370 self.TestLint('for (a&& b;;) {', rvalue_error)
2371 self.TestLint('for (; a&& b;)', space_error)
2372 self.TestLint('for (; a&& b;) {', space_error)
2373
2374 # Constructors
2375 self.TestLint('A(a&& b)', rvalue_error)
2376 self.TestLint('explicit A(a&& b)', rvalue_error)
2377 self.TestLint('A(a b) : c(d&& e)', space_error)
2378 self.TestLint('A(a b) : c(), d(e&& f)', space_error)
2379
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002380 def testAllowedRvalueReference(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00002381 # Verify that RValue reference warnings for a line range can be silenced
2382 error_collector = ErrorCollector(self.assert_)
2383 cpplint.ProcessFileData('foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002384 ['// Copyright 2014 Your Company.',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002385 'GOOGLE_ALLOW_RVALUE_REFERENCES_PUSH',
2386 'void F(A&& b);',
2387 'GOOGLE_ALLOW_RVALUE_REFERENCES_POP',
2388 ''],
2389 error_collector)
2390 self.assertEquals(error_collector.Results(), '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002391
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002392 # RValue references for constructors and operator=
2393 error_collector = ErrorCollector(self.assert_)
2394 cpplint.ProcessFileData(
2395 'foo.cc', 'cc',
2396 ['// Copyright 2014 Your Company.',
2397 'class X {',
2398 ' X(X&& param) = delete; // NOLINT(runtime/explicit)',
2399 ' X(X &&param) = default; // NOLINT(runtime/explicit)',
2400 '',
2401 ' X& operator=(X&& param) = delete;',
2402 ' X& operator=(X&& param)=default;',
2403 '};',
2404 ''],
2405 error_collector)
2406 self.assertEquals(error_collector.Results(), '')
2407
erg@google.com4e00b9a2009-01-12 23:05:11 +00002408 def testSpacingBeforeLastSemicolon(self):
2409 self.TestLint('call_function() ;',
2410 'Extra space before last semicolon. If this should be an '
erg@google.comd350fe52013-01-14 17:51:48 +00002411 'empty statement, use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002412 ' [whitespace/semicolon] [5]')
2413 self.TestLint('while (true) ;',
2414 'Extra space before last semicolon. If this should be an '
erg@google.comd350fe52013-01-14 17:51:48 +00002415 'empty statement, use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002416 ' [whitespace/semicolon] [5]')
2417 self.TestLint('default:;',
erg@google.comd350fe52013-01-14 17:51:48 +00002418 'Semicolon defining empty statement. Use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002419 ' [whitespace/semicolon] [5]')
2420 self.TestLint(' ;',
2421 'Line contains only semicolon. If this should be an empty '
erg@google.comd350fe52013-01-14 17:51:48 +00002422 'statement, use {} instead.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002423 ' [whitespace/semicolon] [5]')
2424 self.TestLint('for (int i = 0; ;', '')
2425
erg@google.comc6671232013-10-25 21:44:03 +00002426 def testEmptyBlockBody(self):
erg@google.comd350fe52013-01-14 17:51:48 +00002427 self.TestLint('while (true);',
2428 'Empty loop bodies should use {} or continue'
2429 ' [whitespace/empty_loop_body] [5]')
erg@google.comc6671232013-10-25 21:44:03 +00002430 self.TestLint('if (true);',
2431 'Empty conditional bodies should use {}'
2432 ' [whitespace/empty_conditional_body] [5]')
erg@google.comd350fe52013-01-14 17:51:48 +00002433 self.TestLint('while (true)', '')
2434 self.TestLint('while (true) continue;', '')
2435 self.TestLint('for (;;);',
2436 'Empty loop bodies should use {} or continue'
2437 ' [whitespace/empty_loop_body] [5]')
2438 self.TestLint('for (;;)', '')
2439 self.TestLint('for (;;) continue;', '')
2440 self.TestLint('for (;;) func();', '')
2441 self.TestMultiLineLint("""while (true &&
2442 false);""",
2443 'Empty loop bodies should use {} or continue'
2444 ' [whitespace/empty_loop_body] [5]')
2445 self.TestMultiLineLint("""do {
2446 } while (false);""",
2447 '')
2448 self.TestMultiLineLint("""#define MACRO \\
2449 do { \\
2450 } while (false);""",
2451 '')
2452 self.TestMultiLineLint("""do {
2453 } while (false); // next line gets a warning
2454 while (false);""",
2455 'Empty loop bodies should use {} or continue'
2456 ' [whitespace/empty_loop_body] [5]')
2457
2458 def testSpacingForRangeBasedFor(self):
2459 # Basic correctly formatted case:
2460 self.TestLint('for (int i : numbers) {', '')
2461
2462 # Missing space before colon:
2463 self.TestLint('for (int i: numbers) {',
2464 'Missing space around colon in range-based for loop'
2465 ' [whitespace/forcolon] [2]')
2466 # Missing space after colon:
2467 self.TestLint('for (int i :numbers) {',
2468 'Missing space around colon in range-based for loop'
2469 ' [whitespace/forcolon] [2]')
2470 # Missing spaces both before and after the colon.
2471 self.TestLint('for (int i:numbers) {',
2472 'Missing space around colon in range-based for loop'
2473 ' [whitespace/forcolon] [2]')
2474
2475 # The scope operator '::' shouldn't cause warnings...
2476 self.TestLint('for (std::size_t i : sizes) {}', '')
2477 # ...but it shouldn't suppress them either.
2478 self.TestLint('for (std::size_t i: sizes) {}',
2479 'Missing space around colon in range-based for loop'
2480 ' [whitespace/forcolon] [2]')
2481
2482
erg@google.com4e00b9a2009-01-12 23:05:11 +00002483 # Static or global STL strings.
2484 def testStaticOrGlobalSTLStrings(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002485 error_msg = ('For a static/global string constant, use a C style '
2486 'string instead: "%s[]". [runtime/string] [4]')
2487
erg@google.com4e00b9a2009-01-12 23:05:11 +00002488 self.TestLint('string foo;',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002489 error_msg % 'char foo')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002490 self.TestLint('string kFoo = "hello"; // English',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002491 error_msg % 'char kFoo')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002492 self.TestLint('static string foo;',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002493 error_msg % 'static char foo')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002494 self.TestLint('static const string foo;',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002495 error_msg % 'static const char foo')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002496 self.TestLint('string Foo::bar;',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002497 error_msg % 'char Foo::bar')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002498 self.TestLint('string* pointer', '')
2499 self.TestLint('string *pointer', '')
2500 self.TestLint('string* pointer = Func();', '')
2501 self.TestLint('string *pointer = Func();', '')
2502 self.TestLint('const string* pointer', '')
2503 self.TestLint('const string *pointer', '')
2504 self.TestLint('const string* pointer = Func();', '')
2505 self.TestLint('const string *pointer = Func();', '')
2506 self.TestLint('string const* pointer', '')
2507 self.TestLint('string const *pointer', '')
2508 self.TestLint('string const* pointer = Func();', '')
2509 self.TestLint('string const *pointer = Func();', '')
2510 self.TestLint('string* const pointer', '')
2511 self.TestLint('string *const pointer', '')
2512 self.TestLint('string* const pointer = Func();', '')
2513 self.TestLint('string *const pointer = Func();', '')
erg@google.com2aa59982013-10-28 19:09:25 +00002514 self.TestLint('string Foo::bar() {}', '')
2515 self.TestLint('string Foo::operator*() {}', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002516 # Rare case.
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002517 self.TestLint('string foo("foobar");', error_msg % 'char foo')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002518 # Should not catch local or member variables.
2519 self.TestLint(' string foo', '')
2520 # Should not catch functions.
2521 self.TestLint('string EmptyString() { return ""; }', '')
2522 self.TestLint('string EmptyString () { return ""; }', '')
2523 self.TestLint('string VeryLongNameFunctionSometimesEndsWith(\n'
2524 ' VeryLongNameType very_long_name_variable) {}', '')
2525 self.TestLint('template<>\n'
2526 'string FunctionTemplateSpecialization<SomeType>(\n'
2527 ' int x) { return ""; }', '')
2528 self.TestLint('template<>\n'
2529 'string FunctionTemplateSpecialization<vector<A::B>* >(\n'
2530 ' int x) { return ""; }', '')
2531
2532 # should not catch methods of template classes.
2533 self.TestLint('string Class<Type>::Method() const {\n'
2534 ' return "";\n'
2535 '}\n', '')
2536 self.TestLint('string Class<Type>::Method(\n'
2537 ' int arg) const {\n'
2538 ' return "";\n'
2539 '}\n', '')
2540
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002541 # Check multiline cases.
2542 error_collector = ErrorCollector(self.assert_)
2543 cpplint.ProcessFileData('foo.cc', 'cc',
2544 ['// Copyright 2014 Your Company.',
2545 'string Class',
2546 '::MemberFunction1();',
2547 'string Class::',
2548 'MemberFunction2();',
2549 'string Class::',
2550 'NestedClass::MemberFunction3();',
2551 'string TemplateClass<T>::',
2552 'NestedClass::MemberFunction4();',
2553 'string Class',
2554 '::static_member_variable1;',
2555 'string Class::',
2556 'static_member_variable2;',
2557 'string Class',
2558 '::static_member_variable3 = "initial value";',
2559 'string Class::',
2560 'static_member_variable4 = "initial value";',
2561 ''],
2562 error_collector)
2563 self.assertEquals(error_collector.Results(),
2564 [error_msg % 'char Class::static_member_variable1',
2565 error_msg % 'char Class::static_member_variable2',
2566 error_msg % 'char Class::static_member_variable3',
2567 error_msg % 'char Class::static_member_variable4'])
2568
erg@google.com4e00b9a2009-01-12 23:05:11 +00002569 def testNoSpacesInFunctionCalls(self):
2570 self.TestLint('TellStory(1, 3);',
2571 '')
2572 self.TestLint('TellStory(1, 3 );',
2573 'Extra space before )'
2574 ' [whitespace/parens] [2]')
2575 self.TestLint('TellStory(1 /* wolf */, 3 /* pigs */);',
2576 '')
erg@google.com8a95ecc2011-09-08 00:45:54 +00002577 self.TestMultiLineLint("""TellStory(1, 3
2578 );""",
2579 'Closing ) should be moved to the previous line'
2580 ' [whitespace/parens] [2]')
2581 self.TestMultiLineLint("""TellStory(Wolves(1),
2582 Pigs(3
2583 ));""",
2584 'Closing ) should be moved to the previous line'
2585 ' [whitespace/parens] [2]')
2586 self.TestMultiLineLint("""TellStory(1,
2587 3 );""",
2588 'Extra space before )'
2589 ' [whitespace/parens] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002590
2591 def testToDoComments(self):
2592 start_space = ('Too many spaces before TODO'
2593 ' [whitespace/todo] [2]')
2594 missing_username = ('Missing username in TODO; it should look like '
2595 '"// TODO(my_username): Stuff."'
2596 ' [readability/todo] [2]')
2597 end_space = ('TODO(my_username) should be followed by a space'
2598 ' [whitespace/todo] [2]')
2599
2600 self.TestLint('// TODOfix this',
2601 [start_space, missing_username, end_space])
2602 self.TestLint('// TODO(ljenkins)fix this',
2603 [start_space, end_space])
2604 self.TestLint('// TODO fix this',
2605 [start_space, missing_username])
2606 self.TestLint('// TODO fix this', missing_username)
2607 self.TestLint('// TODO: fix this', missing_username)
2608 self.TestLint('//TODO(ljenkins): Fix this',
2609 'Should have a space between // and comment'
2610 ' [whitespace/comments] [4]')
2611 self.TestLint('// TODO(ljenkins):Fix this', end_space)
2612 self.TestLint('// TODO(ljenkins):', '')
2613 self.TestLint('// TODO(ljenkins): fix this', '')
2614 self.TestLint('// TODO(ljenkins): Fix this', '')
erg@google.comd350fe52013-01-14 17:51:48 +00002615 self.TestLint('#if 1 // TEST_URLTODOCID_WHICH_HAS_THAT_WORD_IN_IT_H_', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002616 self.TestLint('// See also similar TODO above', '')
2617
2618 def testTwoSpacesBetweenCodeAndComments(self):
2619 self.TestLint('} // namespace foo',
2620 'At least two spaces is best between code and comments'
2621 ' [whitespace/comments] [2]')
2622 self.TestLint('}// namespace foo',
2623 'At least two spaces is best between code and comments'
2624 ' [whitespace/comments] [2]')
2625 self.TestLint('printf("foo"); // Outside quotes.',
2626 'At least two spaces is best between code and comments'
2627 ' [whitespace/comments] [2]')
2628 self.TestLint('int i = 0; // Having two spaces is fine.', '')
2629 self.TestLint('int i = 0; // Having three spaces is OK.', '')
2630 self.TestLint('// Top level comment', '')
2631 self.TestLint(' // Line starts with two spaces.', '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002632 self.TestMultiLineLint('void foo() {\n'
2633 ' { // A scope is opening.\n'
2634 ' int a;', '')
2635 self.TestMultiLineLint('void foo() {\n'
2636 ' { // A scope is opening.\n'
2637 '#define A a',
2638 'At least two spaces is best between code and '
2639 'comments [whitespace/comments] [2]')
2640 self.TestMultiLineLint(' foo();\n'
2641 ' { // An indented scope is opening.\n'
2642 ' int a;', '')
2643 self.TestMultiLineLint('vector<int> my_elements = {// first\n'
2644 ' 1,', '')
2645 self.TestMultiLineLint('vector<int> my_elements = {// my_elements is ..\n'
2646 ' 1,',
2647 'At least two spaces is best between code and '
2648 'comments [whitespace/comments] [2]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002649 self.TestLint('if (foo) { // not a pure scope; comment is too close!',
2650 'At least two spaces is best between code and comments'
2651 ' [whitespace/comments] [2]')
2652 self.TestLint('printf("// In quotes.")', '')
2653 self.TestLint('printf("\\"%s // In quotes.")', '')
2654 self.TestLint('printf("%s", "// In quotes.")', '')
2655
2656 def testSpaceAfterCommentMarker(self):
2657 self.TestLint('//', '')
2658 self.TestLint('//x', 'Should have a space between // and comment'
2659 ' [whitespace/comments] [4]')
2660 self.TestLint('// x', '')
erg@google.come35f7652009-06-19 20:52:09 +00002661 self.TestLint('//----', '')
2662 self.TestLint('//====', '')
2663 self.TestLint('//////', '')
2664 self.TestLint('////// x', '')
2665 self.TestLint('/// x', '')
erg@google.com6d8d9832013-10-31 19:46:18 +00002666 self.TestLint('///< x', '') # After-member Doxygen comment
2667 self.TestLint('//!< x', '') # After-member Doxygen comment
erg@google.coma51c16b2010-11-17 18:09:31 +00002668 self.TestLint('///', '') # Empty Doxygen comment
erg@google.come35f7652009-06-19 20:52:09 +00002669 self.TestLint('////x', 'Should have a space between // and comment'
2670 ' [whitespace/comments] [4]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00002671 self.TestLint('//}', '')
2672 self.TestLint('//}x', 'Should have a space between // and comment'
2673 ' [whitespace/comments] [4]')
erg@google.com6d8d9832013-10-31 19:46:18 +00002674 self.TestLint('//!<x', 'Should have a space between // and comment'
2675 ' [whitespace/comments] [4]')
2676 self.TestLint('///<x', 'Should have a space between // and comment'
2677 ' [whitespace/comments] [4]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00002678
2679 # Test a line preceded by empty or comment lines. There was a bug
2680 # that caused it to print the same warning N times if the erroneous
2681 # line was preceded by N lines of empty or comment lines. To be
2682 # precise, the '// marker so line numbers and indices both start at
2683 # 1' line was also causing the issue.
2684 def testLinePrecededByEmptyOrCommentLines(self):
2685 def DoTest(self, lines):
2686 error_collector = ErrorCollector(self.assert_)
2687 cpplint.ProcessFileData('foo.cc', 'cc', lines, error_collector)
2688 # The warning appears only once.
2689 self.assertEquals(
2690 1,
2691 error_collector.Results().count(
2692 'Do not use namespace using-directives. '
2693 'Use using-declarations instead.'
2694 ' [build/namespaces] [5]'))
2695 DoTest(self, ['using namespace foo;'])
2696 DoTest(self, ['', '', '', 'using namespace foo;'])
2697 DoTest(self, ['// hello', 'using namespace foo;'])
2698
2699 def testNewlineAtEOF(self):
2700 def DoTest(self, data, is_missing_eof):
2701 error_collector = ErrorCollector(self.assert_)
2702 cpplint.ProcessFileData('foo.cc', 'cc', data.split('\n'),
2703 error_collector)
2704 # The warning appears only once.
2705 self.assertEquals(
2706 int(is_missing_eof),
2707 error_collector.Results().count(
2708 'Could not find a newline character at the end of the file.'
2709 ' [whitespace/ending_newline] [5]'))
2710
2711 DoTest(self, '// Newline\n// at EOF\n', False)
2712 DoTest(self, '// No newline\n// at EOF', True)
2713
2714 def testInvalidUtf8(self):
2715 def DoTest(self, raw_bytes, has_invalid_utf8):
2716 error_collector = ErrorCollector(self.assert_)
2717 cpplint.ProcessFileData(
2718 'foo.cc', 'cc',
2719 unicode(raw_bytes, 'utf8', 'replace').split('\n'),
2720 error_collector)
2721 # The warning appears only once.
2722 self.assertEquals(
2723 int(has_invalid_utf8),
2724 error_collector.Results().count(
2725 'Line contains invalid UTF-8'
2726 ' (or Unicode replacement character).'
2727 ' [readability/utf8] [5]'))
2728
2729 DoTest(self, 'Hello world\n', False)
2730 DoTest(self, '\xe9\x8e\xbd\n', False)
2731 DoTest(self, '\xe9x\x8e\xbd\n', True)
2732 # This is the encoding of the replacement character itself (which
2733 # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')).
2734 DoTest(self, '\xef\xbf\xbd\n', True)
2735
erg@google.com2aa59982013-10-28 19:09:25 +00002736 def testBadCharacters(self):
2737 # Test for NUL bytes only
2738 error_collector = ErrorCollector(self.assert_)
2739 cpplint.ProcessFileData('nul.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002740 ['// Copyright 2014 Your Company.',
erg@google.com2aa59982013-10-28 19:09:25 +00002741 '\0', ''], error_collector)
2742 self.assertEquals(
2743 error_collector.Results(),
2744 'Line contains NUL byte. [readability/nul] [5]')
2745
2746 # Make sure both NUL bytes and UTF-8 are caught if they appear on
2747 # the same line.
2748 error_collector = ErrorCollector(self.assert_)
2749 cpplint.ProcessFileData(
2750 'nul_utf8.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002751 ['// Copyright 2014 Your Company.',
erg@google.com2aa59982013-10-28 19:09:25 +00002752 unicode('\xe9x\0', 'utf8', 'replace'), ''],
2753 error_collector)
2754 self.assertEquals(
2755 error_collector.Results(),
2756 ['Line contains invalid UTF-8 (or Unicode replacement character).'
2757 ' [readability/utf8] [5]',
2758 'Line contains NUL byte. [readability/nul] [5]'])
2759
erg@google.com4e00b9a2009-01-12 23:05:11 +00002760 def testIsBlankLine(self):
2761 self.assert_(cpplint.IsBlankLine(''))
2762 self.assert_(cpplint.IsBlankLine(' '))
2763 self.assert_(cpplint.IsBlankLine(' \t\r\n'))
2764 self.assert_(not cpplint.IsBlankLine('int a;'))
2765 self.assert_(not cpplint.IsBlankLine('{'))
2766
2767 def testBlankLinesCheck(self):
2768 self.TestBlankLinesCheck(['{\n', '\n', '\n', '}\n'], 1, 1)
2769 self.TestBlankLinesCheck([' if (foo) {\n', '\n', ' }\n'], 1, 1)
2770 self.TestBlankLinesCheck(
2771 ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0)
2772 self.TestBlankLinesCheck(['\n', 'run("{");\n', '\n'], 0, 0)
2773 self.TestBlankLinesCheck(['\n', ' if (foo) { return 0; }\n', '\n'], 0, 0)
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002774 self.TestBlankLinesCheck(
2775 ['int x(\n', ' int a) {\n', '\n', 'return 0;\n', '}'], 0, 0)
2776 self.TestBlankLinesCheck(
2777 ['int x(\n', ' int a) const {\n', '\n', 'return 0;\n', '}'], 0, 0)
2778 self.TestBlankLinesCheck(
2779 ['int x(\n', ' int a) {\n', '\n', 'return 0;\n', '}'], 1, 0)
2780 self.TestBlankLinesCheck(
2781 ['int x(\n', ' int a) {\n', '\n', 'return 0;\n', '}'], 1, 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00002782
2783 def testAllowBlankLineBeforeClosingNamespace(self):
2784 error_collector = ErrorCollector(self.assert_)
2785 cpplint.ProcessFileData('foo.cc', 'cc',
erg@google.comd350fe52013-01-14 17:51:48 +00002786 ['namespace {',
2787 '',
2788 '} // namespace',
2789 'namespace another_namespace {',
2790 '',
2791 '}',
2792 'namespace {',
2793 '',
2794 'template<class T, ',
2795 ' class A = hoge<T>, ',
2796 ' class B = piyo<T>, ',
2797 ' class C = fuga<T> >',
2798 'class D {',
2799 ' public:',
2800 '};',
2801 '', '', '', '',
2802 '}'],
erg@google.com4e00b9a2009-01-12 23:05:11 +00002803 error_collector)
2804 self.assertEquals(0, error_collector.Results().count(
erg@google.com2aa59982013-10-28 19:09:25 +00002805 'Redundant blank line at the end of a code block should be deleted.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002806 ' [whitespace/blank_line] [3]'))
2807
2808 def testAllowBlankLineBeforeIfElseChain(self):
2809 error_collector = ErrorCollector(self.assert_)
2810 cpplint.ProcessFileData('foo.cc', 'cc',
2811 ['if (hoge) {',
2812 '', # No warning
2813 '} else if (piyo) {',
2814 '', # No warning
2815 '} else if (piyopiyo) {',
2816 ' hoge = true;', # No warning
2817 '} else {',
2818 '', # Warning on this line
2819 '}'],
2820 error_collector)
2821 self.assertEquals(1, error_collector.Results().count(
erg@google.com2aa59982013-10-28 19:09:25 +00002822 'Redundant blank line at the end of a code block should be deleted.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00002823 ' [whitespace/blank_line] [3]'))
2824
avakulenko@google.com02af6282014-06-04 18:53:25 +00002825 def testAllowBlankLineAfterExtern(self):
2826 error_collector = ErrorCollector(self.assert_)
2827 cpplint.ProcessFileData('foo.cc', 'cc',
2828 ['extern "C" {',
2829 '',
2830 'EXPORTAPI void APICALL Some_function() {}',
2831 '',
2832 '}'],
2833 error_collector)
2834 self.assertEquals(0, error_collector.Results().count(
2835 'Redundant blank line at the start of a code block should be deleted.'
2836 ' [whitespace/blank_line] [2]'))
2837 self.assertEquals(0, error_collector.Results().count(
2838 'Redundant blank line at the end of a code block should be deleted.'
2839 ' [whitespace/blank_line] [3]'))
2840
erg@google.com8a95ecc2011-09-08 00:45:54 +00002841 def testBlankLineBeforeSectionKeyword(self):
2842 error_collector = ErrorCollector(self.assert_)
2843 cpplint.ProcessFileData('foo.cc', 'cc',
2844 ['class A {',
2845 ' public:',
2846 ' protected:', # warning 1
2847 ' private:', # warning 2
2848 ' struct B {',
2849 ' public:',
2850 ' private:'] + # warning 3
2851 ([''] * 100) + # Make A and B longer than 100 lines
2852 [' };',
2853 ' struct C {',
2854 ' protected:',
2855 ' private:', # C is too short for warnings
2856 ' };',
2857 '};',
2858 'class D',
2859 ' : public {',
2860 ' public:', # no warning
erg@google.comd350fe52013-01-14 17:51:48 +00002861 '};',
2862 'class E {\\',
2863 ' public:\\'] +
2864 (['\\'] * 100) + # Makes E > 100 lines
2865 [' int non_empty_line;\\',
2866 ' private:\\', # no warning
2867 ' int a;\\',
erg@google.com8a95ecc2011-09-08 00:45:54 +00002868 '};'],
2869 error_collector)
2870 self.assertEquals(2, error_collector.Results().count(
2871 '"private:" should be preceded by a blank line'
2872 ' [whitespace/blank_line] [3]'))
2873 self.assertEquals(1, error_collector.Results().count(
2874 '"protected:" should be preceded by a blank line'
2875 ' [whitespace/blank_line] [3]'))
2876
2877 def testNoBlankLineAfterSectionKeyword(self):
2878 error_collector = ErrorCollector(self.assert_)
2879 cpplint.ProcessFileData('foo.cc', 'cc',
2880 ['class A {',
2881 ' public:',
2882 '', # warning 1
2883 ' private:',
2884 '', # warning 2
2885 ' struct B {',
2886 ' protected:',
2887 '', # warning 3
2888 ' };',
2889 '};'],
2890 error_collector)
2891 self.assertEquals(1, error_collector.Results().count(
2892 'Do not leave a blank line after "public:"'
2893 ' [whitespace/blank_line] [3]'))
2894 self.assertEquals(1, error_collector.Results().count(
2895 'Do not leave a blank line after "protected:"'
2896 ' [whitespace/blank_line] [3]'))
2897 self.assertEquals(1, error_collector.Results().count(
2898 'Do not leave a blank line after "private:"'
2899 ' [whitespace/blank_line] [3]'))
2900
avakulenko@google.com02af6282014-06-04 18:53:25 +00002901 def testAllowBlankLinesInRawStrings(self):
2902 error_collector = ErrorCollector(self.assert_)
2903 cpplint.ProcessFileData('foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00002904 ['// Copyright 2014 Your Company.',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002905 'static const char *kData[] = {R"(',
2906 '',
2907 ')", R"(',
2908 '',
2909 ')"};',
2910 ''],
2911 error_collector)
2912 self.assertEquals('', error_collector.Results())
2913
erg@google.com4e00b9a2009-01-12 23:05:11 +00002914 def testElseOnSameLineAsClosingBraces(self):
2915 error_collector = ErrorCollector(self.assert_)
2916 cpplint.ProcessFileData('foo.cc', 'cc',
2917 ['if (hoge) {',
avakulenko@google.com02af6282014-06-04 18:53:25 +00002918 '}',
2919 'else if (piyo) {', # Warning on this line
erg@google.com4e00b9a2009-01-12 23:05:11 +00002920 '}',
2921 ' else {' # Warning on this line
2922 '',
2923 '}'],
2924 error_collector)
avakulenko@google.com02af6282014-06-04 18:53:25 +00002925 self.assertEquals(2, error_collector.Results().count(
2926 'An else should appear on the same line as the preceding }'
2927 ' [whitespace/newline] [4]'))
2928
2929 error_collector = ErrorCollector(self.assert_)
2930 cpplint.ProcessFileData('foo.cc', 'cc',
2931 ['if (hoge) {',
2932 '',
2933 '}',
2934 'else', # Warning on this line
2935 '{',
2936 '',
2937 '}'],
2938 error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +00002939 self.assertEquals(1, error_collector.Results().count(
2940 'An else should appear on the same line as the preceding }'
2941 ' [whitespace/newline] [4]'))
2942
avakulenko@google.com02af6282014-06-04 18:53:25 +00002943 error_collector = ErrorCollector(self.assert_)
2944 cpplint.ProcessFileData('foo.cc', 'cc',
2945 ['if (hoge) {',
2946 '',
2947 '}',
2948 'else_function();'],
2949 error_collector)
2950 self.assertEquals(0, error_collector.Results().count(
2951 'An else should appear on the same line as the preceding }'
2952 ' [whitespace/newline] [4]'))
2953
erg@google.comd350fe52013-01-14 17:51:48 +00002954 def testMultipleStatementsOnSameLine(self):
2955 error_collector = ErrorCollector(self.assert_)
2956 cpplint.ProcessFileData('foo.cc', 'cc',
2957 ['for (int i = 0; i < 1; i++) {}',
2958 'switch (x) {',
2959 ' case 0: func(); break; ',
2960 '}',
2961 'sum += MathUtil::SafeIntRound(x); x += 0.1;'],
2962 error_collector)
2963 self.assertEquals(0, error_collector.Results().count(
2964 'More than one command on the same line [whitespace/newline] [0]'))
2965
2966 old_verbose_level = cpplint._cpplint_state.verbose_level
2967 cpplint._cpplint_state.verbose_level = 0
2968 cpplint.ProcessFileData('foo.cc', 'cc',
2969 ['sum += MathUtil::SafeIntRound(x); x += 0.1;'],
2970 error_collector)
2971 cpplint._cpplint_state.verbose_level = old_verbose_level
2972
2973 def testEndOfNamespaceComments(self):
2974 error_collector = ErrorCollector(self.assert_)
2975 cpplint.ProcessFileData('foo.cc', 'cc',
2976 ['namespace {',
2977 '',
2978 '}', # No warning (too short)
2979 'namespace expected {',
2980 '} // namespace mismatched', # Warning here
2981 'namespace {',
2982 '} // namespace mismatched', # Warning here
2983 'namespace outer { namespace nested {'] +
2984 ([''] * 10) +
2985 ['}', # Warning here
2986 '}', # Warning here
2987 'namespace {'] +
2988 ([''] * 10) +
2989 ['}', # Warning here
2990 'namespace {'] +
2991 ([''] * 10) +
avakulenko@google.com02af6282014-06-04 18:53:25 +00002992 ['} // namespace some description', # Anon warning
2993 'namespace {'] +
2994 ([''] * 10) +
2995 ['} // namespace anonymous', # Variant warning
2996 'namespace {'] +
2997 ([''] * 10) +
2998 ['} // anonymous namespace (utils)', # Variant
2999 'namespace {'] +
3000 ([''] * 10) +
3001 ['} // anonymous namespace', # No warning
erg@google.comd350fe52013-01-14 17:51:48 +00003002 'namespace missing_comment {'] +
3003 ([''] * 10) +
3004 ['}', # Warning here
3005 'namespace no_warning {'] +
3006 ([''] * 10) +
3007 ['} // namespace no_warning',
3008 'namespace no_warning {'] +
3009 ([''] * 10) +
3010 ['}; // end namespace no_warning',
3011 '#define MACRO \\',
3012 'namespace c_style { \\'] +
3013 (['\\'] * 10) +
3014 ['} /* namespace c_style. */ \\',
3015 ';'],
3016 error_collector)
3017 self.assertEquals(1, error_collector.Results().count(
3018 'Namespace should be terminated with "// namespace expected"'
3019 ' [readability/namespace] [5]'))
3020 self.assertEquals(1, error_collector.Results().count(
3021 'Namespace should be terminated with "// namespace outer"'
3022 ' [readability/namespace] [5]'))
3023 self.assertEquals(1, error_collector.Results().count(
3024 'Namespace should be terminated with "// namespace nested"'
3025 ' [readability/namespace] [5]'))
3026 self.assertEquals(3, error_collector.Results().count(
avakulenko@google.com02af6282014-06-04 18:53:25 +00003027 'Anonymous namespace should be terminated with "// namespace"'
3028 ' [readability/namespace] [5]'))
3029 self.assertEquals(2, error_collector.Results().count(
3030 'Anonymous namespace should be terminated with "// namespace" or'
3031 ' "// anonymous namespace"'
erg@google.comd350fe52013-01-14 17:51:48 +00003032 ' [readability/namespace] [5]'))
3033 self.assertEquals(1, error_collector.Results().count(
3034 'Namespace should be terminated with "// namespace missing_comment"'
3035 ' [readability/namespace] [5]'))
3036 self.assertEquals(0, error_collector.Results().count(
3037 'Namespace should be terminated with "// namespace no_warning"'
3038 ' [readability/namespace] [5]'))
3039
erg@google.com4e00b9a2009-01-12 23:05:11 +00003040 def testElseClauseNotOnSameLineAsElse(self):
3041 self.TestLint(' else DoSomethingElse();',
3042 'Else clause should never be on same line as else '
3043 '(use 2 lines) [whitespace/newline] [4]')
3044 self.TestLint(' else ifDoSomethingElse();',
3045 'Else clause should never be on same line as else '
3046 '(use 2 lines) [whitespace/newline] [4]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003047 self.TestLint(' } else if (blah) {', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003048 self.TestLint(' variable_ends_in_else = true;', '')
3049
3050 def testComma(self):
3051 self.TestLint('a = f(1,2);',
3052 'Missing space after , [whitespace/comma] [3]')
3053 self.TestLint('int tmp=a,a=b,b=tmp;',
3054 ['Missing spaces around = [whitespace/operators] [4]',
3055 'Missing space after , [whitespace/comma] [3]'])
3056 self.TestLint('f(a, /* name */ b);', '')
3057 self.TestLint('f(a, /* name */b);', '')
erg@google.com2aa59982013-10-28 19:09:25 +00003058 self.TestLint('f(a, /* name */-1);', '')
3059 self.TestLint('f(a, /* name */"1");', '')
erg@google.comc6671232013-10-25 21:44:03 +00003060 self.TestLint('f(1, /* empty macro arg */, 2)', '')
3061 self.TestLint('f(1,, 2)', '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003062 self.TestLint('operator,()', '')
3063 self.TestLint('operator,(a,b)',
3064 'Missing space after , [whitespace/comma] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003065
3066 def testIndent(self):
3067 self.TestLint('static int noindent;', '')
3068 self.TestLint(' int two_space_indent;', '')
3069 self.TestLint(' int four_space_indent;', '')
3070 self.TestLint(' int one_space_indent;',
3071 'Weird number of spaces at line-start. '
3072 'Are you using a 2-space indent? [whitespace/indent] [3]')
3073 self.TestLint(' int three_space_indent;',
3074 'Weird number of spaces at line-start. '
3075 'Are you using a 2-space indent? [whitespace/indent] [3]')
3076 self.TestLint(' char* one_space_indent = "public:";',
3077 'Weird number of spaces at line-start. '
3078 'Are you using a 2-space indent? [whitespace/indent] [3]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003079 self.TestLint(' public:', '')
3080 self.TestLint(' protected:', '')
3081 self.TestLint(' private:', '')
3082 self.TestLint(' protected: \\', '')
3083 self.TestLint(' public: \\', '')
3084 self.TestLint(' private: \\', '')
3085 self.TestMultiLineLint(
3086 TrimExtraIndent("""
3087 class foo {
3088 public slots:
3089 void bar();
3090 };"""),
3091 'Weird number of spaces at line-start. '
3092 'Are you using a 2-space indent? [whitespace/indent] [3]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003093 self.TestMultiLineLint(
3094 TrimExtraIndent('''
3095 static const char kRawString[] = R"("
3096 ")";'''),
3097 '')
3098 self.TestMultiLineLint(
3099 TrimExtraIndent('''
3100 static const char kNotRawString[] = "("
3101 ")";'''),
3102 'Weird number of spaces at line-start. '
3103 'Are you using a 2-space indent? [whitespace/indent] [3]')
3104 self.TestMultiLineLint(
3105 ' static const char kSingleLineRawString[] = R"(...)";',
3106 'Weird number of spaces at line-start. '
3107 'Are you using a 2-space indent? [whitespace/indent] [3]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003108
erg@google.comfd5da632013-10-25 17:39:45 +00003109 def testSectionIndent(self):
3110 self.TestMultiLineLint(
3111 """
3112 class A {
3113 public: // no warning
3114 private: // warning here
3115 };""",
3116 'private: should be indented +1 space inside class A'
3117 ' [whitespace/indent] [3]')
3118 self.TestMultiLineLint(
3119 """
3120 class B {
3121 public: // no warning
3122 template<> struct C {
3123 public: // warning here
3124 protected: // no warning
3125 };
3126 };""",
3127 'public: should be indented +1 space inside struct C'
3128 ' [whitespace/indent] [3]')
3129 self.TestMultiLineLint(
3130 """
3131 struct D {
3132 };""",
3133 'Closing brace should be aligned with beginning of struct D'
3134 ' [whitespace/indent] [3]')
3135 self.TestMultiLineLint(
3136 """
3137 template<typename E> class F {
3138 };""",
3139 'Closing brace should be aligned with beginning of class F'
3140 ' [whitespace/indent] [3]')
3141 self.TestMultiLineLint(
3142 """
3143 class G {
3144 Q_OBJECT
3145 public slots:
3146 signals:
3147 };""",
3148 ['public slots: should be indented +1 space inside class G'
3149 ' [whitespace/indent] [3]',
3150 'signals: should be indented +1 space inside class G'
3151 ' [whitespace/indent] [3]'])
3152 self.TestMultiLineLint(
3153 """
3154 class H {
3155 /* comments */ class I {
3156 public: // no warning
3157 private: // warning here
3158 };
3159 };""",
3160 'private: should be indented +1 space inside class I'
3161 ' [whitespace/indent] [3]')
3162 self.TestMultiLineLint(
3163 """
3164 class J
3165 : public ::K {
3166 public: // no warning
3167 protected: // warning here
3168 };""",
3169 'protected: should be indented +1 space inside class J'
3170 ' [whitespace/indent] [3]')
3171 self.TestMultiLineLint(
3172 """
3173 class L
3174 : public M,
3175 public ::N {
3176 };""",
3177 '')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003178 self.TestMultiLineLint(
3179 """
3180 template <class O,
3181 class P,
3182 class Q,
3183 typename R>
3184 static void Func() {
3185 }""",
3186 '')
3187
3188 def testConditionals(self):
3189 self.TestMultiLineLint(
3190 """
3191 if (foo)
3192 goto fail;
3193 goto fail;""",
3194 'If/else bodies with multiple statements require braces'
3195 ' [readability/braces] [4]')
3196 self.TestMultiLineLint(
3197 """
3198 if (foo)
3199 goto fail; goto fail;""",
3200 'If/else bodies with multiple statements require braces'
3201 ' [readability/braces] [4]')
3202 self.TestMultiLineLint(
3203 """
3204 if (foo)
3205 foo;
3206 else
3207 goto fail;
3208 goto fail;""",
3209 'If/else bodies with multiple statements require braces'
3210 ' [readability/braces] [4]')
3211 self.TestMultiLineLint(
3212 """
3213 if (foo) goto fail;
3214 goto fail;""",
3215 'If/else bodies with multiple statements require braces'
3216 ' [readability/braces] [4]')
3217 self.TestMultiLineLint(
3218 """
3219 if (foo)
3220 if (bar)
3221 baz;
3222 else
3223 qux;""",
3224 'Else clause should be indented at the same level as if. Ambiguous'
3225 ' nested if/else chains require braces. [readability/braces] [4]')
3226 self.TestMultiLineLint(
3227 """
3228 if (foo)
3229 if (bar)
3230 baz;
3231 else
3232 qux;""",
3233 'Else clause should be indented at the same level as if. Ambiguous'
3234 ' nested if/else chains require braces. [readability/braces] [4]')
3235 self.TestMultiLineLint(
3236 """
3237 if (foo) {
3238 bar;
3239 baz;
3240 } else
3241 qux;""",
3242 'If an else has a brace on one side, it should have it on both'
3243 ' [readability/braces] [5]')
3244 self.TestMultiLineLint(
3245 """
3246 if (foo)
3247 bar;
3248 else {
3249 baz;
3250 }""",
3251 'If an else has a brace on one side, it should have it on both'
3252 ' [readability/braces] [5]')
3253 self.TestMultiLineLint(
3254 """
3255 if (foo)
3256 bar;
3257 else if (baz) {
3258 qux;
3259 }""",
3260 'If an else has a brace on one side, it should have it on both'
3261 ' [readability/braces] [5]')
3262 self.TestMultiLineLint(
3263 """
3264 if (foo) {
3265 bar;
3266 } else if (baz)
3267 qux;""",
3268 'If an else has a brace on one side, it should have it on both'
3269 ' [readability/braces] [5]')
3270 self.TestMultiLineLint(
3271 """
3272 if (foo)
3273 goto fail;
3274 bar;""",
3275 '')
3276 self.TestMultiLineLint(
3277 """
3278 if (foo
3279 && bar) {
3280 baz;
3281 qux;
3282 }""",
3283 '')
3284 self.TestMultiLineLint(
3285 """
3286 if (foo)
3287 goto
3288 fail;""",
3289 '')
3290 self.TestMultiLineLint(
3291 """
3292 if (foo)
3293 bar;
3294 else
3295 baz;
3296 qux;""",
3297 '')
3298 self.TestMultiLineLint(
3299 """
3300 for (;;) {
3301 if (foo)
3302 bar;
3303 else
3304 baz;
3305 }""",
3306 '')
3307 self.TestMultiLineLint(
3308 """
3309 if (foo)
3310 bar;
3311 else if (baz)
3312 baz;""",
3313 '')
3314 self.TestMultiLineLint(
3315 """
3316 if (foo)
3317 bar;
3318 else
3319 baz;""",
3320 '')
3321 self.TestMultiLineLint(
3322 """
3323 if (foo) {
3324 bar;
3325 } else {
3326 baz;
3327 }""",
3328 '')
3329 self.TestMultiLineLint(
3330 """
3331 if (foo) {
3332 bar;
3333 } else if (baz) {
3334 qux;
3335 }""",
3336 '')
3337 # Note: this is an error for a different reason, but should not trigger the
3338 # single-line if error.
3339 self.TestMultiLineLint(
3340 """
3341 if (foo)
3342 {
3343 bar;
3344 baz;
3345 }""",
3346 '{ should almost always be at the end of the previous line'
3347 ' [whitespace/braces] [4]')
3348 self.TestMultiLineLint(
3349 """
3350 if (foo) { \\
3351 bar; \\
3352 baz; \\
3353 }""",
3354 '')
3355 self.TestMultiLineLint(
3356 """
3357 void foo() { if (bar) baz; }""",
3358 '')
3359 self.TestMultiLineLint(
3360 """
3361 #if foo
3362 bar;
3363 #else
3364 baz;
3365 qux;
3366 #endif""",
3367 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003368
3369 def testTab(self):
3370 self.TestLint('\tint a;',
3371 'Tab found; better to use spaces [whitespace/tab] [1]')
3372 self.TestLint('int a = 5;\t\t// set a to 5',
3373 'Tab found; better to use spaces [whitespace/tab] [1]')
3374
3375 def testParseArguments(self):
3376 old_usage = cpplint._USAGE
3377 old_error_categories = cpplint._ERROR_CATEGORIES
3378 old_output_format = cpplint._cpplint_state.output_format
3379 old_verbose_level = cpplint._cpplint_state.verbose_level
3380 old_filters = cpplint._cpplint_state.filters
erg@google.comab53edf2013-11-05 22:23:37 +00003381 old_line_length = cpplint._line_length
erg@google.com19680272013-12-16 22:48:54 +00003382 old_valid_extensions = cpplint._valid_extensions
erg@google.com4e00b9a2009-01-12 23:05:11 +00003383 try:
3384 # Don't print usage during the tests, or filter categories
3385 cpplint._USAGE = ''
3386 cpplint._ERROR_CATEGORIES = ''
3387
3388 self.assertRaises(SystemExit, cpplint.ParseArguments, [])
3389 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--badopt'])
3390 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--help'])
3391 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--v=0'])
3392 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter='])
3393 # This is illegal because all filters must start with + or -
3394 self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter=foo'])
3395 self.assertRaises(SystemExit, cpplint.ParseArguments,
3396 ['--filter=+a,b,-c'])
3397
3398 self.assertEquals(['foo.cc'], cpplint.ParseArguments(['foo.cc']))
3399 self.assertEquals(old_output_format, cpplint._cpplint_state.output_format)
3400 self.assertEquals(old_verbose_level, cpplint._cpplint_state.verbose_level)
3401
3402 self.assertEquals(['foo.cc'],
3403 cpplint.ParseArguments(['--v=1', 'foo.cc']))
3404 self.assertEquals(1, cpplint._cpplint_state.verbose_level)
3405 self.assertEquals(['foo.h'],
3406 cpplint.ParseArguments(['--v=3', 'foo.h']))
3407 self.assertEquals(3, cpplint._cpplint_state.verbose_level)
3408 self.assertEquals(['foo.cpp'],
3409 cpplint.ParseArguments(['--verbose=5', 'foo.cpp']))
3410 self.assertEquals(5, cpplint._cpplint_state.verbose_level)
3411 self.assertRaises(ValueError,
3412 cpplint.ParseArguments, ['--v=f', 'foo.cc'])
3413
3414 self.assertEquals(['foo.cc'],
3415 cpplint.ParseArguments(['--output=emacs', 'foo.cc']))
3416 self.assertEquals('emacs', cpplint._cpplint_state.output_format)
3417 self.assertEquals(['foo.h'],
3418 cpplint.ParseArguments(['--output=vs7', 'foo.h']))
3419 self.assertEquals('vs7', cpplint._cpplint_state.output_format)
3420 self.assertRaises(SystemExit,
3421 cpplint.ParseArguments, ['--output=blah', 'foo.cc'])
3422
3423 filt = '-,+whitespace,-whitespace/indent'
3424 self.assertEquals(['foo.h'],
3425 cpplint.ParseArguments(['--filter='+filt, 'foo.h']))
3426 self.assertEquals(['-', '+whitespace', '-whitespace/indent'],
3427 cpplint._cpplint_state.filters)
3428
3429 self.assertEquals(['foo.cc', 'foo.h'],
3430 cpplint.ParseArguments(['foo.cc', 'foo.h']))
erg@google.comab53edf2013-11-05 22:23:37 +00003431
3432 self.assertEqual(['foo.h'],
3433 cpplint.ParseArguments(['--linelength=120', 'foo.h']))
3434 self.assertEqual(120, cpplint._line_length)
erg@google.com19680272013-12-16 22:48:54 +00003435
3436 self.assertEqual(['foo.h'],
3437 cpplint.ParseArguments(['--extensions=hpp,cpp,cpp', 'foo.h']))
3438 self.assertEqual(set(['hpp', 'cpp']), cpplint._valid_extensions)
erg@google.com4e00b9a2009-01-12 23:05:11 +00003439 finally:
3440 cpplint._USAGE = old_usage
3441 cpplint._ERROR_CATEGORIES = old_error_categories
3442 cpplint._cpplint_state.output_format = old_output_format
3443 cpplint._cpplint_state.verbose_level = old_verbose_level
3444 cpplint._cpplint_state.filters = old_filters
erg@google.comab53edf2013-11-05 22:23:37 +00003445 cpplint._line_length = old_line_length
erg@google.com19680272013-12-16 22:48:54 +00003446 cpplint._valid_extensions = old_valid_extensions
erg@google.comab53edf2013-11-05 22:23:37 +00003447
3448 def testLineLength(self):
3449 old_line_length = cpplint._line_length
3450 try:
3451 cpplint._line_length = 80
3452 self.TestLint(
3453 '// %s' % ('H' * 77),
3454 '')
3455 self.TestLint(
3456 '// %s' % ('H' * 78),
3457 'Lines should be <= 80 characters long'
3458 ' [whitespace/line_length] [2]')
3459 cpplint._line_length = 120
3460 self.TestLint(
3461 '// %s' % ('H' * 117),
3462 '')
3463 self.TestLint(
3464 '// %s' % ('H' * 118),
3465 'Lines should be <= 120 characters long'
3466 ' [whitespace/line_length] [2]')
3467 finally:
3468 cpplint._line_length = old_line_length
erg@google.com4e00b9a2009-01-12 23:05:11 +00003469
3470 def testFilter(self):
3471 old_filters = cpplint._cpplint_state.filters
3472 try:
3473 cpplint._cpplint_state.SetFilters('-,+whitespace,-whitespace/indent')
3474 self.TestLint(
3475 '// Hello there ',
3476 'Line ends in whitespace. Consider deleting these extra spaces.'
3477 ' [whitespace/end_of_line] [4]')
3478 self.TestLint('int a = (int)1.0;', '')
3479 self.TestLint(' weird opening space', '')
3480 finally:
3481 cpplint._cpplint_state.filters = old_filters
3482
erg@google.come35f7652009-06-19 20:52:09 +00003483 def testDefaultFilter(self):
3484 default_filters = cpplint._DEFAULT_FILTERS
3485 old_filters = cpplint._cpplint_state.filters
erg@google.com8a95ecc2011-09-08 00:45:54 +00003486 cpplint._DEFAULT_FILTERS = ['-whitespace']
erg@google.come35f7652009-06-19 20:52:09 +00003487 try:
3488 # Reset filters
3489 cpplint._cpplint_state.SetFilters('')
3490 self.TestLint('// Hello there ', '')
3491 cpplint._cpplint_state.SetFilters('+whitespace/end_of_line')
3492 self.TestLint(
3493 '// Hello there ',
3494 'Line ends in whitespace. Consider deleting these extra spaces.'
3495 ' [whitespace/end_of_line] [4]')
3496 self.TestLint(' weird opening space', '')
3497 finally:
3498 cpplint._cpplint_state.filters = old_filters
3499 cpplint._DEFAULT_FILTERS = default_filters
3500
erg@google.com4e00b9a2009-01-12 23:05:11 +00003501 def testUnnamedNamespacesInHeaders(self):
3502 self.TestLanguageRulesCheck(
3503 'foo.h', 'namespace {',
3504 'Do not use unnamed namespaces in header files. See'
3505 ' http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
3506 ' for more information. [build/namespaces] [4]')
3507 # namespace registration macros are OK.
3508 self.TestLanguageRulesCheck('foo.h', 'namespace { \\', '')
3509 # named namespaces are OK.
3510 self.TestLanguageRulesCheck('foo.h', 'namespace foo {', '')
3511 self.TestLanguageRulesCheck('foo.h', 'namespace foonamespace {', '')
3512 self.TestLanguageRulesCheck('foo.cc', 'namespace {', '')
3513 self.TestLanguageRulesCheck('foo.cc', 'namespace foo {', '')
3514
3515 def testBuildClass(self):
3516 # Test that the linter can parse to the end of class definitions,
3517 # and that it will report when it can't.
3518 # Use multi-line linter because it performs the ClassState check.
3519 self.TestMultiLineLint(
3520 'class Foo {',
3521 'Failed to find complete declaration of class Foo'
3522 ' [build/class] [5]')
erg@google.com2aa59982013-10-28 19:09:25 +00003523 # Do the same for namespaces
3524 self.TestMultiLineLint(
3525 'namespace Foo {',
3526 'Failed to find complete declaration of namespace Foo'
3527 ' [build/namespaces] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003528 # Don't warn on forward declarations of various types.
3529 self.TestMultiLineLint(
3530 'class Foo;',
3531 '')
3532 self.TestMultiLineLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00003533 """struct Foo*
3534 foo = NewFoo();""",
erg@google.com4e00b9a2009-01-12 23:05:11 +00003535 '')
erg@google.comd350fe52013-01-14 17:51:48 +00003536 # Test preprocessor.
3537 self.TestMultiLineLint(
3538 """#ifdef DERIVE_FROM_GOO
3539 struct Foo : public Goo {
3540 #else
3541 struct Foo : public Hoo {
3542 #endif
3543 };""",
3544 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003545 self.TestMultiLineLint(
erg@google.comfd5da632013-10-25 17:39:45 +00003546 """
3547 class Foo
erg@google.com4e00b9a2009-01-12 23:05:11 +00003548 #ifdef DERIVE_FROM_GOO
3549 : public Goo {
3550 #else
3551 : public Hoo {
3552 #endif
erg@google.comfd5da632013-10-25 17:39:45 +00003553 };""",
erg@google.comd350fe52013-01-14 17:51:48 +00003554 '')
3555 # Test incomplete class
3556 self.TestMultiLineLint(
3557 'class Foo {',
erg@google.com4e00b9a2009-01-12 23:05:11 +00003558 'Failed to find complete declaration of class Foo'
3559 ' [build/class] [5]')
3560
3561 def testBuildEndComment(self):
3562 # The crosstool compiler we currently use will fail to compile the
3563 # code in this test, so we might consider removing the lint check.
erg@google.comd350fe52013-01-14 17:51:48 +00003564 self.TestMultiLineLint(
3565 """#if 0
3566 #endif Not a comment""",
3567 'Uncommented text after #endif is non-standard. Use a comment.'
3568 ' [build/endif_comment] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003569
3570 def testBuildForwardDecl(self):
3571 # The crosstool compiler we currently use will fail to compile the
3572 # code in this test, so we might consider removing the lint check.
3573 self.TestLint('class Foo::Goo;',
3574 'Inner-style forward declarations are invalid.'
3575 ' Remove this line.'
3576 ' [build/forward_decl] [5]')
3577
3578 def testBuildHeaderGuard(self):
3579 file_path = 'mydir/foo.h'
3580
3581 # We can't rely on our internal stuff to get a sane path on the open source
3582 # side of things, so just parse out the suggested header guard. This
3583 # doesn't allow us to test the suggested header guard, but it does let us
3584 # test all the other header tests.
3585 error_collector = ErrorCollector(self.assert_)
3586 cpplint.ProcessFileData(file_path, 'h', [], error_collector)
3587 expected_guard = ''
3588 matcher = re.compile(
3589 'No \#ifndef header guard found\, suggested CPP variable is\: ([A-Z_]+) ')
3590 for error in error_collector.ResultList():
3591 matches = matcher.match(error)
3592 if matches:
3593 expected_guard = matches.group(1)
3594 break
3595
3596 # Make sure we extracted something for our header guard.
3597 self.assertNotEqual(expected_guard, '')
3598
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003599 # No header guard, but the error is suppressed.
3600 error_collector = ErrorCollector(self.assert_)
3601 cpplint.ProcessFileData(file_path, 'h',
3602 ['// Copyright 2014 Your Company.',
3603 '// NOLINT(build/header_guard)', ''],
3604 error_collector)
3605 self.assertEquals([], error_collector.ResultList())
3606
erg@google.com4e00b9a2009-01-12 23:05:11 +00003607 # Wrong guard
3608 error_collector = ErrorCollector(self.assert_)
3609 cpplint.ProcessFileData(file_path, 'h',
3610 ['#ifndef FOO_H', '#define FOO_H'], error_collector)
3611 self.assertEquals(
3612 1,
3613 error_collector.ResultList().count(
3614 '#ifndef header guard has wrong style, please use: %s'
3615 ' [build/header_guard] [5]' % expected_guard),
3616 error_collector.ResultList())
3617
3618 # No define
3619 error_collector = ErrorCollector(self.assert_)
3620 cpplint.ProcessFileData(file_path, 'h',
3621 ['#ifndef %s' % expected_guard], error_collector)
3622 self.assertEquals(
3623 1,
3624 error_collector.ResultList().count(
erg@google.comdc289702012-01-26 20:30:03 +00003625 'No #define header guard found, suggested CPP variable is: %s'
erg@google.com4e00b9a2009-01-12 23:05:11 +00003626 ' [build/header_guard] [5]' % expected_guard),
3627 error_collector.ResultList())
3628
3629 # Mismatched define
3630 error_collector = ErrorCollector(self.assert_)
3631 cpplint.ProcessFileData(file_path, 'h',
3632 ['#ifndef %s' % expected_guard,
3633 '#define FOO_H'],
3634 error_collector)
3635 self.assertEquals(
3636 1,
3637 error_collector.ResultList().count(
erg@google.comdc289702012-01-26 20:30:03 +00003638 '#ifndef and #define don\'t match, suggested CPP variable is: %s'
erg@google.com4e00b9a2009-01-12 23:05:11 +00003639 ' [build/header_guard] [5]' % expected_guard),
3640 error_collector.ResultList())
3641
3642 # No endif
3643 error_collector = ErrorCollector(self.assert_)
3644 cpplint.ProcessFileData(file_path, 'h',
3645 ['#ifndef %s' % expected_guard,
3646 '#define %s' % expected_guard],
3647 error_collector)
3648 self.assertEquals(
3649 1,
3650 error_collector.ResultList().count(
3651 '#endif line should be "#endif // %s"'
3652 ' [build/header_guard] [5]' % expected_guard),
3653 error_collector.ResultList())
3654
3655 # Commentless endif
3656 error_collector = ErrorCollector(self.assert_)
3657 cpplint.ProcessFileData(file_path, 'h',
3658 ['#ifndef %s' % expected_guard,
3659 '#define %s' % expected_guard,
3660 '#endif'],
3661 error_collector)
3662 self.assertEquals(
3663 1,
3664 error_collector.ResultList().count(
3665 '#endif line should be "#endif // %s"'
3666 ' [build/header_guard] [5]' % expected_guard),
3667 error_collector.ResultList())
3668
3669 # Commentless endif for old-style guard
3670 error_collector = ErrorCollector(self.assert_)
3671 cpplint.ProcessFileData(file_path, 'h',
3672 ['#ifndef %s_' % expected_guard,
3673 '#define %s_' % expected_guard,
3674 '#endif'],
3675 error_collector)
3676 self.assertEquals(
3677 1,
3678 error_collector.ResultList().count(
3679 '#endif line should be "#endif // %s"'
3680 ' [build/header_guard] [5]' % expected_guard),
3681 error_collector.ResultList())
3682
3683 # No header guard errors
3684 error_collector = ErrorCollector(self.assert_)
3685 cpplint.ProcessFileData(file_path, 'h',
3686 ['#ifndef %s' % expected_guard,
3687 '#define %s' % expected_guard,
3688 '#endif // %s' % expected_guard],
3689 error_collector)
3690 for line in error_collector.ResultList():
3691 if line.find('build/header_guard') != -1:
3692 self.fail('Unexpected error: %s' % line)
3693
3694 # No header guard errors for old-style guard
3695 error_collector = ErrorCollector(self.assert_)
3696 cpplint.ProcessFileData(file_path, 'h',
3697 ['#ifndef %s_' % expected_guard,
3698 '#define %s_' % expected_guard,
3699 '#endif // %s_' % expected_guard],
3700 error_collector)
3701 for line in error_collector.ResultList():
3702 if line.find('build/header_guard') != -1:
3703 self.fail('Unexpected error: %s' % line)
3704
3705 old_verbose_level = cpplint._cpplint_state.verbose_level
3706 try:
3707 cpplint._cpplint_state.verbose_level = 0
3708 # Warn on old-style guard if verbosity is 0.
3709 error_collector = ErrorCollector(self.assert_)
3710 cpplint.ProcessFileData(file_path, 'h',
3711 ['#ifndef %s_' % expected_guard,
3712 '#define %s_' % expected_guard,
3713 '#endif // %s_' % expected_guard],
3714 error_collector)
3715 self.assertEquals(
3716 1,
3717 error_collector.ResultList().count(
3718 '#ifndef header guard has wrong style, please use: %s'
3719 ' [build/header_guard] [0]' % expected_guard),
3720 error_collector.ResultList())
3721 finally:
3722 cpplint._cpplint_state.verbose_level = old_verbose_level
3723
3724 # Completely incorrect header guard
3725 error_collector = ErrorCollector(self.assert_)
3726 cpplint.ProcessFileData(file_path, 'h',
3727 ['#ifndef FOO',
3728 '#define FOO',
3729 '#endif // FOO'],
3730 error_collector)
3731 self.assertEquals(
3732 1,
3733 error_collector.ResultList().count(
3734 '#ifndef header guard has wrong style, please use: %s'
3735 ' [build/header_guard] [5]' % expected_guard),
3736 error_collector.ResultList())
3737 self.assertEquals(
3738 1,
3739 error_collector.ResultList().count(
3740 '#endif line should be "#endif // %s"'
3741 ' [build/header_guard] [5]' % expected_guard),
3742 error_collector.ResultList())
3743
erg@google.coma868d2d2009-10-09 21:18:45 +00003744 # incorrect header guard with nolint
3745 error_collector = ErrorCollector(self.assert_)
3746 cpplint.ProcessFileData(file_path, 'h',
3747 ['#ifndef FOO // NOLINT',
3748 '#define FOO',
3749 '#endif // FOO NOLINT'],
3750 error_collector)
3751 self.assertEquals(
3752 0,
3753 error_collector.ResultList().count(
3754 '#ifndef header guard has wrong style, please use: %s'
3755 ' [build/header_guard] [5]' % expected_guard),
3756 error_collector.ResultList())
3757 self.assertEquals(
3758 0,
3759 error_collector.ResultList().count(
3760 '#endif line should be "#endif // %s"'
3761 ' [build/header_guard] [5]' % expected_guard),
3762 error_collector.ResultList())
3763
erg+personal@google.com05189642010-04-30 20:43:03 +00003764 # Special case for flymake
erg@google.comd350fe52013-01-14 17:51:48 +00003765 for test_file in ['mydir/foo_flymake.h', 'mydir/.flymake/foo.h']:
3766 error_collector = ErrorCollector(self.assert_)
3767 cpplint.ProcessFileData(test_file, 'h', [], error_collector)
3768 self.assertEquals(
3769 1,
3770 error_collector.ResultList().count(
3771 'No #ifndef header guard found, suggested CPP variable is: %s'
3772 ' [build/header_guard] [5]' % expected_guard),
3773 error_collector.ResultList())
erg@google.coma868d2d2009-10-09 21:18:45 +00003774
erg@google.com4d70a882013-04-16 21:06:32 +00003775 def testBuildHeaderGuardWithRoot(self):
3776 file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
3777 'cpplint_test_header.h')
3778 file_info = cpplint.FileInfo(file_path)
3779 if file_info.FullName() == file_info.RepositoryName():
3780 # When FileInfo cannot deduce the root directory of the repository,
3781 # FileInfo.RepositoryName returns the same value as FileInfo.FullName.
3782 # This can happen when this source file was obtained without .svn or
3783 # .git directory. (e.g. using 'svn export' or 'git archive').
3784 # Skip this test in such a case because --root flag makes sense only
3785 # when the root directory of the repository is properly deduced.
3786 return
3787
3788 self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_',
3789 cpplint.GetHeaderGuardCPPVariable(file_path))
3790 cpplint._root = 'cpplint'
3791 self.assertEquals('CPPLINT_TEST_HEADER_H_',
3792 cpplint.GetHeaderGuardCPPVariable(file_path))
3793 # --root flag is ignored if an non-existent directory is specified.
3794 cpplint._root = 'NON_EXISTENT_DIR'
3795 self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_',
3796 cpplint.GetHeaderGuardCPPVariable(file_path))
3797
erg@google.com4e00b9a2009-01-12 23:05:11 +00003798 def testBuildInclude(self):
3799 # Test that include statements have slashes in them.
3800 self.TestLint('#include "foo.h"',
3801 'Include the directory when naming .h files'
3802 ' [build/include] [4]')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003803 self.TestLint('#include "Python.h"', '')
3804 self.TestLint('#include "lua.h"', '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003805
3806 def testBuildPrintfFormat(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00003807 error_collector = ErrorCollector(self.assert_)
3808 cpplint.ProcessFileData(
3809 'foo.cc', 'cc',
3810 [r'printf("\%%d", value);',
3811 r'snprintf(buffer, sizeof(buffer), "\[%d", value);',
3812 r'fprintf(file, "\(%d", value);',
3813 r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);'],
3814 error_collector)
3815 self.assertEquals(
3816 4,
3817 error_collector.Results().count(
3818 '%, [, (, and { are undefined character escapes. Unescape them.'
3819 ' [build/printf_format] [3]'))
erg@google.com4e00b9a2009-01-12 23:05:11 +00003820
avakulenko@google.com02af6282014-06-04 18:53:25 +00003821 error_collector = ErrorCollector(self.assert_)
3822 cpplint.ProcessFileData(
3823 'foo.cc', 'cc',
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003824 ['// Copyright 2014 Your Company.',
avakulenko@google.com02af6282014-06-04 18:53:25 +00003825 r'printf("\\%%%d", value);',
3826 r'printf(R"(\[)");',
3827 r'printf(R"(\[%s)", R"(\])");',
3828 ''],
3829 error_collector)
3830 self.assertEquals('', error_collector.Results())
erg@google.com4e00b9a2009-01-12 23:05:11 +00003831
3832 def testRuntimePrintfFormat(self):
3833 self.TestLint(
3834 r'fprintf(file, "%q", value);',
3835 '%q in format strings is deprecated. Use %ll instead.'
3836 ' [runtime/printf_format] [3]')
3837
3838 self.TestLint(
3839 r'aprintf(file, "The number is %12q", value);',
3840 '%q in format strings is deprecated. Use %ll instead.'
3841 ' [runtime/printf_format] [3]')
3842
3843 self.TestLint(
3844 r'printf(file, "The number is" "%-12q", value);',
3845 '%q in format strings is deprecated. Use %ll instead.'
3846 ' [runtime/printf_format] [3]')
3847
3848 self.TestLint(
3849 r'printf(file, "The number is" "%+12q", value);',
3850 '%q in format strings is deprecated. Use %ll instead.'
3851 ' [runtime/printf_format] [3]')
3852
3853 self.TestLint(
3854 r'printf(file, "The number is" "% 12q", value);',
3855 '%q in format strings is deprecated. Use %ll instead.'
3856 ' [runtime/printf_format] [3]')
3857
3858 self.TestLint(
erg@google.com8a95ecc2011-09-08 00:45:54 +00003859 r'snprintf(file, "Never mix %d and %1$d parameters!", value);',
erg@google.com4e00b9a2009-01-12 23:05:11 +00003860 '%N$ formats are unconventional. Try rewriting to avoid them.'
3861 ' [runtime/printf_format] [2]')
3862
3863 def TestLintLogCodeOnError(self, code, expected_message):
3864 # Special TestLint which logs the input code on error.
3865 result = self.PerformSingleLineLint(code)
3866 if result != expected_message:
3867 self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"'
3868 % (code, result, expected_message))
3869
3870 def testBuildStorageClass(self):
3871 qualifiers = [None, 'const', 'volatile']
3872 signs = [None, 'signed', 'unsigned']
3873 types = ['void', 'char', 'int', 'float', 'double',
3874 'schar', 'int8', 'uint8', 'int16', 'uint16',
3875 'int32', 'uint32', 'int64', 'uint64']
erg@google.comd350fe52013-01-14 17:51:48 +00003876 storage_classes = ['extern', 'register', 'static', 'typedef']
erg@google.com4e00b9a2009-01-12 23:05:11 +00003877
3878 build_storage_class_error_message = (
3879 'Storage class (static, extern, typedef, etc) should be first.'
3880 ' [build/storage_class] [5]')
3881
3882 # Some explicit cases. Legal in C++, deprecated in C99.
3883 self.TestLint('const int static foo = 5;',
3884 build_storage_class_error_message)
3885
3886 self.TestLint('char static foo;',
3887 build_storage_class_error_message)
3888
3889 self.TestLint('double const static foo = 2.0;',
3890 build_storage_class_error_message)
3891
3892 self.TestLint('uint64 typedef unsigned_long_long;',
3893 build_storage_class_error_message)
3894
3895 self.TestLint('int register foo = 0;',
3896 build_storage_class_error_message)
3897
3898 # Since there are a very large number of possibilities, randomly
3899 # construct declarations.
3900 # Make sure that the declaration is logged if there's an error.
3901 # Seed generator with an integer for absolute reproducibility.
3902 random.seed(25)
3903 for unused_i in range(10):
3904 # Build up random list of non-storage-class declaration specs.
3905 other_decl_specs = [random.choice(qualifiers), random.choice(signs),
3906 random.choice(types)]
3907 # remove None
erg@google.comc6671232013-10-25 21:44:03 +00003908 other_decl_specs = [x for x in other_decl_specs if x is not None]
erg@google.com4e00b9a2009-01-12 23:05:11 +00003909
3910 # shuffle
3911 random.shuffle(other_decl_specs)
3912
3913 # insert storage class after the first
3914 storage_class = random.choice(storage_classes)
3915 insertion_point = random.randint(1, len(other_decl_specs))
3916 decl_specs = (other_decl_specs[0:insertion_point]
3917 + [storage_class]
3918 + other_decl_specs[insertion_point:])
3919
3920 self.TestLintLogCodeOnError(
3921 ' '.join(decl_specs) + ';',
3922 build_storage_class_error_message)
3923
3924 # but no error if storage class is first
3925 self.TestLintLogCodeOnError(
3926 storage_class + ' ' + ' '.join(other_decl_specs),
3927 '')
3928
3929 def testLegalCopyright(self):
3930 legal_copyright_message = (
3931 'No copyright message found. '
3932 'You should have a line: "Copyright [year] <Copyright Owner>"'
3933 ' [legal/copyright] [5]')
3934
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00003935 copyright_line = '// Copyright 2014 Google Inc. All Rights Reserved.'
erg@google.com4e00b9a2009-01-12 23:05:11 +00003936
3937 file_path = 'mydir/googleclient/foo.cc'
3938
3939 # There should be a copyright message in the first 10 lines
3940 error_collector = ErrorCollector(self.assert_)
3941 cpplint.ProcessFileData(file_path, 'cc', [], error_collector)
3942 self.assertEquals(
3943 1,
3944 error_collector.ResultList().count(legal_copyright_message))
3945
3946 error_collector = ErrorCollector(self.assert_)
3947 cpplint.ProcessFileData(
3948 file_path, 'cc',
3949 ['' for unused_i in range(10)] + [copyright_line],
3950 error_collector)
3951 self.assertEquals(
3952 1,
3953 error_collector.ResultList().count(legal_copyright_message))
3954
3955 # Test that warning isn't issued if Copyright line appears early enough.
3956 error_collector = ErrorCollector(self.assert_)
3957 cpplint.ProcessFileData(file_path, 'cc', [copyright_line], error_collector)
3958 for message in error_collector.ResultList():
3959 if message.find('legal/copyright') != -1:
3960 self.fail('Unexpected error: %s' % message)
3961
3962 error_collector = ErrorCollector(self.assert_)
3963 cpplint.ProcessFileData(
3964 file_path, 'cc',
3965 ['' for unused_i in range(9)] + [copyright_line],
3966 error_collector)
3967 for message in error_collector.ResultList():
3968 if message.find('legal/copyright') != -1:
3969 self.fail('Unexpected error: %s' % message)
3970
erg@google.com36649102009-03-25 21:18:36 +00003971 def testInvalidIncrement(self):
3972 self.TestLint('*count++;',
3973 'Changing pointer instead of value (or unused value of '
3974 'operator*). [runtime/invalid_increment] [5]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00003975
erg@google.comd350fe52013-01-14 17:51:48 +00003976 def testSnprintfSize(self):
3977 self.TestLint('vsnprintf(NULL, 0, format)', '')
3978 self.TestLint('snprintf(fisk, 1, format)',
3979 'If you can, use sizeof(fisk) instead of 1 as the 2nd arg '
3980 'to snprintf. [runtime/printf] [3]')
avakulenko@google.com02af6282014-06-04 18:53:25 +00003981class Cxx11Test(CpplintTestBase):
3982
3983 def Helper(self, package, extension, lines, count):
3984 filename = package + '/foo.' + extension
3985 lines = lines[:]
3986
3987 # Header files need to have an ifdef guard wrapped around their code.
3988 if extension == 'h':
3989 guard = filename.upper().replace('/', '_').replace('.', '_') + '_'
3990 lines.insert(0, '#ifndef ' + guard)
3991 lines.insert(1, '#define ' + guard)
3992 lines.append('#endif // ' + guard)
3993
3994 # All files need a final blank line.
3995 lines.append('')
3996
3997 # Process the file and check resulting error count.
3998 collector = ErrorCollector(self.assert_)
3999 cpplint.ProcessFileData(filename, extension, lines, collector)
4000 error_list = collector.ResultList()
4001 self.assertEquals(count, len(error_list), error_list)
4002
4003 def TestCxx11Feature(self, code, expected_error):
4004 lines = code.split('\n')
4005 collector = ErrorCollector(self.assert_)
4006 cpplint.RemoveMultiLineComments('foo.h', lines, collector)
4007 clean_lines = cpplint.CleansedLines(lines)
4008 cpplint.FlagCxx11Features('foo.cc', clean_lines, 0, collector)
4009 self.assertEquals(expected_error, collector.Results())
4010
4011 def testBlockedHeaders(self):
4012 self.TestCxx11Feature('#include <mutex>',
4013 '<mutex> is an unapproved C++11 header.'
4014 ' [build/c++11] [5]')
4015
4016 def testBlockedClasses(self):
4017 self.TestCxx11Feature('std::alignment_of<T>',
4018 'std::alignment_of is an unapproved '
4019 'C++11 class or function. Send c-style an example '
4020 'of where it would make your code more readable, '
4021 'and they may let you use it.'
4022 ' [build/c++11] [5]')
4023 self.TestCxx11Feature('std::alignment_offer', '')
4024 self.TestCxx11Feature('mystd::alignment_of', '')
4025 self.TestCxx11Feature('std::binomial_distribution', '')
4026
4027 def testBlockedFunctions(self):
4028 self.TestCxx11Feature('std::alignment_of<int>',
4029 'std::alignment_of is an unapproved '
4030 'C++11 class or function. Send c-style an example '
4031 'of where it would make your code more readable, '
4032 'and they may let you use it.'
4033 ' [build/c++11] [5]')
4034 # Missed because of the lack of "std::". Compiles because ADL
4035 # looks in the namespace of my_shared_ptr, which (presumably) is
4036 # std::. But there will be a lint error somewhere in this file
4037 # since my_shared_ptr had to be defined.
4038 self.TestCxx11Feature('static_pointer_cast<Base>(my_shared_ptr)', '')
4039 self.TestCxx11Feature('std::declval<T>()', '')
erg@google.comd350fe52013-01-14 17:51:48 +00004040
4041 def testExplicitMakePair(self):
4042 self.TestLint('make_pair', '')
4043 self.TestLint('make_pair(42, 42)', '')
4044 self.TestLint('make_pair<',
4045 'For C++11-compatibility, omit template arguments from'
4046 ' make_pair OR use pair directly OR if appropriate,'
4047 ' construct a pair directly'
4048 ' [build/explicit_make_pair] [4]')
4049 self.TestLint('make_pair <',
4050 'For C++11-compatibility, omit template arguments from'
4051 ' make_pair OR use pair directly OR if appropriate,'
4052 ' construct a pair directly'
4053 ' [build/explicit_make_pair] [4]')
4054 self.TestLint('my_make_pair<int, int>', '')
4055
erg@google.com4e00b9a2009-01-12 23:05:11 +00004056class CleansedLinesTest(unittest.TestCase):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004057
erg@google.com4e00b9a2009-01-12 23:05:11 +00004058 def testInit(self):
4059 lines = ['Line 1',
4060 'Line 2',
4061 'Line 3 // Comment test',
erg@google.comd7d27472011-09-07 17:36:35 +00004062 'Line 4 /* Comment test */',
4063 'Line 5 "foo"']
4064
erg@google.com4e00b9a2009-01-12 23:05:11 +00004065
4066 clean_lines = cpplint.CleansedLines(lines)
4067 self.assertEquals(lines, clean_lines.raw_lines)
erg@google.comd7d27472011-09-07 17:36:35 +00004068 self.assertEquals(5, clean_lines.NumLines())
erg@google.com4e00b9a2009-01-12 23:05:11 +00004069
4070 self.assertEquals(['Line 1',
4071 'Line 2',
erg@google.comd7d27472011-09-07 17:36:35 +00004072 'Line 3',
4073 'Line 4',
4074 'Line 5 "foo"'],
erg@google.com4e00b9a2009-01-12 23:05:11 +00004075 clean_lines.lines)
4076
4077 self.assertEquals(['Line 1',
4078 'Line 2',
erg@google.comd7d27472011-09-07 17:36:35 +00004079 'Line 3',
4080 'Line 4',
4081 'Line 5 ""'],
erg@google.com4e00b9a2009-01-12 23:05:11 +00004082 clean_lines.elided)
4083
4084 def testInitEmpty(self):
4085 clean_lines = cpplint.CleansedLines([])
4086 self.assertEquals([], clean_lines.raw_lines)
4087 self.assertEquals(0, clean_lines.NumLines())
4088
4089 def testCollapseStrings(self):
4090 collapse = cpplint.CleansedLines._CollapseStrings
4091 self.assertEquals('""', collapse('""')) # "" (empty)
4092 self.assertEquals('"""', collapse('"""')) # """ (bad)
4093 self.assertEquals('""', collapse('"xyz"')) # "xyz" (string)
4094 self.assertEquals('""', collapse('"\\\""')) # "\"" (string)
4095 self.assertEquals('""', collapse('"\'"')) # "'" (string)
4096 self.assertEquals('"\"', collapse('"\"')) # "\" (bad)
4097 self.assertEquals('""', collapse('"\\\\"')) # "\\" (string)
4098 self.assertEquals('"', collapse('"\\\\\\"')) # "\\\" (bad)
4099 self.assertEquals('""', collapse('"\\\\\\\\"')) # "\\\\" (string)
4100
4101 self.assertEquals('\'\'', collapse('\'\'')) # '' (empty)
4102 self.assertEquals('\'\'', collapse('\'a\'')) # 'a' (char)
4103 self.assertEquals('\'\'', collapse('\'\\\'\'')) # '\'' (char)
4104 self.assertEquals('\'', collapse('\'\\\'')) # '\' (bad)
4105 self.assertEquals('', collapse('\\012')) # '\012' (char)
4106 self.assertEquals('', collapse('\\xfF0')) # '\xfF0' (char)
4107 self.assertEquals('', collapse('\\n')) # '\n' (char)
avakulenko@google.com02af6282014-06-04 18:53:25 +00004108 self.assertEquals(r'\#', collapse('\\#')) # '\#' (bad)
4109
4110 self.assertEquals('"" + ""', collapse('"\'" + "\'"'))
4111 self.assertEquals("'', ''", collapse("'\"', '\"'"))
4112 self.assertEquals('""[0b10]', collapse('"a\'b"[0b1\'0]'))
4113
4114 self.assertEquals('42', collapse("4'2"))
4115 self.assertEquals('0b0101', collapse("0b0'1'0'1"))
4116 self.assertEquals('1048576', collapse("1'048'576"))
4117 self.assertEquals('0X100000', collapse("0X10'0000"))
4118 self.assertEquals('0004000000', collapse("0'004'000'000"))
4119 self.assertEquals('1.602176565e-19', collapse("1.602'176'565e-19"))
4120 self.assertEquals('\'\' + 0xffff', collapse("'i' + 0xf'f'f'f"))
4121 self.assertEquals('sizeof\'\' == 1', collapse("sizeof'x' == 1"))
4122 self.assertEquals('0x.03p100', collapse('0x.0\'3p1\'0\'0'))
4123 self.assertEquals('123.45', collapse('1\'23.4\'5'))
erg@google.com4e00b9a2009-01-12 23:05:11 +00004124
4125 self.assertEquals('StringReplace(body, "", "");',
4126 collapse('StringReplace(body, "\\\\", "\\\\\\\\");'))
4127 self.assertEquals('\'\' ""',
4128 collapse('\'"\' "foo"'))
4129
4130
4131class OrderOfIncludesTest(CpplintTestBase):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004132
erg@google.com4e00b9a2009-01-12 23:05:11 +00004133 def setUp(self):
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004134 CpplintTestBase.setUp(self)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004135 self.include_state = cpplint._IncludeState()
erg@google.com4e00b9a2009-01-12 23:05:11 +00004136 os.path.abspath = lambda value: value
4137
erg@google.com4e00b9a2009-01-12 23:05:11 +00004138 def testCheckNextIncludeOrder_OtherThenCpp(self):
4139 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4140 cpplint._OTHER_HEADER))
4141 self.assertEqual('Found C++ system header after other header',
4142 self.include_state.CheckNextIncludeOrder(
4143 cpplint._CPP_SYS_HEADER))
4144
4145 def testCheckNextIncludeOrder_CppThenC(self):
4146 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4147 cpplint._CPP_SYS_HEADER))
4148 self.assertEqual('Found C system header after C++ system header',
4149 self.include_state.CheckNextIncludeOrder(
4150 cpplint._C_SYS_HEADER))
4151
4152 def testCheckNextIncludeOrder_LikelyThenCpp(self):
4153 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4154 cpplint._LIKELY_MY_HEADER))
4155 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4156 cpplint._CPP_SYS_HEADER))
4157
4158 def testCheckNextIncludeOrder_PossibleThenCpp(self):
4159 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4160 cpplint._POSSIBLE_MY_HEADER))
4161 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4162 cpplint._CPP_SYS_HEADER))
4163
4164 def testCheckNextIncludeOrder_CppThenLikely(self):
4165 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4166 cpplint._CPP_SYS_HEADER))
4167 # This will eventually fail.
4168 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4169 cpplint._LIKELY_MY_HEADER))
4170
4171 def testCheckNextIncludeOrder_CppThenPossible(self):
4172 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4173 cpplint._CPP_SYS_HEADER))
4174 self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4175 cpplint._POSSIBLE_MY_HEADER))
4176
4177 def testClassifyInclude(self):
4178 file_info = cpplint.FileInfo
4179 classify_include = cpplint._ClassifyInclude
4180 self.assertEqual(cpplint._C_SYS_HEADER,
4181 classify_include(file_info('foo/foo.cc'),
4182 'stdio.h',
4183 True))
4184 self.assertEqual(cpplint._CPP_SYS_HEADER,
4185 classify_include(file_info('foo/foo.cc'),
4186 'string',
4187 True))
4188 self.assertEqual(cpplint._CPP_SYS_HEADER,
4189 classify_include(file_info('foo/foo.cc'),
4190 'typeinfo',
4191 True))
4192 self.assertEqual(cpplint._OTHER_HEADER,
4193 classify_include(file_info('foo/foo.cc'),
4194 'string',
4195 False))
4196
4197 self.assertEqual(cpplint._LIKELY_MY_HEADER,
4198 classify_include(file_info('foo/foo.cc'),
4199 'foo/foo-inl.h',
4200 False))
4201 self.assertEqual(cpplint._LIKELY_MY_HEADER,
4202 classify_include(file_info('foo/internal/foo.cc'),
4203 'foo/public/foo.h',
4204 False))
4205 self.assertEqual(cpplint._POSSIBLE_MY_HEADER,
4206 classify_include(file_info('foo/internal/foo.cc'),
4207 'foo/other/public/foo.h',
4208 False))
4209 self.assertEqual(cpplint._OTHER_HEADER,
4210 classify_include(file_info('foo/internal/foo.cc'),
4211 'foo/other/public/foop.h',
4212 False))
4213
4214 def testTryDropCommonSuffixes(self):
4215 self.assertEqual('foo/foo', cpplint._DropCommonSuffixes('foo/foo-inl.h'))
4216 self.assertEqual('foo/bar/foo',
4217 cpplint._DropCommonSuffixes('foo/bar/foo_inl.h'))
4218 self.assertEqual('foo/foo', cpplint._DropCommonSuffixes('foo/foo.cc'))
4219 self.assertEqual('foo/foo_unusualinternal',
4220 cpplint._DropCommonSuffixes('foo/foo_unusualinternal.h'))
4221 self.assertEqual('',
4222 cpplint._DropCommonSuffixes('_test.cc'))
4223 self.assertEqual('test',
4224 cpplint._DropCommonSuffixes('test.cc'))
4225
4226 def testRegression(self):
4227 def Format(includes):
erg@google.comfd5da632013-10-25 17:39:45 +00004228 include_list = []
4229 for header_path in includes:
4230 if header_path:
4231 include_list.append('#include %s\n' % header_path)
4232 else:
4233 include_list.append('\n')
4234 return ''.join(include_list)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004235
4236 # Test singleton cases first.
4237 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"foo/foo.h"']), '')
4238 self.TestLanguageRulesCheck('foo/foo.cc', Format(['<stdio.h>']), '')
4239 self.TestLanguageRulesCheck('foo/foo.cc', Format(['<string>']), '')
4240 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"foo/foo-inl.h"']), '')
4241 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"bar/bar-inl.h"']), '')
4242 self.TestLanguageRulesCheck('foo/foo.cc', Format(['"bar/bar.h"']), '')
4243
4244 # Test everything in a good and new order.
4245 self.TestLanguageRulesCheck('foo/foo.cc',
4246 Format(['"foo/foo.h"',
4247 '"foo/foo-inl.h"',
4248 '<stdio.h>',
4249 '<string>',
avakulenko@google.com02af6282014-06-04 18:53:25 +00004250 '<unordered_map>',
erg@google.com4e00b9a2009-01-12 23:05:11 +00004251 '"bar/bar-inl.h"',
4252 '"bar/bar.h"']),
4253 '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004254
4255 # Test bad orders.
4256 self.TestLanguageRulesCheck(
4257 'foo/foo.cc',
4258 Format(['<string>', '<stdio.h>']),
4259 'Found C system header after C++ system header.'
4260 ' Should be: foo.h, c system, c++ system, other.'
4261 ' [build/include_order] [4]')
4262 self.TestLanguageRulesCheck(
4263 'foo/foo.cc',
4264 Format(['"foo/bar-inl.h"',
4265 '"foo/foo-inl.h"']),
4266 '')
erg@google.comfd5da632013-10-25 17:39:45 +00004267 self.TestLanguageRulesCheck(
4268 'foo/foo.cc',
4269 Format(['"foo/e.h"',
4270 '"foo/b.h"', # warning here (e>b)
4271 '"foo/c.h"',
4272 '"foo/d.h"',
4273 '"foo/a.h"']), # warning here (d>a)
4274 ['Include "foo/b.h" not in alphabetical order'
4275 ' [build/include_alpha] [4]',
4276 'Include "foo/a.h" not in alphabetical order'
4277 ' [build/include_alpha] [4]'])
erg@google.com4e00b9a2009-01-12 23:05:11 +00004278 # -inl.h headers are no longer special.
4279 self.TestLanguageRulesCheck('foo/foo.cc',
4280 Format(['"foo/foo-inl.h"', '<string>']),
4281 '')
4282 self.TestLanguageRulesCheck('foo/foo.cc',
4283 Format(['"foo/bar.h"', '"foo/bar-inl.h"']),
4284 '')
4285 # Test componentized header. OK to have my header in ../public dir.
4286 self.TestLanguageRulesCheck('foo/internal/foo.cc',
4287 Format(['"foo/public/foo.h"', '<string>']),
4288 '')
4289 # OK to have my header in other dir (not stylistically, but
4290 # cpplint isn't as good as a human).
4291 self.TestLanguageRulesCheck('foo/internal/foo.cc',
4292 Format(['"foo/other/public/foo.h"',
4293 '<string>']),
4294 '')
erg@google.coma868d2d2009-10-09 21:18:45 +00004295 self.TestLanguageRulesCheck('foo/foo.cc',
4296 Format(['"foo/foo.h"',
4297 '<string>',
4298 '"base/google.h"',
4299 '"base/flags.h"']),
4300 'Include "base/flags.h" not in alphabetical '
4301 'order [build/include_alpha] [4]')
4302 # According to the style, -inl.h should come before .h, but we don't
4303 # complain about that.
4304 self.TestLanguageRulesCheck('foo/foo.cc',
4305 Format(['"foo/foo-inl.h"',
4306 '"foo/foo.h"',
4307 '"base/google.h"',
4308 '"base/google-inl.h"']),
4309 '')
erg@google.comfd5da632013-10-25 17:39:45 +00004310 # Allow project includes to be separated by blank lines
4311 self.TestLanguageRulesCheck('a/a.cc',
4312 Format(['"a/a.h"',
4313 '<string>',
4314 '"base/google.h"',
4315 '',
4316 '"a/b.h"']),
4317 '')
4318 self.TestLanguageRulesCheck('a/a.cc',
4319 Format(['"a/a.h"',
4320 '<string>',
4321 '"base/google.h"',
4322 '"a/b.h"']),
4323 'Include "a/b.h" not in alphabetical '
4324 'order [build/include_alpha] [4]')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004325
erg@google.com2aa59982013-10-28 19:09:25 +00004326 # Test conditional includes
4327 self.TestLanguageRulesCheck(
4328 'a/a.cc',
4329 ''.join(['#include <string.h>\n',
4330 '#include "base/port.h"\n',
4331 '#include <initializer_list>\n']),
4332 ('Found C++ system header after other header. '
4333 'Should be: a.h, c system, c++ system, other. '
4334 '[build/include_order] [4]'))
4335 self.TestLanguageRulesCheck(
4336 'a/a.cc',
4337 ''.join(['#include <string.h>\n',
4338 '#include "base/port.h"\n',
4339 '#ifdef LANG_CXX11\n',
4340 '#include <initializer_list>\n',
4341 '#endif // LANG_CXX11\n']),
4342 '')
4343 self.TestLanguageRulesCheck(
4344 'a/a.cc',
4345 ''.join(['#include <string.h>\n',
4346 '#ifdef LANG_CXX11\n',
4347 '#include "base/port.h"\n',
4348 '#include <initializer_list>\n',
4349 '#endif // LANG_CXX11\n']),
4350 ('Found C++ system header after other header. '
4351 'Should be: a.h, c system, c++ system, other. '
4352 '[build/include_order] [4]'))
4353
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004354 # Third party headers are exempt from order checks
4355 self.TestLanguageRulesCheck('foo/foo.cc',
4356 Format(['<string>', '"Python.h"', '<vector>']),
4357 '')
4358
erg@google.com4e00b9a2009-01-12 23:05:11 +00004359
4360class CheckForFunctionLengthsTest(CpplintTestBase):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004361
erg@google.com4e00b9a2009-01-12 23:05:11 +00004362 def setUp(self):
4363 # Reducing these thresholds for the tests speeds up tests significantly.
4364 self.old_normal_trigger = cpplint._FunctionState._NORMAL_TRIGGER
4365 self.old_test_trigger = cpplint._FunctionState._TEST_TRIGGER
4366
4367 cpplint._FunctionState._NORMAL_TRIGGER = 10
4368 cpplint._FunctionState._TEST_TRIGGER = 25
4369
4370 def tearDown(self):
4371 cpplint._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger
4372 cpplint._FunctionState._TEST_TRIGGER = self.old_test_trigger
4373
4374 def TestFunctionLengthsCheck(self, code, expected_message):
4375 """Check warnings for long function bodies are as expected.
4376
4377 Args:
4378 code: C++ source code expected to generate a warning message.
4379 expected_message: Message expected to be generated by the C++ code.
4380 """
4381 self.assertEquals(expected_message,
4382 self.PerformFunctionLengthsCheck(code))
4383
4384 def TriggerLines(self, error_level):
4385 """Return number of lines needed to trigger a function length warning.
4386
4387 Args:
4388 error_level: --v setting for cpplint.
4389
4390 Returns:
4391 Number of lines needed to trigger a function length warning.
4392 """
4393 return cpplint._FunctionState._NORMAL_TRIGGER * 2**error_level
4394
4395 def TestLines(self, error_level):
4396 """Return number of lines needed to trigger a test function length warning.
4397
4398 Args:
4399 error_level: --v setting for cpplint.
4400
4401 Returns:
4402 Number of lines needed to trigger a test function length warning.
4403 """
4404 return cpplint._FunctionState._TEST_TRIGGER * 2**error_level
4405
4406 def TestFunctionLengthCheckDefinition(self, lines, error_level):
4407 """Generate long function definition and check warnings are as expected.
4408
4409 Args:
4410 lines: Number of lines to generate.
4411 error_level: --v setting for cpplint.
4412 """
4413 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4414 self.TestFunctionLengthsCheck(
4415 'void test(int x)' + self.FunctionBody(lines),
4416 ('Small and focused functions are preferred: '
4417 'test() has %d non-comment lines '
4418 '(error triggered by exceeding %d lines).'
4419 ' [readability/fn_size] [%d]'
4420 % (lines, trigger_level, error_level)))
4421
4422 def TestFunctionLengthCheckDefinitionOK(self, lines):
4423 """Generate shorter function definition and check no warning is produced.
4424
4425 Args:
4426 lines: Number of lines to generate.
4427 """
4428 self.TestFunctionLengthsCheck(
4429 'void test(int x)' + self.FunctionBody(lines),
4430 '')
4431
4432 def TestFunctionLengthCheckAtErrorLevel(self, error_level):
4433 """Generate and check function at the trigger level for --v setting.
4434
4435 Args:
4436 error_level: --v setting for cpplint.
4437 """
4438 self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level),
4439 error_level)
4440
4441 def TestFunctionLengthCheckBelowErrorLevel(self, error_level):
4442 """Generate and check function just below the trigger level for --v setting.
4443
4444 Args:
4445 error_level: --v setting for cpplint.
4446 """
4447 self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level)-1,
4448 error_level-1)
4449
4450 def TestFunctionLengthCheckAboveErrorLevel(self, error_level):
4451 """Generate and check function just above the trigger level for --v setting.
4452
4453 Args:
4454 error_level: --v setting for cpplint.
4455 """
4456 self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level)+1,
4457 error_level)
4458
4459 def FunctionBody(self, number_of_lines):
4460 return ' {\n' + ' this_is_just_a_test();\n'*number_of_lines + '}'
4461
4462 def FunctionBodyWithBlankLines(self, number_of_lines):
4463 return ' {\n' + ' this_is_just_a_test();\n\n'*number_of_lines + '}'
4464
4465 def FunctionBodyWithNoLints(self, number_of_lines):
4466 return (' {\n' +
4467 ' this_is_just_a_test(); // NOLINT\n'*number_of_lines + '}')
4468
4469 # Test line length checks.
4470 def testFunctionLengthCheckDeclaration(self):
4471 self.TestFunctionLengthsCheck(
4472 'void test();', # Not a function definition
4473 '')
4474
4475 def testFunctionLengthCheckDeclarationWithBlockFollowing(self):
4476 self.TestFunctionLengthsCheck(
4477 ('void test();\n'
4478 + self.FunctionBody(66)), # Not a function definition
4479 '')
4480
4481 def testFunctionLengthCheckClassDefinition(self):
4482 self.TestFunctionLengthsCheck( # Not a function definition
4483 'class Test' + self.FunctionBody(66) + ';',
4484 '')
4485
4486 def testFunctionLengthCheckTrivial(self):
4487 self.TestFunctionLengthsCheck(
4488 'void test() {}', # Not counted
4489 '')
4490
4491 def testFunctionLengthCheckEmpty(self):
4492 self.TestFunctionLengthsCheck(
4493 'void test() {\n}',
4494 '')
4495
4496 def testFunctionLengthCheckDefinitionBelowSeverity0(self):
4497 old_verbosity = cpplint._SetVerboseLevel(0)
4498 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(0)-1)
4499 cpplint._SetVerboseLevel(old_verbosity)
4500
4501 def testFunctionLengthCheckDefinitionAtSeverity0(self):
4502 old_verbosity = cpplint._SetVerboseLevel(0)
4503 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(0))
4504 cpplint._SetVerboseLevel(old_verbosity)
4505
4506 def testFunctionLengthCheckDefinitionAboveSeverity0(self):
4507 old_verbosity = cpplint._SetVerboseLevel(0)
4508 self.TestFunctionLengthCheckAboveErrorLevel(0)
4509 cpplint._SetVerboseLevel(old_verbosity)
4510
4511 def testFunctionLengthCheckDefinitionBelowSeverity1v0(self):
4512 old_verbosity = cpplint._SetVerboseLevel(0)
4513 self.TestFunctionLengthCheckBelowErrorLevel(1)
4514 cpplint._SetVerboseLevel(old_verbosity)
4515
4516 def testFunctionLengthCheckDefinitionAtSeverity1v0(self):
4517 old_verbosity = cpplint._SetVerboseLevel(0)
4518 self.TestFunctionLengthCheckAtErrorLevel(1)
4519 cpplint._SetVerboseLevel(old_verbosity)
4520
4521 def testFunctionLengthCheckDefinitionBelowSeverity1(self):
4522 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(1)-1)
4523
4524 def testFunctionLengthCheckDefinitionAtSeverity1(self):
4525 self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(1))
4526
4527 def testFunctionLengthCheckDefinitionAboveSeverity1(self):
4528 self.TestFunctionLengthCheckAboveErrorLevel(1)
4529
4530 def testFunctionLengthCheckDefinitionSeverity1PlusBlanks(self):
4531 error_level = 1
4532 error_lines = self.TriggerLines(error_level) + 1
4533 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4534 self.TestFunctionLengthsCheck(
4535 'void test_blanks(int x)' + self.FunctionBody(error_lines),
4536 ('Small and focused functions are preferred: '
4537 'test_blanks() has %d non-comment lines '
4538 '(error triggered by exceeding %d lines).'
4539 ' [readability/fn_size] [%d]')
4540 % (error_lines, trigger_level, error_level))
4541
4542 def testFunctionLengthCheckComplexDefinitionSeverity1(self):
4543 error_level = 1
4544 error_lines = self.TriggerLines(error_level) + 1
4545 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4546 self.TestFunctionLengthsCheck(
4547 ('my_namespace::my_other_namespace::MyVeryLongTypeName*\n'
4548 'my_namespace::my_other_namespace::MyFunction(int arg1, char* arg2)'
4549 + self.FunctionBody(error_lines)),
4550 ('Small and focused functions are preferred: '
4551 'my_namespace::my_other_namespace::MyFunction()'
4552 ' has %d non-comment lines '
4553 '(error triggered by exceeding %d lines).'
4554 ' [readability/fn_size] [%d]')
4555 % (error_lines, trigger_level, error_level))
4556
4557 def testFunctionLengthCheckDefinitionSeverity1ForTest(self):
4558 error_level = 1
4559 error_lines = self.TestLines(error_level) + 1
4560 trigger_level = self.TestLines(cpplint._VerboseLevel())
4561 self.TestFunctionLengthsCheck(
4562 'TEST_F(Test, Mutator)' + self.FunctionBody(error_lines),
4563 ('Small and focused functions are preferred: '
4564 'TEST_F(Test, Mutator) has %d non-comment lines '
4565 '(error triggered by exceeding %d lines).'
4566 ' [readability/fn_size] [%d]')
4567 % (error_lines, trigger_level, error_level))
4568
4569 def testFunctionLengthCheckDefinitionSeverity1ForSplitLineTest(self):
4570 error_level = 1
4571 error_lines = self.TestLines(error_level) + 1
4572 trigger_level = self.TestLines(cpplint._VerboseLevel())
4573 self.TestFunctionLengthsCheck(
4574 ('TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,\n'
4575 ' FixGoogleUpdate_AllValues_MachineApp)' # note: 4 spaces
4576 + self.FunctionBody(error_lines)),
4577 ('Small and focused functions are preferred: '
4578 'TEST_F(GoogleUpdateRecoveryRegistryProtectedTest, ' # 1 space
4579 'FixGoogleUpdate_AllValues_MachineApp) has %d non-comment lines '
4580 '(error triggered by exceeding %d lines).'
4581 ' [readability/fn_size] [%d]')
4582 % (error_lines+1, trigger_level, error_level))
4583
4584 def testFunctionLengthCheckDefinitionSeverity1ForBadTestDoesntBreak(self):
4585 error_level = 1
4586 error_lines = self.TestLines(error_level) + 1
4587 trigger_level = self.TestLines(cpplint._VerboseLevel())
4588 self.TestFunctionLengthsCheck(
4589 ('TEST_F('
4590 + self.FunctionBody(error_lines)),
4591 ('Small and focused functions are preferred: '
4592 'TEST_F has %d non-comment lines '
4593 '(error triggered by exceeding %d lines).'
4594 ' [readability/fn_size] [%d]')
4595 % (error_lines, trigger_level, error_level))
4596
4597 def testFunctionLengthCheckDefinitionSeverity1WithEmbeddedNoLints(self):
4598 error_level = 1
4599 error_lines = self.TriggerLines(error_level)+1
4600 trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4601 self.TestFunctionLengthsCheck(
4602 'void test(int x)' + self.FunctionBodyWithNoLints(error_lines),
4603 ('Small and focused functions are preferred: '
4604 'test() has %d non-comment lines '
4605 '(error triggered by exceeding %d lines).'
4606 ' [readability/fn_size] [%d]')
4607 % (error_lines, trigger_level, error_level))
4608
4609 def testFunctionLengthCheckDefinitionSeverity1WithNoLint(self):
4610 self.TestFunctionLengthsCheck(
4611 ('void test(int x)' + self.FunctionBody(self.TriggerLines(1))
4612 + ' // NOLINT -- long function'),
4613 '')
4614
4615 def testFunctionLengthCheckDefinitionBelowSeverity2(self):
4616 self.TestFunctionLengthCheckBelowErrorLevel(2)
4617
4618 def testFunctionLengthCheckDefinitionSeverity2(self):
4619 self.TestFunctionLengthCheckAtErrorLevel(2)
4620
4621 def testFunctionLengthCheckDefinitionAboveSeverity2(self):
4622 self.TestFunctionLengthCheckAboveErrorLevel(2)
4623
4624 def testFunctionLengthCheckDefinitionBelowSeverity3(self):
4625 self.TestFunctionLengthCheckBelowErrorLevel(3)
4626
4627 def testFunctionLengthCheckDefinitionSeverity3(self):
4628 self.TestFunctionLengthCheckAtErrorLevel(3)
4629
4630 def testFunctionLengthCheckDefinitionAboveSeverity3(self):
4631 self.TestFunctionLengthCheckAboveErrorLevel(3)
4632
4633 def testFunctionLengthCheckDefinitionBelowSeverity4(self):
4634 self.TestFunctionLengthCheckBelowErrorLevel(4)
4635
4636 def testFunctionLengthCheckDefinitionSeverity4(self):
4637 self.TestFunctionLengthCheckAtErrorLevel(4)
4638
4639 def testFunctionLengthCheckDefinitionAboveSeverity4(self):
4640 self.TestFunctionLengthCheckAboveErrorLevel(4)
4641
4642 def testFunctionLengthCheckDefinitionBelowSeverity5(self):
4643 self.TestFunctionLengthCheckBelowErrorLevel(5)
4644
4645 def testFunctionLengthCheckDefinitionAtSeverity5(self):
4646 self.TestFunctionLengthCheckAtErrorLevel(5)
4647
4648 def testFunctionLengthCheckDefinitionAboveSeverity5(self):
4649 self.TestFunctionLengthCheckAboveErrorLevel(5)
4650
4651 def testFunctionLengthCheckDefinitionHugeLines(self):
4652 # 5 is the limit
4653 self.TestFunctionLengthCheckDefinition(self.TriggerLines(10), 5)
4654
4655 def testFunctionLengthNotDeterminable(self):
erg@google.com4e00b9a2009-01-12 23:05:11 +00004656 # Macro invocation without terminating semicolon.
4657 self.TestFunctionLengthsCheck(
4658 'MACRO(arg)',
4659 '')
4660
4661 # Macro with underscores
4662 self.TestFunctionLengthsCheck(
4663 'MACRO_WITH_UNDERSCORES(arg1, arg2, arg3)',
4664 '')
avakulenko@google.coma8ee7ea2014-08-11 19:41:35 +00004665
erg@google.com4e00b9a2009-01-12 23:05:11 +00004666 self.TestFunctionLengthsCheck(
4667 'NonMacro(arg)',
4668 'Lint failed to find start of function body.'
4669 ' [readability/fn_size] [5]')
4670
avakulenko@google.com02af6282014-06-04 18:53:25 +00004671
4672def TrimExtraIndent(text_block):
4673 """Trim a uniform amount of whitespace off of each line in a string.
4674
4675 Compute the minimum indent on all non blank lines and trim that from each, so
4676 that the block of text has no extra indentation.
4677
4678 Args:
4679 text_block: a multiline string
4680
4681 Returns:
4682 text_block with the common whitespace indent of each line removed.
4683 """
4684
4685 def CountLeadingWhitespace(s):
4686 count = 0
4687 for c in s:
4688 if not c.isspace():
4689 break
4690 count += 1
4691 return count
4692 # find the minimum indent (except for blank lines)
4693 min_indent = min([CountLeadingWhitespace(line)
4694 for line in text_block.split('\n') if line])
4695 return '\n'.join([line[min_indent:] for line in text_block.split('\n')])
4696
4697
4698class CloseExpressionTest(unittest.TestCase):
4699
erg@google.comd350fe52013-01-14 17:51:48 +00004700 def setUp(self):
avakulenko@google.com02af6282014-06-04 18:53:25 +00004701 self.lines = cpplint.CleansedLines(
4702 # 1 2 3 4 5
4703 # 0123456789012345678901234567890123456789012345678901234567890
4704 ['// Line 0',
4705 'inline RCULocked<X>::ReadPtr::ReadPtr(const RCULocked* rcu) {',
4706 ' DCHECK(!(data & kFlagMask)) << "Error";',
4707 '}',
4708 '// Line 4',
4709 'RCULocked<X>::WritePtr::WritePtr(RCULocked* rcu)',
4710 ' : lock_(&rcu_->mutex_) {',
4711 '}',
4712 '// Line 8',
4713 'template <typename T, typename... A>',
4714 'typename std::enable_if<',
4715 ' std::is_array<T>::value && (std::extent<T>::value > 0)>::type',
4716 'MakeUnique(A&&... a) = delete;',
4717 '// Line 13',
4718 'auto x = []() {};',
4719 '// Line 15',
4720 'template <typename U>',
4721 'friend bool operator==(const reffed_ptr& a,',
4722 ' const reffed_ptr<U>& b) {',
4723 ' return a.get() == b.get();',
4724 '}',
4725 '// Line 21'])
4726
4727 def testCloseExpression(self):
4728 # List of positions to test:
4729 # (start line, start position, end line, end position + 1)
4730 positions = [(1, 16, 1, 19),
4731 (1, 37, 1, 59),
4732 (1, 60, 3, 1),
4733 (2, 8, 2, 29),
4734 (2, 30, 22, -1), # Left shift operator
4735 (9, 9, 9, 36),
4736 (10, 23, 11, 59),
4737 (11, 54, 22, -1), # Greater than operator
4738 (14, 9, 14, 11),
4739 (14, 11, 14, 13),
4740 (14, 14, 14, 16),
4741 (17, 22, 18, 46),
4742 (18, 47, 20, 1)]
4743 for p in positions:
4744 (_, line, column) = cpplint.CloseExpression(self.lines, p[0], p[1])
4745 self.assertEquals((p[2], p[3]), (line, column))
4746
4747 def testReverseCloseExpression(self):
4748 # List of positions to test:
4749 # (end line, end position, start line, start position)
4750 positions = [(1, 18, 1, 16),
4751 (1, 58, 1, 37),
4752 (2, 27, 2, 10),
4753 (2, 28, 2, 8),
4754 (6, 18, 0, -1), # -> operator
4755 (9, 35, 9, 9),
4756 (11, 54, 0, -1), # Greater than operator
4757 (11, 57, 11, 31),
4758 (14, 10, 14, 9),
4759 (14, 12, 14, 11),
4760 (14, 15, 14, 14),
4761 (18, 45, 17, 22),
4762 (20, 0, 18, 47)]
4763 for p in positions:
4764 (_, line, column) = cpplint.ReverseCloseExpression(self.lines, p[0], p[1])
4765 self.assertEquals((p[2], p[3]), (line, column))
4766
4767
4768class NestingStateTest(unittest.TestCase):
4769
4770 def setUp(self):
4771 self.nesting_state = cpplint.NestingState()
erg@google.comd350fe52013-01-14 17:51:48 +00004772 self.error_collector = ErrorCollector(self.assert_)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004773
erg@google.comd350fe52013-01-14 17:51:48 +00004774 def UpdateWithLines(self, lines):
4775 clean_lines = cpplint.CleansedLines(lines)
4776 for line in xrange(clean_lines.NumLines()):
4777 self.nesting_state.Update('test.cc',
4778 clean_lines, line, self.error_collector)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004779
erg@google.comd350fe52013-01-14 17:51:48 +00004780 def testEmpty(self):
4781 self.UpdateWithLines([])
4782 self.assertEquals(self.nesting_state.stack, [])
erg@google.com4e00b9a2009-01-12 23:05:11 +00004783
erg@google.comd350fe52013-01-14 17:51:48 +00004784 def testNamespace(self):
4785 self.UpdateWithLines(['namespace {'])
4786 self.assertEquals(len(self.nesting_state.stack), 1)
4787 self.assertTrue(isinstance(self.nesting_state.stack[0],
4788 cpplint._NamespaceInfo))
4789 self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
4790 self.assertEquals(self.nesting_state.stack[0].name, '')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004791
erg@google.comd350fe52013-01-14 17:51:48 +00004792 self.UpdateWithLines(['namespace outer { namespace inner'])
4793 self.assertEquals(len(self.nesting_state.stack), 3)
4794 self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
4795 self.assertTrue(self.nesting_state.stack[1].seen_open_brace)
4796 self.assertFalse(self.nesting_state.stack[2].seen_open_brace)
4797 self.assertEquals(self.nesting_state.stack[0].name, '')
4798 self.assertEquals(self.nesting_state.stack[1].name, 'outer')
4799 self.assertEquals(self.nesting_state.stack[2].name, 'inner')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004800
erg@google.comd350fe52013-01-14 17:51:48 +00004801 self.UpdateWithLines(['{'])
4802 self.assertTrue(self.nesting_state.stack[2].seen_open_brace)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004803
erg@google.comd350fe52013-01-14 17:51:48 +00004804 self.UpdateWithLines(['}', '}}'])
4805 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004806
erg@google.comd350fe52013-01-14 17:51:48 +00004807 def testClass(self):
4808 self.UpdateWithLines(['class A {'])
4809 self.assertEquals(len(self.nesting_state.stack), 1)
4810 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
4811 self.assertEquals(self.nesting_state.stack[0].name, 'A')
4812 self.assertFalse(self.nesting_state.stack[0].is_derived)
erg@google.comfd5da632013-10-25 17:39:45 +00004813 self.assertEquals(self.nesting_state.stack[0].class_indent, 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004814
erg@google.comd350fe52013-01-14 17:51:48 +00004815 self.UpdateWithLines(['};',
4816 'struct B : public A {'])
4817 self.assertEquals(len(self.nesting_state.stack), 1)
4818 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
4819 self.assertEquals(self.nesting_state.stack[0].name, 'B')
4820 self.assertTrue(self.nesting_state.stack[0].is_derived)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004821
erg@google.comd350fe52013-01-14 17:51:48 +00004822 self.UpdateWithLines(['};',
4823 'class C',
4824 ': public A {'])
4825 self.assertEquals(len(self.nesting_state.stack), 1)
4826 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
4827 self.assertEquals(self.nesting_state.stack[0].name, 'C')
4828 self.assertTrue(self.nesting_state.stack[0].is_derived)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004829
erg@google.comd350fe52013-01-14 17:51:48 +00004830 self.UpdateWithLines(['};',
4831 'template<T>'])
4832 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004833
erg@google.comfd5da632013-10-25 17:39:45 +00004834 self.UpdateWithLines(['class D {', ' class E {'])
erg@google.comd350fe52013-01-14 17:51:48 +00004835 self.assertEquals(len(self.nesting_state.stack), 2)
4836 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
4837 self.assertEquals(self.nesting_state.stack[0].name, 'D')
4838 self.assertFalse(self.nesting_state.stack[0].is_derived)
4839 self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
4840 self.assertEquals(self.nesting_state.stack[1].name, 'E')
4841 self.assertFalse(self.nesting_state.stack[1].is_derived)
erg@google.comfd5da632013-10-25 17:39:45 +00004842 self.assertEquals(self.nesting_state.stack[1].class_indent, 2)
erg@google.comd350fe52013-01-14 17:51:48 +00004843 self.assertEquals(self.nesting_state.InnermostClass().name, 'E')
erg@google.comd7d27472011-09-07 17:36:35 +00004844
erg@google.comd350fe52013-01-14 17:51:48 +00004845 self.UpdateWithLines(['}', '}'])
4846 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.comd7d27472011-09-07 17:36:35 +00004847
erg@google.comd350fe52013-01-14 17:51:48 +00004848 def testClassAccess(self):
4849 self.UpdateWithLines(['class A {'])
4850 self.assertEquals(len(self.nesting_state.stack), 1)
4851 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
4852 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.comd7d27472011-09-07 17:36:35 +00004853
erg@google.comd350fe52013-01-14 17:51:48 +00004854 self.UpdateWithLines([' public:'])
4855 self.assertEquals(self.nesting_state.stack[0].access, 'public')
4856 self.UpdateWithLines([' protracted:'])
4857 self.assertEquals(self.nesting_state.stack[0].access, 'public')
4858 self.UpdateWithLines([' protected:'])
4859 self.assertEquals(self.nesting_state.stack[0].access, 'protected')
4860 self.UpdateWithLines([' private:'])
4861 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004862
erg@google.comd350fe52013-01-14 17:51:48 +00004863 self.UpdateWithLines([' struct B {'])
4864 self.assertEquals(len(self.nesting_state.stack), 2)
4865 self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
4866 self.assertEquals(self.nesting_state.stack[1].access, 'public')
4867 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004868
erg@google.comd350fe52013-01-14 17:51:48 +00004869 self.UpdateWithLines([' protected :'])
4870 self.assertEquals(self.nesting_state.stack[1].access, 'protected')
4871 self.assertEquals(self.nesting_state.stack[0].access, 'private')
erg@google.com4e00b9a2009-01-12 23:05:11 +00004872
erg@google.comd350fe52013-01-14 17:51:48 +00004873 self.UpdateWithLines([' }', '}'])
4874 self.assertEquals(len(self.nesting_state.stack), 0)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004875
erg@google.comd350fe52013-01-14 17:51:48 +00004876 def testStruct(self):
4877 self.UpdateWithLines(['struct A {'])
4878 self.assertEquals(len(self.nesting_state.stack), 1)
4879 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
4880 self.assertEquals(self.nesting_state.stack[0].name, 'A')
4881 self.assertFalse(self.nesting_state.stack[0].is_derived)
erg@google.com4e00b9a2009-01-12 23:05:11 +00004882
erg@google.comd350fe52013-01-14 17:51:48 +00004883 self.UpdateWithLines(['}',
4884 'void Func(struct B arg) {'])
4885 self.assertEquals(len(self.nesting_state.stack), 1)
4886 self.assertFalse(isinstance(self.nesting_state.stack[0],
4887 cpplint._ClassInfo))
erg@google.com4e00b9a2009-01-12 23:05:11 +00004888
erg@google.comd350fe52013-01-14 17:51:48 +00004889 self.UpdateWithLines(['}'])
4890 self.assertEquals(len(self.nesting_state.stack), 0)
erg+personal@google.com05189642010-04-30 20:43:03 +00004891
erg@google.comd350fe52013-01-14 17:51:48 +00004892 def testPreprocessor(self):
4893 self.assertEquals(len(self.nesting_state.pp_stack), 0)
4894 self.UpdateWithLines(['#if MACRO1'])
4895 self.assertEquals(len(self.nesting_state.pp_stack), 1)
4896 self.UpdateWithLines(['#endif'])
4897 self.assertEquals(len(self.nesting_state.pp_stack), 0)
4898
4899 self.UpdateWithLines(['#ifdef MACRO2'])
4900 self.assertEquals(len(self.nesting_state.pp_stack), 1)
4901 self.UpdateWithLines(['#else'])
4902 self.assertEquals(len(self.nesting_state.pp_stack), 1)
4903 self.UpdateWithLines(['#ifdef MACRO3'])
4904 self.assertEquals(len(self.nesting_state.pp_stack), 2)
4905 self.UpdateWithLines(['#elif MACRO4'])
4906 self.assertEquals(len(self.nesting_state.pp_stack), 2)
4907 self.UpdateWithLines(['#endif'])
4908 self.assertEquals(len(self.nesting_state.pp_stack), 1)
4909 self.UpdateWithLines(['#endif'])
4910 self.assertEquals(len(self.nesting_state.pp_stack), 0)
4911
4912 self.UpdateWithLines(['#ifdef MACRO5',
4913 'class A {',
4914 '#elif MACRO6',
4915 'class B {',
4916 '#else',
4917 'class C {',
4918 '#endif'])
4919 self.assertEquals(len(self.nesting_state.pp_stack), 0)
4920 self.assertEquals(len(self.nesting_state.stack), 1)
4921 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
4922 self.assertEquals(self.nesting_state.stack[0].name, 'A')
4923 self.UpdateWithLines(['};'])
4924 self.assertEquals(len(self.nesting_state.stack), 0)
4925
4926 self.UpdateWithLines(['class D',
4927 '#ifdef MACRO7'])
4928 self.assertEquals(len(self.nesting_state.pp_stack), 1)
4929 self.assertEquals(len(self.nesting_state.stack), 1)
4930 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
4931 self.assertEquals(self.nesting_state.stack[0].name, 'D')
4932 self.assertFalse(self.nesting_state.stack[0].is_derived)
4933
4934 self.UpdateWithLines(['#elif MACRO8',
4935 ': public E'])
4936 self.assertEquals(len(self.nesting_state.stack), 1)
4937 self.assertEquals(self.nesting_state.stack[0].name, 'D')
4938 self.assertTrue(self.nesting_state.stack[0].is_derived)
4939 self.assertFalse(self.nesting_state.stack[0].seen_open_brace)
4940
4941 self.UpdateWithLines(['#else',
4942 '{'])
4943 self.assertEquals(len(self.nesting_state.stack), 1)
4944 self.assertEquals(self.nesting_state.stack[0].name, 'D')
4945 self.assertFalse(self.nesting_state.stack[0].is_derived)
4946 self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
4947
4948 self.UpdateWithLines(['#endif'])
4949 self.assertEquals(len(self.nesting_state.pp_stack), 0)
4950 self.assertEquals(len(self.nesting_state.stack), 1)
4951 self.assertEquals(self.nesting_state.stack[0].name, 'D')
4952 self.assertFalse(self.nesting_state.stack[0].is_derived)
4953 self.assertFalse(self.nesting_state.stack[0].seen_open_brace)
4954
4955 self.UpdateWithLines([';'])
4956 self.assertEquals(len(self.nesting_state.stack), 0)
4957
4958 def testTemplate(self):
4959 self.UpdateWithLines(['template <T,',
4960 ' class Arg1 = tmpl<T> >'])
4961 self.assertEquals(len(self.nesting_state.stack), 0)
4962 self.UpdateWithLines(['class A {'])
4963 self.assertEquals(len(self.nesting_state.stack), 1)
4964 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
4965 self.assertEquals(self.nesting_state.stack[0].name, 'A')
4966
4967 self.UpdateWithLines(['};',
4968 'template <T,',
4969 ' template <typename, typename> class B>',
4970 'class C'])
4971 self.assertEquals(len(self.nesting_state.stack), 1)
4972 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
4973 self.assertEquals(self.nesting_state.stack[0].name, 'C')
4974 self.UpdateWithLines([';'])
4975 self.assertEquals(len(self.nesting_state.stack), 0)
4976
4977 self.UpdateWithLines(['class D : public Tmpl<E>'])
4978 self.assertEquals(len(self.nesting_state.stack), 1)
4979 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
4980 self.assertEquals(self.nesting_state.stack[0].name, 'D')
4981
avakulenko@google.com02af6282014-06-04 18:53:25 +00004982 self.UpdateWithLines(['{', '};'])
4983 self.assertEquals(len(self.nesting_state.stack), 0)
4984
4985 self.UpdateWithLines(['template <class F,',
4986 ' class G,',
4987 ' class H,',
4988 ' typename I>',
4989 'static void Func() {'])
4990 self.assertEquals(len(self.nesting_state.stack), 1)
4991 self.assertFalse(isinstance(self.nesting_state.stack[0],
4992 cpplint._ClassInfo))
4993 self.UpdateWithLines(['}',
4994 'template <class J> class K {'])
4995 self.assertEquals(len(self.nesting_state.stack), 1)
4996 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
4997 self.assertEquals(self.nesting_state.stack[0].name, 'K')
4998
erg@google.comfd5da632013-10-25 17:39:45 +00004999 def testTemplateInnerClass(self):
5000 self.UpdateWithLines(['class A {',
5001 ' public:'])
5002 self.assertEquals(len(self.nesting_state.stack), 1)
5003 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5004
5005 self.UpdateWithLines([' template <class B>',
5006 ' class C<alloc<B> >',
5007 ' : public A {'])
5008 self.assertEquals(len(self.nesting_state.stack), 2)
5009 self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5010
erg@google.comd350fe52013-01-14 17:51:48 +00005011 def testArguments(self):
5012 self.UpdateWithLines(['class A {'])
5013 self.assertEquals(len(self.nesting_state.stack), 1)
5014 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5015 self.assertEquals(self.nesting_state.stack[0].name, 'A')
5016 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5017
5018 self.UpdateWithLines([' void Func(',
5019 ' struct X arg1,'])
5020 self.assertEquals(len(self.nesting_state.stack), 1)
5021 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5022 self.UpdateWithLines([' struct X *arg2);'])
5023 self.assertEquals(len(self.nesting_state.stack), 1)
5024 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5025
5026 self.UpdateWithLines(['};'])
5027 self.assertEquals(len(self.nesting_state.stack), 0)
5028
5029 self.UpdateWithLines(['struct B {'])
5030 self.assertEquals(len(self.nesting_state.stack), 1)
5031 self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5032 self.assertEquals(self.nesting_state.stack[0].name, 'B')
5033
5034 self.UpdateWithLines(['#ifdef MACRO',
5035 ' void Func(',
5036 ' struct X arg1'])
5037 self.assertEquals(len(self.nesting_state.stack), 1)
5038 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5039 self.UpdateWithLines(['#else'])
5040
5041 self.assertEquals(len(self.nesting_state.stack), 1)
5042 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5043 self.UpdateWithLines([' void Func(',
5044 ' struct X arg1'])
5045 self.assertEquals(len(self.nesting_state.stack), 1)
5046 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5047
5048 self.UpdateWithLines(['#endif'])
5049 self.assertEquals(len(self.nesting_state.stack), 1)
5050 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5051 self.UpdateWithLines([' struct X *arg2);'])
5052 self.assertEquals(len(self.nesting_state.stack), 1)
5053 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5054
5055 self.UpdateWithLines(['};'])
5056 self.assertEquals(len(self.nesting_state.stack), 0)
5057
5058 def testInlineAssembly(self):
5059 self.UpdateWithLines(['void CopyRow_SSE2(const uint8* src, uint8* dst,',
5060 ' int count) {'])
5061 self.assertEquals(len(self.nesting_state.stack), 1)
5062 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5063 self.assertEquals(self.nesting_state.stack[-1].inline_asm, cpplint._NO_ASM)
5064
5065 self.UpdateWithLines([' asm volatile ('])
5066 self.assertEquals(len(self.nesting_state.stack), 1)
5067 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5068 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5069 cpplint._INSIDE_ASM)
5070
5071 self.UpdateWithLines([' "sub %0,%1 \\n"',
5072 ' "1: \\n"',
5073 ' "movdqa (%0),%%xmm0 \\n"',
5074 ' "movdqa 0x10(%0),%%xmm1 \\n"',
5075 ' "movdqa %%xmm0,(%0,%1) \\n"',
5076 ' "movdqa %%xmm1,0x10(%0,%1) \\n"',
5077 ' "lea 0x20(%0),%0 \\n"',
5078 ' "sub $0x20,%2 \\n"',
5079 ' "jg 1b \\n"',
5080 ' : "+r"(src), // %0',
5081 ' "+r"(dst), // %1',
5082 ' "+r"(count) // %2',
5083 ' :',
5084 ' : "memory", "cc"'])
5085 self.assertEquals(len(self.nesting_state.stack), 1)
5086 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5087 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5088 cpplint._INSIDE_ASM)
5089
5090 self.UpdateWithLines(['#if defined(__SSE2__)',
5091 ' , "xmm0", "xmm1"'])
5092 self.assertEquals(len(self.nesting_state.stack), 1)
5093 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5094 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5095 cpplint._INSIDE_ASM)
5096
5097 self.UpdateWithLines(['#endif'])
5098 self.assertEquals(len(self.nesting_state.stack), 1)
5099 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5100 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5101 cpplint._INSIDE_ASM)
5102
5103 self.UpdateWithLines([' );'])
5104 self.assertEquals(len(self.nesting_state.stack), 1)
5105 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5106 self.assertEquals(self.nesting_state.stack[-1].inline_asm, cpplint._END_ASM)
5107
5108 self.UpdateWithLines(['__asm {'])
5109 self.assertEquals(len(self.nesting_state.stack), 2)
5110 self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5111 self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5112 cpplint._BLOCK_ASM)
5113
5114 self.UpdateWithLines(['}'])
5115 self.assertEquals(len(self.nesting_state.stack), 1)
5116
5117 self.UpdateWithLines(['}'])
5118 self.assertEquals(len(self.nesting_state.stack), 0)
5119
erg+personal@google.com05189642010-04-30 20:43:03 +00005120
erg@google.coma868d2d2009-10-09 21:18:45 +00005121# pylint: disable-msg=C6409
5122def setUp():
erg@google.com8a95ecc2011-09-08 00:45:54 +00005123 """Runs before all tests are executed.
erg@google.coma868d2d2009-10-09 21:18:45 +00005124 """
5125 # Enable all filters, so we don't miss anything that is off by default.
5126 cpplint._DEFAULT_FILTERS = []
5127 cpplint._cpplint_state.SetFilters('')
erg@google.com4e00b9a2009-01-12 23:05:11 +00005128
erg@google.coma868d2d2009-10-09 21:18:45 +00005129
5130# pylint: disable-msg=C6409
erg@google.com4e00b9a2009-01-12 23:05:11 +00005131def tearDown():
5132 """A global check to make sure all error-categories have been tested.
5133
5134 The main tearDown() routine is the only code we can guarantee will be
5135 run after all other tests have been executed.
5136 """
5137 try:
5138 if _run_verifyallcategoriesseen:
5139 ErrorCollector(None).VerifyAllCategoriesAreSeen()
5140 except NameError:
5141 # If nobody set the global _run_verifyallcategoriesseen, then
5142 # we assume we shouldn't run the test
5143 pass
5144
erg@google.coma868d2d2009-10-09 21:18:45 +00005145
erg@google.com4e00b9a2009-01-12 23:05:11 +00005146if __name__ == '__main__':
erg@google.com4e00b9a2009-01-12 23:05:11 +00005147 # We don't want to run the VerifyAllCategoriesAreSeen() test unless
5148 # we're running the full test suite: if we only run one test,
5149 # obviously we're not going to see all the error categories. So we
5150 # only run VerifyAllCategoriesAreSeen() when no commandline flags
5151 # are passed in.
5152 global _run_verifyallcategoriesseen
5153 _run_verifyallcategoriesseen = (len(sys.argv) == 1)
5154
erg@google.coma868d2d2009-10-09 21:18:45 +00005155 setUp()
erg@google.com4e00b9a2009-01-12 23:05:11 +00005156 unittest.main()
erg@google.coma868d2d2009-10-09 21:18:45 +00005157 tearDown()