2 # -*- coding: utf-8; -*-
4 # Copyright (C) 2009 Google Inc. All rights reserved.
5 # Copyright (C) 2009 Torch Mobile Inc.
6 # Copyright (C) 2009 Apple Inc. All rights reserved.
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are
12 # * Redistributions of source code must retain the above copyright
13 # notice, this list of conditions and the following disclaimer.
14 # * Redistributions in binary form must reproduce the above
15 # copyright notice, this list of conditions and the following disclaimer
16 # in the documentation and/or other materials provided with the
18 # * Neither the name of Google Inc. nor the names of its
19 # contributors may be used to endorse or promote products derived from
20 # this software without specific prior written permission.
22 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 """Unit test for cpp_style.py."""
36 # FIXME: Add a good test that tests UpdateIncludeState.
46 # This class works as an error collector and replaces cpp_style.Error
47 # function for the unit tests. We also verify each category we see
48 # is in cpp_style._ERROR_CATEGORIES, to help keep that list up to date.
50 # These are a global list, covering all categories seen ever.
51 _ERROR_CATEGORIES = [x.strip() # get rid of leading whitespace
52 for x in cpp_style._ERROR_CATEGORIES.split()]
53 _SEEN_ERROR_CATEGORIES = {}
55 def __init__(self, assert_fn):
56 """assert_fn: a function to call when we notice a problem."""
57 self._assert_fn = assert_fn
60 def __call__(self, unused_filename, unused_linenum,
61 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
66 if cpp_style._should_print_error(category, confidence):
67 self._errors.append('%s [%s] [%d]' % (message, category, confidence))
70 if len(self._errors) < 2:
71 return ''.join(self._errors) # Most tests expect to have a string.
73 return self._errors # Let's give a list if there is more than one.
75 def result_list(self):
78 def verify_all_categories_are_seen(self):
79 """Fails if there's a category in _ERROR_CATEGORIES - _SEEN_ERROR_CATEGORIES.
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!
87 for category in self._ERROR_CATEGORIES:
88 if category not in self._SEEN_ERROR_CATEGORIES:
90 sys.exit('FATAL ERROR: There are no tests for category "%s"' % category)
92 def remove_if_present(self, substr):
93 for (index, error) in enumerate(self._errors):
94 if error.find(substr) != -1:
95 self._errors = self._errors[0:index] + self._errors[(index + 1):]
99 # This class is a lame mock of codecs. We do not verify filename, mode, or
100 # encoding, but for the current use case it is not needed.
102 def __init__(self, mock_file):
103 self.mock_file = mock_file
105 def open(self, unused_filename, unused_mode, unused_encoding, _): # NOLINT
106 # (lint doesn't like open as a method name)
107 return self.mock_file
110 class CppStyleTestBase(unittest.TestCase):
111 """Provides some useful helper functions for cpp_style tests."""
113 # Perform lint on single line of input and return the error message.
114 def perform_single_line_lint(self, code, file_name):
115 error_collector = ErrorCollector(self.assert_)
116 lines = code.split('\n')
117 cpp_style.remove_multi_line_comments(file_name, lines, error_collector)
118 clean_lines = cpp_style.CleansedLines(lines)
119 include_state = cpp_style._IncludeState()
120 function_state = cpp_style._FunctionState()
121 ext = file_name[file_name.rfind('.') + 1:]
122 class_state = cpp_style._ClassState()
123 cpp_style.process_line(file_name, ext, clean_lines, 0,
124 include_state, function_state,
125 class_state, error_collector)
126 # Single-line lint tests are allowed to fail the 'unlintable function'
128 error_collector.remove_if_present(
129 'Lint failed to find start of function body.')
130 return error_collector.results()
132 # Perform lint over multiple lines and return the error message.
133 def perform_multi_line_lint(self, code, file_name):
134 error_collector = ErrorCollector(self.assert_)
135 lines = code.split('\n')
136 cpp_style.remove_multi_line_comments(file_name, lines, error_collector)
137 lines = cpp_style.CleansedLines(lines)
138 ext = file_name[file_name.rfind('.') + 1:]
139 class_state = cpp_style._ClassState()
140 for i in xrange(lines.num_lines()):
141 cpp_style.check_style(file_name, lines, i, ext, error_collector)
142 cpp_style.check_for_non_standard_constructs(file_name, lines, i, class_state,
144 class_state.check_finished(file_name, error_collector)
145 return error_collector.results()
147 # Similar to perform_multi_line_lint, but calls check_language instead of
148 # check_for_non_standard_constructs
149 def perform_language_rules_check(self, file_name, code):
150 error_collector = ErrorCollector(self.assert_)
151 include_state = cpp_style._IncludeState()
152 lines = code.split('\n')
153 cpp_style.remove_multi_line_comments(file_name, lines, error_collector)
154 lines = cpp_style.CleansedLines(lines)
155 ext = file_name[file_name.rfind('.') + 1:]
156 for i in xrange(lines.num_lines()):
157 cpp_style.check_language(file_name, lines, i, ext, include_state,
159 return error_collector.results()
161 def perform_function_lengths_check(self, code):
162 """Perform Lint function length check on block of code and return warnings.
164 Builds up an array of lines corresponding to the code and strips comments
165 using cpp_style functions.
167 Establishes an error collector and invokes the function length checking
168 function following cpp_style's pattern.
171 code: C++ source code expected to generate a warning message.
174 The accumulated errors.
176 file_name = 'foo.cpp'
177 error_collector = ErrorCollector(self.assert_)
178 function_state = cpp_style._FunctionState()
179 lines = code.split('\n')
180 cpp_style.remove_multi_line_comments(file_name, lines, error_collector)
181 lines = cpp_style.CleansedLines(lines)
182 for i in xrange(lines.num_lines()):
183 cpp_style.check_for_function_lengths(file_name, lines, i,
184 function_state, error_collector)
185 return error_collector.results()
187 def perform_include_what_you_use(self, code, filename='foo.h', io=codecs):
188 # First, build up the include state.
189 error_collector = ErrorCollector(self.assert_)
190 include_state = cpp_style._IncludeState()
191 lines = code.split('\n')
192 cpp_style.remove_multi_line_comments(filename, lines, error_collector)
193 lines = cpp_style.CleansedLines(lines)
194 for i in xrange(lines.num_lines()):
195 cpp_style.check_language(filename, lines, i, '.h', include_state,
197 # We could clear the error_collector here, but this should
198 # also be fine, since our IncludeWhatYouUse unittests do not
199 # have language problems.
201 # Second, look for missing includes.
202 cpp_style.check_for_include_what_you_use(filename, lines, include_state,
204 return error_collector.results()
206 # Perform lint and compare the error message with "expected_message".
207 def assert_lint(self, code, expected_message, file_name='foo.cpp'):
208 self.assertEquals(expected_message, self.perform_single_line_lint(code, file_name))
210 def assert_lint_one_of_many_errors_re(self, code, expected_message_re, file_name='foo.cpp'):
211 messages = self.perform_single_line_lint(code, file_name)
212 for message in messages:
213 if re.search(expected_message_re, message):
216 self.assertEquals(expected_message, messages)
218 def assert_multi_line_lint(self, code, expected_message, file_name='foo.h'):
219 self.assertEquals(expected_message, self.perform_multi_line_lint(code, file_name))
221 def assert_multi_line_lint_re(self, code, expected_message_re, file_name='foo.h'):
222 message = self.perform_multi_line_lint(code, file_name)
223 if not re.search(expected_message_re, message):
224 self.fail('Message was:\n' + message + 'Expected match to "' + expected_message_re + '"')
226 def assert_language_rules_check(self, file_name, code, expected_message):
227 self.assertEquals(expected_message,
228 self.perform_language_rules_check(file_name, code))
230 def assert_include_what_you_use(self, code, expected_message):
231 self.assertEquals(expected_message,
232 self.perform_include_what_you_use(code))
234 def assert_blank_lines_check(self, lines, start_errors, end_errors):
235 error_collector = ErrorCollector(self.assert_)
236 cpp_style.process_file_data('foo.cpp', 'cpp', lines, error_collector)
239 error_collector.results().count(
240 'Blank line at the start of a code block. Is this needed?'
241 ' [whitespace/blank_line] [2]'))
244 error_collector.results().count(
245 'Blank line at the end of a code block. Is this needed?'
246 ' [whitespace/blank_line] [3]'))
249 class CppStyleTest(CppStyleTestBase):
251 # Test get line width.
252 def test_get_line_width(self):
253 self.assertEquals(0, cpp_style.get_line_width(''))
254 self.assertEquals(10, cpp_style.get_line_width(u'x' * 10))
255 self.assertEquals(16, cpp_style.get_line_width(u'都|道|府|県|支庁'))
257 def test_find_next_multi_line_comment_start(self):
258 self.assertEquals(1, cpp_style.find_next_multi_line_comment_start([''], 0))
260 lines = ['a', 'b', '/* c']
261 self.assertEquals(2, cpp_style.find_next_multi_line_comment_start(lines, 0))
263 lines = ['char a[] = "/*";'] # not recognized as comment.
264 self.assertEquals(1, cpp_style.find_next_multi_line_comment_start(lines, 0))
266 def test_find_next_multi_line_comment_end(self):
267 self.assertEquals(1, cpp_style.find_next_multi_line_comment_end([''], 0))
268 lines = ['a', 'b', ' c */']
269 self.assertEquals(2, cpp_style.find_next_multi_line_comment_end(lines, 0))
271 def test_remove_multi_line_comments_from_range(self):
272 lines = ['a', ' /* comment ', ' * still comment', ' comment */ ', 'b']
273 cpp_style.remove_multi_line_comments_from_range(lines, 1, 4)
274 self.assertEquals(['a', '// dummy', '// dummy', '// dummy', 'b'], lines)
276 def test_spaces_at_end_of_line(self):
279 'Line ends in whitespace. Consider deleting these extra spaces.'
280 ' [whitespace/end_of_line] [4]')
282 # Test C-style cast cases.
283 def test_cstyle_cast(self):
286 'Using C-style cast. Use static_cast<int>(...) instead'
287 ' [readability/casting] [4]')
289 'int *a = (int *)DEFINED_VALUE;',
290 'Using C-style cast. Use reinterpret_cast<int *>(...) instead'
291 ' [readability/casting] [4]', 'foo.c')
293 'uint16 a = (uint16)1.0;',
294 'Using C-style cast. Use static_cast<uint16>(...) instead'
295 ' [readability/casting] [4]')
297 'int32 a = (int32)1.0;',
298 'Using C-style cast. Use static_cast<int32>(...) instead'
299 ' [readability/casting] [4]')
301 'uint64 a = (uint64)1.0;',
302 'Using C-style cast. Use static_cast<uint64>(...) instead'
303 ' [readability/casting] [4]')
305 # Test taking address of casts (runtime/casting)
306 def test_runtime_casting(self):
308 'int* x = &static_cast<int*>(foo);',
309 'Are you taking an address of a cast? '
310 'This is dangerous: could be a temp var. '
311 'Take the address before doing the cast, rather than after'
312 ' [runtime/casting] [4]')
315 'int* x = &dynamic_cast<int *>(foo);',
316 ['Are you taking an address of a cast? '
317 'This is dangerous: could be a temp var. '
318 'Take the address before doing the cast, rather than after'
319 ' [runtime/casting] [4]',
320 'Do not use dynamic_cast<>. If you need to cast within a class '
321 'hierarchy, use static_cast<> to upcast. Google doesn\'t support '
322 'RTTI. [runtime/rtti] [5]'])
325 'int* x = &reinterpret_cast<int *>(foo);',
326 'Are you taking an address of a cast? '
327 'This is dangerous: could be a temp var. '
328 'Take the address before doing the cast, rather than after'
329 ' [runtime/casting] [4]')
331 # It's OK to cast an address.
333 'int* x = reinterpret_cast<int *>(&foo);',
336 def test_runtime_selfinit(self):
338 'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }',
339 'You seem to be initializing a member variable with itself.'
340 ' [runtime/init] [4]')
342 'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }',
345 'Foo::Foo(Bar r) : r_(r), l_(r_), ll_(l_) { }',
348 def test_runtime_rtti(self):
349 statement = 'int* x = dynamic_cast<int*>(&foo);'
351 'Do not use dynamic_cast<>. If you need to cast within a class '
352 'hierarchy, use static_cast<> to upcast. Google doesn\'t support '
353 'RTTI. [runtime/rtti] [5]')
354 # dynamic_cast is disallowed in most files.
355 self.assert_language_rules_check('foo.cpp', statement, error_message)
356 self.assert_language_rules_check('foo.h', statement, error_message)
357 # It is explicitly allowed in tests, however.
358 self.assert_language_rules_check('foo_test.cpp', statement, '')
359 self.assert_language_rules_check('foo_unittest.cpp', statement, '')
360 self.assert_language_rules_check('foo_regtest.cpp', statement, '')
362 # We cannot test this functionality because of difference of
363 # function definitions. Anyway, we may never enable this.
365 # # Test for unnamed arguments in a method.
366 # def test_check_for_unnamed_params(self):
367 # message = ('All parameters should be named in a function'
368 # ' [readability/function] [3]')
369 # self.assert_lint('virtual void A(int*) const;', message)
370 # self.assert_lint('virtual void B(void (*fn)(int*));', message)
371 # self.assert_lint('virtual void C(int*);', message)
372 # self.assert_lint('void *(*f)(void *) = x;', message)
373 # self.assert_lint('void Method(char*) {', message)
374 # self.assert_lint('void Method(char*);', message)
375 # self.assert_lint('void Method(char* /*x*/);', message)
376 # self.assert_lint('typedef void (*Method)(int32);', message)
377 # self.assert_lint('static void operator delete[](void*) throw();', message)
379 # self.assert_lint('virtual void D(int* p);', '')
380 # self.assert_lint('void operator delete(void* x) throw();', '')
381 # self.assert_lint('void Method(char* x)\n{', '')
382 # self.assert_lint('void Method(char* /*x*/)\n{', '')
383 # self.assert_lint('void Method(char* x);', '')
384 # self.assert_lint('typedef void (*Method)(int32 x);', '')
385 # self.assert_lint('static void operator delete[](void* x) throw();', '')
386 # self.assert_lint('static void operator delete[](void* /*x*/) throw();', '')
388 # # This one should technically warn, but doesn't because the function
389 # # pointer is confusing.
390 # self.assert_lint('virtual void E(void (*fn)(int* p));', '')
392 # Test deprecated casts such as int(d)
393 def test_deprecated_cast(self):
396 'Using deprecated casting style. '
397 'Use static_cast<int>(...) instead'
398 ' [readability/casting] [4]')
399 # Checks for false positives...
401 'int a = int(); // Constructor, o.k.',
404 'X::X() : a(int()) {} // default Constructor, o.k.',
407 'operator bool(); // Conversion operator, o.k.',
410 # The second parameter to a gMock method definition is a function signature
411 # that often looks like a bad cast but should not picked up by lint.
412 def test_mock_method(self):
414 'MOCK_METHOD0(method, int());',
417 'MOCK_CONST_METHOD1(method, float(string));',
420 'MOCK_CONST_METHOD2_T(method, double(float, float));',
423 # Test sizeof(type) cases.
424 def test_sizeof_type(self):
427 'Using sizeof(type). Use sizeof(varname) instead if possible'
428 ' [runtime/sizeof] [1]')
431 'Using sizeof(type). Use sizeof(varname) instead if possible'
432 ' [runtime/sizeof] [1]')
434 # Test typedef cases. There was a bug that cpp_style misidentified
435 # typedef for pointer to function as C-style cast and produced
436 # false-positive error messages.
437 def test_typedef_for_pointer_to_function(self):
439 'typedef void (*Func)(int x);',
442 'typedef void (*Func)(int *x);',
445 'typedef void Func(int x);',
448 'typedef void Func(int *x);',
451 def test_include_what_you_use_no_implementation_files(self):
452 code = 'std::vector<int> foo;'
453 self.assertEquals('Add #include <vector> for vector<>'
454 ' [build/include_what_you_use] [4]',
455 self.perform_include_what_you_use(code, 'foo.h'))
456 self.assertEquals('',
457 self.perform_include_what_you_use(code, 'foo.cpp'))
459 def test_include_what_you_use(self):
460 self.assert_include_what_you_use(
462 std::vector<int> foo;
465 self.assert_include_what_you_use(
467 std::pair<int,int> foo;
470 self.assert_include_what_you_use(
471 '''#include <multimap>
472 std::pair<int,int> foo;
475 self.assert_include_what_you_use(
476 '''#include <hash_map>
477 std::pair<int,int> foo;
480 self.assert_include_what_you_use(
481 '''#include <utility>
482 std::pair<int,int> foo;
485 self.assert_include_what_you_use(
487 DECLARE_string(foobar);
490 self.assert_include_what_you_use(
492 DEFINE_string(foobar, "", "");
495 self.assert_include_what_you_use(
497 std::pair<int,int> foo;
499 'Add #include <utility> for pair<>'
500 ' [build/include_what_you_use] [4]')
501 self.assert_include_what_you_use(
502 '''#include "base/foobar.h"
503 std::vector<int> foo;
505 'Add #include <vector> for vector<>'
506 ' [build/include_what_you_use] [4]')
507 self.assert_include_what_you_use(
511 'Add #include <set> for set<>'
512 ' [build/include_what_you_use] [4]')
513 self.assert_include_what_you_use(
514 '''#include "base/foobar.h"
515 hash_map<int, int> foobar;
517 'Add #include <hash_map> for hash_map<>'
518 ' [build/include_what_you_use] [4]')
519 self.assert_include_what_you_use(
520 '''#include "base/foobar.h"
521 bool foobar = std::less<int>(0,1);
523 'Add #include <functional> for less<>'
524 ' [build/include_what_you_use] [4]')
525 self.assert_include_what_you_use(
526 '''#include "base/foobar.h"
527 bool foobar = min<int>(0,1);
529 'Add #include <algorithm> for min [build/include_what_you_use] [4]')
530 self.assert_include_what_you_use(
531 'void a(const string &foobar);',
532 'Add #include <string> for string [build/include_what_you_use] [4]')
533 self.assert_include_what_you_use(
534 '''#include "base/foobar.h"
535 bool foobar = swap(0,1);
537 'Add #include <algorithm> for swap [build/include_what_you_use] [4]')
538 self.assert_include_what_you_use(
539 '''#include "base/foobar.h"
540 bool foobar = transform(a.begin(), a.end(), b.start(), Foo);
542 'Add #include <algorithm> for transform '
543 '[build/include_what_you_use] [4]')
544 self.assert_include_what_you_use(
545 '''#include "base/foobar.h"
546 bool foobar = min_element(a.begin(), a.end());
548 'Add #include <algorithm> for min_element '
549 '[build/include_what_you_use] [4]')
550 self.assert_include_what_you_use(
555 self.assert_include_what_you_use(
557 void a(const std::multimap<int,string> &foobar);
559 'Add #include <map> for multimap<>'
560 ' [build/include_what_you_use] [4]')
561 self.assert_include_what_you_use(
563 void a(const std::priority_queue<int> &foobar);
566 self.assert_include_what_you_use(
567 '''#include "base/basictypes.h"
568 #include "base/port.h"
572 vector<string> hajoa;''', '')
573 self.assert_include_what_you_use(
575 int i = numeric_limits<int>::max()
577 'Add #include <limits> for numeric_limits<>'
578 ' [build/include_what_you_use] [4]')
579 self.assert_include_what_you_use(
581 int i = numeric_limits<int>::max()
585 # Test the UpdateIncludeState code path.
586 mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"']
587 message = self.perform_include_what_you_use(
588 '#include "config.h"\n'
589 '#include "blah/a.h"\n',
590 filename='blah/a.cpp',
591 io=MockIo(mock_header_contents))
592 self.assertEquals(message, '')
594 mock_header_contents = ['#include <set>']
595 message = self.perform_include_what_you_use(
596 '''#include "config.h"
599 std::set<int> foo;''',
600 filename='blah/a.cpp',
601 io=MockIo(mock_header_contents))
602 self.assertEquals(message, '')
604 # If there's just a .cpp and the header can't be found then it's ok.
605 message = self.perform_include_what_you_use(
606 '''#include "config.h"
609 std::set<int> foo;''',
610 filename='blah/a.cpp')
611 self.assertEquals(message, '')
613 # Make sure we find the headers with relative paths.
614 mock_header_contents = ['']
615 message = self.perform_include_what_you_use(
616 '''#include "config.h"
619 std::set<int> foo;''' % os.path.basename(os.getcwd()),
621 io=MockIo(mock_header_contents))
622 self.assertEquals(message, 'Add #include <set> for set<> '
623 '[build/include_what_you_use] [4]')
625 def test_files_belong_to_same_module(self):
626 f = cpp_style.files_belong_to_same_module
627 self.assertEquals((True, ''), f('a.cpp', 'a.h'))
628 self.assertEquals((True, ''), f('base/google.cpp', 'base/google.h'))
629 self.assertEquals((True, ''), f('base/google_test.cpp', 'base/google.h'))
630 self.assertEquals((True, ''),
631 f('base/google_unittest.cpp', 'base/google.h'))
632 self.assertEquals((True, ''),
633 f('base/internal/google_unittest.cpp',
634 'base/public/google.h'))
635 self.assertEquals((True, 'xxx/yyy/'),
636 f('xxx/yyy/base/internal/google_unittest.cpp',
637 'base/public/google.h'))
638 self.assertEquals((True, 'xxx/yyy/'),
639 f('xxx/yyy/base/google_unittest.cpp',
640 'base/public/google.h'))
641 self.assertEquals((True, ''),
642 f('base/google_unittest.cpp', 'base/google-inl.h'))
643 self.assertEquals((True, '/home/build/google3/'),
644 f('/home/build/google3/base/google.cpp', 'base/google.h'))
646 self.assertEquals((False, ''),
647 f('/home/build/google3/base/google.cpp', 'basu/google.h'))
648 self.assertEquals((False, ''), f('a.cpp', 'b.h'))
650 def test_cleanse_line(self):
651 self.assertEquals('int foo = 0; ',
652 cpp_style.cleanse_comments('int foo = 0; // danger!'))
653 self.assertEquals('int o = 0;',
654 cpp_style.cleanse_comments('int /* foo */ o = 0;'))
655 self.assertEquals('foo(int a, int b);',
656 cpp_style.cleanse_comments('foo(int a /* abc */, int b);'))
657 self.assertEqual('f(a, b);',
658 cpp_style.cleanse_comments('f(a, /* name */ b);'))
659 self.assertEqual('f(a, b);',
660 cpp_style.cleanse_comments('f(a /* name */, b);'))
661 self.assertEqual('f(a, b);',
662 cpp_style.cleanse_comments('f(a, /* name */b);'))
664 def test_multi_line_comments(self):
665 # missing explicit is bad
666 self.assert_multi_line_lint(
670 Foo(int f); // should cause a lint warning in code
674 self.assert_multi_line_lint(
675 r'''/* int a = 0; multi-liner
676 static const int b = 0;''',
677 'Could not find end of multi-line comment'
678 ' [readability/multiline_comment] [5]')
679 self.assert_multi_line_lint(r''' /* multi-line comment''',
680 'Could not find end of multi-line comment'
681 ' [readability/multiline_comment] [5]')
682 self.assert_multi_line_lint(r''' // /* comment, but not multi-line''', '')
684 def test_multiline_strings(self):
685 multiline_string_error_message = (
686 'Multi-line string ("...") found. This lint script doesn\'t '
687 'do well with such strings, and may give bogus warnings. They\'re '
688 'ugly and unnecessary, and you should use concatenation instead".'
689 ' [readability/multiline_string] [5]')
691 file_path = 'mydir/foo.cpp'
693 error_collector = ErrorCollector(self.assert_)
694 cpp_style.process_file_data(file_path, 'cpp',
695 ['const char* str = "This is a\\',
696 ' multiline string.";'],
700 error_collector.result_list().count(multiline_string_error_message))
702 # Test non-explicit single-argument constructors
703 def test_explicit_single_argument_constructors(self):
704 # missing explicit is bad
705 self.assert_multi_line_lint(
709 'Single-argument constructors should be marked explicit.'
710 ' [runtime/explicit] [5]')
711 # missing explicit is bad, even with whitespace
712 self.assert_multi_line_lint(
716 ['Extra space before ( in function call [whitespace/parens] [4]',
717 'Single-argument constructors should be marked explicit.'
718 ' [runtime/explicit] [5]'])
719 # missing explicit, with distracting comment, is still bad
720 self.assert_multi_line_lint(
722 Foo(int f); // simpler than Foo(blargh, blarg)
724 'Single-argument constructors should be marked explicit.'
725 ' [runtime/explicit] [5]')
726 # missing explicit, with qualified classname
727 self.assert_multi_line_lint(
728 '''class Qualifier::AnotherOne::Foo {
731 'Single-argument constructors should be marked explicit.'
732 ' [runtime/explicit] [5]')
733 # structs are caught as well.
734 self.assert_multi_line_lint(
738 'Single-argument constructors should be marked explicit.'
739 ' [runtime/explicit] [5]')
740 # Templatized classes are caught as well.
741 self.assert_multi_line_lint(
742 '''template<typename T> class Foo {
745 'Single-argument constructors should be marked explicit.'
746 ' [runtime/explicit] [5]')
747 # proper style is okay
748 self.assert_multi_line_lint(
753 # two argument constructor is okay
754 self.assert_multi_line_lint(
759 # two argument constructor, across two lines, is okay
760 self.assert_multi_line_lint(
766 # non-constructor (but similar name), is okay
767 self.assert_multi_line_lint(
772 # constructor with void argument is okay
773 self.assert_multi_line_lint(
778 # single argument method is okay
779 self.assert_multi_line_lint(
784 # comments should be ignored
785 self.assert_multi_line_lint(
790 # single argument function following class definition is okay
791 # (okay, it's not actually valid, but we don't want a false positive)
792 self.assert_multi_line_lint(
798 # single argument function is okay
799 self.assert_multi_line_lint(
800 '''static Foo(int f);''',
802 # single argument copy constructor is okay.
803 self.assert_multi_line_lint(
808 self.assert_multi_line_lint(
814 def test_slash_star_comment_on_single_line(self):
815 self.assert_multi_line_lint(
816 '''/* static */ Foo(int f);''',
818 self.assert_multi_line_lint(
819 '''/*/ static */ Foo(int f);''',
821 self.assert_multi_line_lint(
822 '''/*/ static Foo(int f);''',
823 'Could not find end of multi-line comment'
824 ' [readability/multiline_comment] [5]')
825 self.assert_multi_line_lint(
826 ''' /*/ static Foo(int f);''',
827 'Could not find end of multi-line comment'
828 ' [readability/multiline_comment] [5]')
829 self.assert_multi_line_lint(
830 ''' /**/ static Foo(int f);''',
833 # Test suspicious usage of "if" like this:
836 # } if (a == c) { // Should be "else if".
837 # DoSomething(); // This gets called twice if a == b && a == c.
839 def test_suspicious_usage_of_if(self):
845 'Did you mean "else if"? If not, start a new line for "if".'
846 ' [readability/braces] [4]')
848 # Test suspicious usage of memset. Specifically, a 0
849 # as the final argument is almost certainly an error.
850 def test_suspicious_usage_of_memset(self):
851 # Normal use is okay.
853 ' memset(buf, 0, sizeof(buf))',
856 # A 0 as the final argument is almost certainly an error.
858 ' memset(buf, sizeof(buf), 0)',
859 'Did you mean "memset(buf, 0, sizeof(buf))"?'
860 ' [runtime/memset] [4]')
862 ' memset(buf, xsize * ysize, 0)',
863 'Did you mean "memset(buf, 0, xsize * ysize)"?'
864 ' [runtime/memset] [4]')
866 # There is legitimate test code that uses this form.
867 # This is okay since the second argument is a literal.
869 " memset(buf, 'y', 0)",
872 ' memset(buf, 4, 0)',
875 ' memset(buf, -1, 0)',
878 ' memset(buf, 0xF1, 0)',
881 ' memset(buf, 0xcd, 0)',
884 def test_check_posix_threading(self):
885 self.assert_lint('sctime_r()', '')
886 self.assert_lint('strtok_r()', '')
887 self.assert_lint(' strtok_r(foo, ba, r)', '')
888 self.assert_lint('brand()', '')
889 self.assert_lint('_rand()', '')
890 self.assert_lint('.rand()', '')
891 self.assert_lint('>rand()', '')
892 self.assert_lint('rand()',
893 'Consider using rand_r(...) instead of rand(...)'
894 ' for improved thread safety.'
895 ' [runtime/threadsafe_fn] [2]')
896 self.assert_lint('strtok()',
897 'Consider using strtok_r(...) '
898 'instead of strtok(...)'
899 ' for improved thread safety.'
900 ' [runtime/threadsafe_fn] [2]')
902 # Test potential format string bugs like printf(foo).
903 def test_format_strings(self):
904 self.assert_lint('printf("foo")', '')
905 self.assert_lint('printf("foo: %s", foo)', '')
906 self.assert_lint('DocidForPrintf(docid)', '') # Should not trigger.
909 'Potential format string bug. Do printf("%s", foo) instead.'
910 ' [runtime/printf] [4]')
912 'printf(foo.c_str())',
913 'Potential format string bug. '
914 'Do printf("%s", foo.c_str()) instead.'
915 ' [runtime/printf] [4]')
917 'printf(foo->c_str())',
918 'Potential format string bug. '
919 'Do printf("%s", foo->c_str()) instead.'
920 ' [runtime/printf] [4]')
923 'Potential format string bug. Do StringPrintf("%s", foo) instead.'
925 ' [runtime/printf] [4]')
927 # Variable-length arrays are not permitted.
928 def test_variable_length_array_detection(self):
929 errmsg = ('Do not use variable-length arrays. Use an appropriately named '
930 "('k' followed by CamelCase) compile-time constant for the size."
931 ' [runtime/arrays] [1]')
933 self.assert_lint('int a[any_old_variable];', errmsg)
934 self.assert_lint('int doublesize[some_var * 2];', errmsg)
935 self.assert_lint('int a[afunction()];', errmsg)
936 self.assert_lint('int a[function(kMaxFooBars)];', errmsg)
937 self.assert_lint('bool a_list[items_->size()];', errmsg)
938 self.assert_lint('namespace::Type buffer[len+1];', errmsg)
940 self.assert_lint('int a[64];', '')
941 self.assert_lint('int a[0xFF];', '')
942 self.assert_lint('int first[256], second[256];', '')
943 self.assert_lint('int array_name[kCompileTimeConstant];', '')
944 self.assert_lint('char buf[somenamespace::kBufSize];', '')
945 self.assert_lint('int array_name[ALL_CAPS];', '')
946 self.assert_lint('AClass array1[foo::bar::ALL_CAPS];', '')
947 self.assert_lint('int a[kMaxStrLen + 1];', '')
948 self.assert_lint('int a[sizeof(foo)];', '')
949 self.assert_lint('int a[sizeof(*foo)];', '')
950 self.assert_lint('int a[sizeof foo];', '')
951 self.assert_lint('int a[sizeof(struct Foo)];', '')
952 self.assert_lint('int a[128 - sizeof(const bar)];', '')
953 self.assert_lint('int a[(sizeof(foo) * 4)];', '')
954 self.assert_lint('int a[(arraysize(fixed_size_array)/2) << 1];', 'Missing spaces around / [whitespace/operators] [3]')
955 self.assert_lint('delete a[some_var];', '')
956 self.assert_lint('return a[some_var];', '')
959 def test_braces(self):
960 # Braces shouldn't be followed by a ; unless they're defining a struct
961 # or initializing an array
962 self.assert_lint('int a[3] = { 1, 2, 3 };', '')
967 # For single line, unmatched '}' with a ';' is ignored (not enough context)
968 self.assert_multi_line_lint(
973 self.assert_multi_line_lint(
974 '''int a[2][3] = { { 1, 2 },
977 self.assert_multi_line_lint(
983 # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements
984 def test_check_check(self):
985 self.assert_lint('CHECK(x == 42)',
986 'Consider using CHECK_EQ instead of CHECK(a == b)'
987 ' [readability/check] [2]')
988 self.assert_lint('CHECK(x != 42)',
989 'Consider using CHECK_NE instead of CHECK(a != b)'
990 ' [readability/check] [2]')
991 self.assert_lint('CHECK(x >= 42)',
992 'Consider using CHECK_GE instead of CHECK(a >= b)'
993 ' [readability/check] [2]')
994 self.assert_lint('CHECK(x > 42)',
995 'Consider using CHECK_GT instead of CHECK(a > b)'
996 ' [readability/check] [2]')
997 self.assert_lint('CHECK(x <= 42)',
998 'Consider using CHECK_LE instead of CHECK(a <= b)'
999 ' [readability/check] [2]')
1000 self.assert_lint('CHECK(x < 42)',
1001 'Consider using CHECK_LT instead of CHECK(a < b)'
1002 ' [readability/check] [2]')
1004 self.assert_lint('DCHECK(x == 42)',
1005 'Consider using DCHECK_EQ instead of DCHECK(a == b)'
1006 ' [readability/check] [2]')
1007 self.assert_lint('DCHECK(x != 42)',
1008 'Consider using DCHECK_NE instead of DCHECK(a != b)'
1009 ' [readability/check] [2]')
1010 self.assert_lint('DCHECK(x >= 42)',
1011 'Consider using DCHECK_GE instead of DCHECK(a >= b)'
1012 ' [readability/check] [2]')
1013 self.assert_lint('DCHECK(x > 42)',
1014 'Consider using DCHECK_GT instead of DCHECK(a > b)'
1015 ' [readability/check] [2]')
1016 self.assert_lint('DCHECK(x <= 42)',
1017 'Consider using DCHECK_LE instead of DCHECK(a <= b)'
1018 ' [readability/check] [2]')
1019 self.assert_lint('DCHECK(x < 42)',
1020 'Consider using DCHECK_LT instead of DCHECK(a < b)'
1021 ' [readability/check] [2]')
1024 'EXPECT_TRUE("42" == x)',
1025 'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)'
1026 ' [readability/check] [2]')
1028 'EXPECT_TRUE("42" != x)',
1029 'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)'
1030 ' [readability/check] [2]')
1032 'EXPECT_TRUE(+42 >= x)',
1033 'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)'
1034 ' [readability/check] [2]')
1036 'EXPECT_TRUE_M(-42 > x)',
1037 'Consider using EXPECT_GT_M instead of EXPECT_TRUE_M(a > b)'
1038 ' [readability/check] [2]')
1040 'EXPECT_TRUE_M(42U <= x)',
1041 'Consider using EXPECT_LE_M instead of EXPECT_TRUE_M(a <= b)'
1042 ' [readability/check] [2]')
1044 'EXPECT_TRUE_M(42L < x)',
1045 'Consider using EXPECT_LT_M instead of EXPECT_TRUE_M(a < b)'
1046 ' [readability/check] [2]')
1049 'EXPECT_FALSE(x == 42)',
1050 'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)'
1051 ' [readability/check] [2]')
1053 'EXPECT_FALSE(x != 42)',
1054 'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)'
1055 ' [readability/check] [2]')
1057 'EXPECT_FALSE(x >= 42)',
1058 'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)'
1059 ' [readability/check] [2]')
1061 'ASSERT_FALSE(x > 42)',
1062 'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)'
1063 ' [readability/check] [2]')
1065 'ASSERT_FALSE(x <= 42)',
1066 'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)'
1067 ' [readability/check] [2]')
1069 'ASSERT_FALSE_M(x < 42)',
1070 'Consider using ASSERT_GE_M instead of ASSERT_FALSE_M(a < b)'
1071 ' [readability/check] [2]')
1073 self.assert_lint('CHECK(some_iterator == obj.end())', '')
1074 self.assert_lint('EXPECT_TRUE(some_iterator == obj.end())', '')
1075 self.assert_lint('EXPECT_FALSE(some_iterator == obj.end())', '')
1077 self.assert_lint('CHECK(CreateTestFile(dir, (1 << 20)));', '')
1078 self.assert_lint('CHECK(CreateTestFile(dir, (1 >> 20)));', '')
1080 self.assert_lint('CHECK(x<42)',
1081 ['Missing spaces around <'
1082 ' [whitespace/operators] [3]',
1083 'Consider using CHECK_LT instead of CHECK(a < b)'
1084 ' [readability/check] [2]'])
1085 self.assert_lint('CHECK(x>42)',
1086 'Consider using CHECK_GT instead of CHECK(a > b)'
1087 ' [readability/check] [2]')
1090 ' EXPECT_TRUE(42 < x) // Random comment.',
1091 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1092 ' [readability/check] [2]')
1094 'EXPECT_TRUE( 42 < x )',
1095 ['Extra space after ( in function call'
1096 ' [whitespace/parens] [4]',
1097 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1098 ' [readability/check] [2]'])
1100 'CHECK("foo" == "foo")',
1101 'Consider using CHECK_EQ instead of CHECK(a == b)'
1102 ' [readability/check] [2]')
1104 self.assert_lint('CHECK_EQ("foo", "foo")', '')
1106 def test_brace_at_begin_of_line(self):
1107 self.assert_lint('{',
1108 'This { should be at the end of the previous line'
1109 ' [whitespace/braces] [4]')
1110 self.assert_multi_line_lint(
1115 self.assert_multi_line_lint(
1118 self.assert_multi_line_lint(
1120 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
1121 self.assert_multi_line_lint(
1122 'int foo() const {',
1123 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
1124 self.assert_multi_line_lint(
1129 self.assert_multi_line_lint(
1132 ' && condition3) {\n'
1136 def test_mismatching_spaces_in_parens(self):
1137 self.assert_lint('if (foo ) {', 'Mismatching spaces inside () in if'
1138 ' [whitespace/parens] [5]')
1139 self.assert_lint('switch ( foo) {', 'Mismatching spaces inside () in switch'
1140 ' [whitespace/parens] [5]')
1141 self.assert_lint('for (foo; ba; bar ) {', 'Mismatching spaces inside () in for'
1142 ' [whitespace/parens] [5]')
1143 self.assert_lint('for (; foo; bar) {', '')
1144 self.assert_lint('for ( ; foo; bar) {', '')
1145 self.assert_lint('for ( ; foo; bar ) {', '')
1146 self.assert_lint('for (foo; bar; ) {', '')
1147 self.assert_lint('foreach (foo, foos ) {', 'Mismatching spaces inside () in foreach'
1148 ' [whitespace/parens] [5]')
1149 self.assert_lint('foreach ( foo, foos) {', 'Mismatching spaces inside () in foreach'
1150 ' [whitespace/parens] [5]')
1151 self.assert_lint('while ( foo ) {', 'Should have zero or one spaces inside'
1152 ' ( and ) in while [whitespace/parens] [5]')
1154 def test_spacing_for_fncall(self):
1155 self.assert_lint('if (foo) {', '')
1156 self.assert_lint('for (foo;bar;baz) {', '')
1157 self.assert_lint('foreach (foo, foos) {', '')
1158 self.assert_lint('while (foo) {', '')
1159 self.assert_lint('switch (foo) {', '')
1160 self.assert_lint('new (RenderArena()) RenderInline(document())', '')
1161 self.assert_lint('foo( bar)', 'Extra space after ( in function call'
1162 ' [whitespace/parens] [4]')
1163 self.assert_lint('foobar( \\', '')
1164 self.assert_lint('foobar( \\', '')
1165 self.assert_lint('( a + b)', 'Extra space after ('
1166 ' [whitespace/parens] [2]')
1167 self.assert_lint('((a+b))', '')
1168 self.assert_lint('foo (foo)', 'Extra space before ( in function call'
1169 ' [whitespace/parens] [4]')
1170 self.assert_lint('typedef foo (*foo)(foo)', '')
1171 self.assert_lint('typedef foo (*foo12bar_)(foo)', '')
1172 self.assert_lint('typedef foo (Foo::*bar)(foo)', '')
1173 self.assert_lint('foo (Foo::*bar)(',
1174 'Extra space before ( in function call'
1175 ' [whitespace/parens] [4]')
1176 self.assert_lint('typedef foo (Foo::*bar)(', '')
1177 self.assert_lint('(foo)(bar)', '')
1178 self.assert_lint('Foo (*foo)(bar)', '')
1179 self.assert_lint('Foo (*foo)(Bar bar,', '')
1180 self.assert_lint('char (*p)[sizeof(foo)] = &foo', '')
1181 self.assert_lint('char (&ref)[sizeof(foo)] = &foo', '')
1182 self.assert_lint('const char32 (*table[])[6];', '')
1184 def test_spacing_before_braces(self):
1185 self.assert_lint('if (foo){', 'Missing space before {'
1186 ' [whitespace/braces] [5]')
1187 self.assert_lint('for{', 'Missing space before {'
1188 ' [whitespace/braces] [5]')
1189 self.assert_lint('for {', '')
1190 self.assert_lint('EXPECT_DEBUG_DEATH({', '')
1192 def test_spacing_around_else(self):
1193 self.assert_lint('}else {', 'Missing space before else'
1194 ' [whitespace/braces] [5]')
1195 self.assert_lint('} else{', 'Missing space before {'
1196 ' [whitespace/braces] [5]')
1197 self.assert_lint('} else {', '')
1198 self.assert_lint('} else if', '')
1200 def test_spacing_for_binary_ops(self):
1201 self.assert_lint('if (foo<=bar) {', 'Missing spaces around <='
1202 ' [whitespace/operators] [3]')
1203 self.assert_lint('if (foo<bar) {', 'Missing spaces around <'
1204 ' [whitespace/operators] [3]')
1205 self.assert_lint('if (foo<bar->baz) {', 'Missing spaces around <'
1206 ' [whitespace/operators] [3]')
1207 self.assert_lint('if (foo<bar->bar) {', 'Missing spaces around <'
1208 ' [whitespace/operators] [3]')
1209 self.assert_lint('typedef hash_map<Foo, Bar', 'Missing spaces around <'
1210 ' [whitespace/operators] [3]')
1211 self.assert_lint('typedef hash_map<FoooooType, BaaaaarType,', '')
1212 self.assert_lint('a<Foo> t+=b;', 'Missing spaces around +='
1213 ' [whitespace/operators] [3]')
1214 self.assert_lint('a<Foo> t-=b;', 'Missing spaces around -='
1215 ' [whitespace/operators] [3]')
1216 self.assert_lint('a<Foo*> t*=b;', 'Missing spaces around *='
1217 ' [whitespace/operators] [3]')
1218 self.assert_lint('a<Foo*> t/=b;', 'Missing spaces around /='
1219 ' [whitespace/operators] [3]')
1220 self.assert_lint('a<Foo*> t|=b;', 'Missing spaces around |='
1221 ' [whitespace/operators] [3]')
1222 self.assert_lint('a<Foo*> t&=b;', 'Missing spaces around &='
1223 ' [whitespace/operators] [3]')
1224 self.assert_lint('a<Foo*> t<<=b;', 'Missing spaces around <<='
1225 ' [whitespace/operators] [3]')
1226 self.assert_lint('a<Foo*> t>>=b;', 'Missing spaces around >>='
1227 ' [whitespace/operators] [3]')
1228 self.assert_lint('a<Foo*> t>>=&b|c;', 'Missing spaces around >>='
1229 ' [whitespace/operators] [3]')
1230 self.assert_lint('a<Foo*> t<<=*b/c;', 'Missing spaces around <<='
1231 ' [whitespace/operators] [3]')
1232 self.assert_lint('a<Foo> t -= b;', '')
1233 self.assert_lint('a<Foo> t += b;', '')
1234 self.assert_lint('a<Foo*> t *= b;', '')
1235 self.assert_lint('a<Foo*> t /= b;', '')
1236 self.assert_lint('a<Foo*> t |= b;', '')
1237 self.assert_lint('a<Foo*> t &= b;', '')
1238 self.assert_lint('a<Foo*> t <<= b;', '')
1239 self.assert_lint('a<Foo*> t >>= b;', '')
1240 self.assert_lint('a<Foo*> t >>= &b|c;', 'Missing spaces around |'
1241 ' [whitespace/operators] [3]')
1242 self.assert_lint('a<Foo*> t <<= *b/c;', 'Missing spaces around /'
1243 ' [whitespace/operators] [3]')
1244 self.assert_lint('a<Foo*> t <<= b/c; //Test', ['At least two spaces'
1245 ' is best between code and comments [whitespace/'
1246 'comments] [2]', 'Should have a space between // '
1247 'and comment [whitespace/comments] [4]', 'Missing'
1248 ' spaces around / [whitespace/operators] [3]'])
1249 self.assert_lint('a<Foo*> t <<= b||c; //Test', ['Should have a space'
1250 ' between // and comment [whitespace/comments] [4]',
1251 'Missing spaces around || [whitespace/operators] [3]'])
1252 self.assert_lint('a<Foo*> t <<= b&&c; // Test', 'Missing spaces around'
1253 ' && [whitespace/operators] [3]')
1254 self.assert_lint('a<Foo*> t <<= b&&&c; // Test', 'Missing spaces around'
1255 ' && [whitespace/operators] [3]')
1256 self.assert_lint('a<Foo*> t <<= b&&*c; // Test', 'Missing spaces around'
1257 ' && [whitespace/operators] [3]')
1258 self.assert_lint('a<Foo*> t <<= b && *c; // Test', '')
1259 self.assert_lint('a<Foo*> t <<= b && &c; // Test', '')
1260 self.assert_lint('a<Foo*> t <<= b || &c; /*Test', 'Complex multi-line '
1261 '/*...*/-style comment found. Lint may give bogus '
1262 'warnings. Consider replacing these with //-style'
1263 ' comments, with #if 0...#endif, or with more clearly'
1264 ' structured multi-line comments. [readability/multiline_comment] [5]')
1265 self.assert_lint('a<Foo&> t <<= &b | &c;', '')
1266 self.assert_lint('a<Foo*> t <<= &b & &c; // Test', '')
1267 self.assert_lint('a<Foo*> t <<= *b / &c; // Test', '')
1268 self.assert_lint('if (a=b == 1)', 'Missing spaces around = [whitespace/operators] [4]')
1269 self.assert_lint('a = 1<<20', 'Missing spaces around << [whitespace/operators] [3]')
1270 self.assert_lint('if (a = b == 1)', '')
1271 self.assert_lint('a = 1 << 20', '')
1272 self.assert_multi_line_lint('#include "config.h"\n#include <sys/io.h>\n',
1275 def test_spacing_before_last_semicolon(self):
1276 self.assert_lint('call_function() ;',
1277 'Extra space before last semicolon. If this should be an '
1278 'empty statement, use { } instead.'
1279 ' [whitespace/semicolon] [5]')
1280 self.assert_lint('while (true) ;',
1281 'Extra space before last semicolon. If this should be an '
1282 'empty statement, use { } instead.'
1283 ' [whitespace/semicolon] [5]')
1284 self.assert_lint('default:;',
1285 'Semicolon defining empty statement. Use { } instead.'
1286 ' [whitespace/semicolon] [5]')
1287 self.assert_lint(' ;',
1288 'Line contains only semicolon. If this should be an empty '
1289 'statement, use { } instead.'
1290 ' [whitespace/semicolon] [5]')
1291 self.assert_lint('for (int i = 0; ;', '')
1293 # Static or global STL strings.
1294 def test_static_or_global_stlstrings(self):
1295 self.assert_lint('string foo;',
1296 'For a static/global string constant, use a C style '
1297 'string instead: "char foo[]".'
1298 ' [runtime/string] [4]')
1299 self.assert_lint('string kFoo = "hello"; // English',
1300 'For a static/global string constant, use a C style '
1301 'string instead: "char kFoo[]".'
1302 ' [runtime/string] [4]')
1303 self.assert_lint('static string foo;',
1304 'For a static/global string constant, use a C style '
1305 'string instead: "static char foo[]".'
1306 ' [runtime/string] [4]')
1307 self.assert_lint('static const string foo;',
1308 'For a static/global string constant, use a C style '
1309 'string instead: "static const char foo[]".'
1310 ' [runtime/string] [4]')
1311 self.assert_lint('string Foo::bar;',
1312 'For a static/global string constant, use a C style '
1313 'string instead: "char Foo::bar[]".'
1314 ' [runtime/string] [4]')
1316 self.assert_lint('string foo("foobar");',
1317 'For a static/global string constant, use a C style '
1318 'string instead: "char foo[]".'
1319 ' [runtime/string] [4]')
1320 # Should not catch local or member variables.
1321 self.assert_lint(' string foo', '')
1322 # Should not catch functions.
1323 self.assert_lint('string EmptyString() { return ""; }', '')
1324 self.assert_lint('string EmptyString () { return ""; }', '')
1325 self.assert_lint('string VeryLongNameFunctionSometimesEndsWith(\n'
1326 ' VeryLongNameType very_long_name_variable) {}', '')
1327 self.assert_lint('template<>\n'
1328 'string FunctionTemplateSpecialization<SomeType>(\n'
1329 ' int x) { return ""; }', '')
1330 self.assert_lint('template<>\n'
1331 'string FunctionTemplateSpecialization<vector<A::B>* >(\n'
1332 ' int x) { return ""; }', '')
1334 # should not catch methods of template classes.
1335 self.assert_lint('string Class<Type>::Method() const\n'
1339 self.assert_lint('string Class<Type>::Method(\n'
1345 def test_no_spaces_in_function_calls(self):
1346 self.assert_lint('TellStory(1, 3);',
1348 self.assert_lint('TellStory(1, 3 );',
1349 'Extra space before )'
1350 ' [whitespace/parens] [2]')
1351 self.assert_lint('TellStory(1 /* wolf */, 3 /* pigs */);',
1353 self.assert_multi_line_lint('#endif\n );',
1356 def test_two_spaces_between_code_and_comments(self):
1357 self.assert_lint('} // namespace foo',
1358 'At least two spaces is best between code and comments'
1359 ' [whitespace/comments] [2]')
1360 self.assert_lint('}// namespace foo',
1361 'At least two spaces is best between code and comments'
1362 ' [whitespace/comments] [2]')
1363 self.assert_lint('printf("foo"); // Outside quotes.',
1364 'At least two spaces is best between code and comments'
1365 ' [whitespace/comments] [2]')
1366 self.assert_lint('int i = 0; // Having two spaces is fine.', '')
1367 self.assert_lint('int i = 0; // Having three spaces is OK.', '')
1368 self.assert_lint('// Top level comment', '')
1369 self.assert_lint(' // Line starts with four spaces.', '')
1370 self.assert_lint('foo();\n'
1371 '{ // A scope is opening.', '')
1372 self.assert_lint(' foo();\n'
1373 ' { // An indented scope is opening.', '')
1374 self.assert_lint('if (foo) { // not a pure scope; comment is too close!',
1375 'At least two spaces is best between code and comments'
1376 ' [whitespace/comments] [2]')
1377 self.assert_lint('printf("// In quotes.")', '')
1378 self.assert_lint('printf("\\"%s // In quotes.")', '')
1379 self.assert_lint('printf("%s", "// In quotes.")', '')
1381 def test_space_after_comment_marker(self):
1382 self.assert_lint('//', '')
1383 self.assert_lint('//x', 'Should have a space between // and comment'
1384 ' [whitespace/comments] [4]')
1385 self.assert_lint('// x', '')
1386 self.assert_lint('//----', '')
1387 self.assert_lint('//====', '')
1388 self.assert_lint('//////', '')
1389 self.assert_lint('////// x', '')
1390 self.assert_lint('/// x', '')
1391 self.assert_lint('////x', 'Should have a space between // and comment'
1392 ' [whitespace/comments] [4]')
1394 def test_newline_at_eof(self):
1395 def do_test(self, data, is_missing_eof):
1396 error_collector = ErrorCollector(self.assert_)
1397 cpp_style.process_file_data('foo.cpp', 'cpp', data.split('\n'),
1399 # The warning appears only once.
1401 int(is_missing_eof),
1402 error_collector.results().count(
1403 'Could not find a newline character at the end of the file.'
1404 ' [whitespace/ending_newline] [5]'))
1406 do_test(self, '// Newline\n// at EOF\n', False)
1407 do_test(self, '// No newline\n// at EOF', True)
1409 def test_invalid_utf8(self):
1410 def do_test(self, raw_bytes, has_invalid_utf8):
1411 error_collector = ErrorCollector(self.assert_)
1412 cpp_style.process_file_data(
1414 unicode(raw_bytes, 'utf8', 'replace').split('\n'),
1416 # The warning appears only once.
1418 int(has_invalid_utf8),
1419 error_collector.results().count(
1420 'Line contains invalid UTF-8'
1421 ' (or Unicode replacement character).'
1422 ' [readability/utf8] [5]'))
1424 do_test(self, 'Hello world\n', False)
1425 do_test(self, '\xe9\x8e\xbd\n', False)
1426 do_test(self, '\xe9x\x8e\xbd\n', True)
1427 # This is the encoding of the replacement character itself (which
1428 # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')).
1429 do_test(self, '\xef\xbf\xbd\n', True)
1431 def test_is_blank_line(self):
1432 self.assert_(cpp_style.is_blank_line(''))
1433 self.assert_(cpp_style.is_blank_line(' '))
1434 self.assert_(cpp_style.is_blank_line(' \t\r\n'))
1435 self.assert_(not cpp_style.is_blank_line('int a;'))
1436 self.assert_(not cpp_style.is_blank_line('{'))
1438 def test_blank_lines_check(self):
1439 self.assert_blank_lines_check(['{\n', '\n', '\n', '}\n'], 1, 1)
1440 self.assert_blank_lines_check([' if (foo) {\n', '\n', ' }\n'], 1, 1)
1441 self.assert_blank_lines_check(
1442 ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0)
1443 self.assert_blank_lines_check(['\n', 'run("{");\n', '\n'], 0, 0)
1444 self.assert_blank_lines_check(['\n', ' if (foo) { return 0; }\n', '\n'], 0, 0)
1446 def test_allow_blank_line_before_closing_namespace(self):
1447 error_collector = ErrorCollector(self.assert_)
1448 cpp_style.process_file_data('foo.cpp', 'cpp',
1449 ['namespace {', '', '} // namespace'],
1451 self.assertEquals(0, error_collector.results().count(
1452 'Blank line at the end of a code block. Is this needed?'
1453 ' [whitespace/blank_line] [3]'))
1455 def test_allow_blank_line_before_if_else_chain(self):
1456 error_collector = ErrorCollector(self.assert_)
1457 cpp_style.process_file_data('foo.cpp', 'cpp',
1460 '} else if (piyo) {',
1462 '} else if (piyopiyo) {',
1463 ' hoge = true;', # No warning
1465 '', # Warning on this line
1468 self.assertEquals(1, error_collector.results().count(
1469 'Blank line at the end of a code block. Is this needed?'
1470 ' [whitespace/blank_line] [3]'))
1472 def test_else_on_same_line_as_closing_braces(self):
1473 error_collector = ErrorCollector(self.assert_)
1474 cpp_style.process_file_data('foo.cpp', 'cpp',
1478 ' else {' # Warning on this line
1482 self.assertEquals(1, error_collector.results().count(
1483 'An else should appear on the same line as the preceding }'
1484 ' [whitespace/newline] [4]'))
1486 def test_else_clause_not_on_same_line_as_else(self):
1487 self.assert_lint(' else DoSomethingElse();',
1488 'Else clause should never be on same line as else '
1489 '(use 2 lines) [whitespace/newline] [4]')
1490 self.assert_lint(' else ifDoSomethingElse();',
1491 'Else clause should never be on same line as else '
1492 '(use 2 lines) [whitespace/newline] [4]')
1493 self.assert_lint(' else if (blah) {', '')
1494 self.assert_lint(' variable_ends_in_else = true;', '')
1496 def test_comma(self):
1497 self.assert_lint('a = f(1,2);',
1498 'Missing space after , [whitespace/comma] [3]')
1499 self.assert_lint('int tmp=a,a=b,b=tmp;',
1500 ['Missing spaces around = [whitespace/operators] [4]',
1501 'Missing space after , [whitespace/comma] [3]'])
1502 self.assert_lint('f(a, /* name */ b);', '')
1503 self.assert_lint('f(a, /* name */b);', '')
1505 def test_pointer_reference_marker_location(self):
1506 self.assert_lint('int* b;', '', 'foo.cpp')
1507 self.assert_lint('int *b;',
1508 'Declaration has space between type name and * in int *b [whitespace/declaration] [3]',
1510 self.assert_lint('return *b;', '', 'foo.cpp')
1511 self.assert_lint('int *b;', '', 'foo.c')
1512 self.assert_lint('int* b;',
1513 'Declaration has space between * and variable name in int* b [whitespace/declaration] [3]',
1515 self.assert_lint('int& b;', '', 'foo.cpp')
1516 self.assert_lint('int &b;',
1517 'Declaration has space between type name and & in int &b [whitespace/declaration] [3]',
1519 self.assert_lint('return &b;', '', 'foo.cpp')
1521 def test_indent(self):
1522 self.assert_lint('static int noindent;', '')
1523 self.assert_lint(' int four_space_indent;', '')
1524 self.assert_lint(' int one_space_indent;',
1525 'Weird number of spaces at line-start. '
1526 'Are you using a 4-space indent? [whitespace/indent] [3]')
1527 self.assert_lint(' int three_space_indent;',
1528 'Weird number of spaces at line-start. '
1529 'Are you using a 4-space indent? [whitespace/indent] [3]')
1530 self.assert_lint(' char* one_space_indent = "public:";',
1531 'Weird number of spaces at line-start. '
1532 'Are you using a 4-space indent? [whitespace/indent] [3]')
1533 self.assert_lint(' public:', '')
1534 self.assert_lint(' public:', '')
1535 self.assert_lint(' public:', '')
1537 def test_label(self):
1538 self.assert_lint('public:',
1539 'Labels should always be indented at least one space. '
1540 'If this is a member-initializer list in a constructor, '
1541 'the colon should be on the line after the definition '
1542 'header. [whitespace/labels] [4]')
1543 self.assert_lint(' public:', '')
1544 self.assert_lint(' public:', '')
1545 self.assert_lint(' public:', '')
1546 self.assert_lint(' public:', '')
1547 self.assert_lint(' public:', '')
1549 def test_not_alabel(self):
1550 self.assert_lint('MyVeryLongNamespace::MyVeryLongClassName::', '')
1553 self.assert_lint('\tint a;',
1554 'Tab found; better to use spaces [whitespace/tab] [1]')
1555 self.assert_lint('int a = 5;\t\t// set a to 5',
1556 'Tab found; better to use spaces [whitespace/tab] [1]')
1558 def test_parse_arguments(self):
1559 old_usage = cpp_style._USAGE
1560 old_error_categories = cpp_style._ERROR_CATEGORIES
1561 old_output_format = cpp_style._cpp_style_state.output_format
1562 old_verbose_level = cpp_style._cpp_style_state.verbose_level
1563 old_filters = cpp_style._cpp_style_state.filters
1565 # Don't print usage during the tests, or filter categories
1566 cpp_style._USAGE = ''
1567 cpp_style._ERROR_CATEGORIES = ''
1569 self.assertRaises(SystemExit, cpp_style.parse_arguments, ['--badopt'])
1570 self.assertRaises(SystemExit, cpp_style.parse_arguments, ['--help'])
1571 self.assertRaises(SystemExit, cpp_style.parse_arguments, ['--filter='])
1572 # This is illegal because all filters must start with + or -
1573 self.assertRaises(ValueError, cpp_style.parse_arguments, ['--filter=foo'])
1574 self.assertRaises(ValueError, cpp_style.parse_arguments,
1575 ['--filter=+a,b,-c'])
1577 self.assertEquals((['foo.cpp'], {}), cpp_style.parse_arguments(['foo.cpp']))
1578 self.assertEquals(old_output_format, cpp_style._cpp_style_state.output_format)
1579 self.assertEquals(old_verbose_level, cpp_style._cpp_style_state.verbose_level)
1581 self.assertEquals(([], {}), cpp_style.parse_arguments([]))
1582 self.assertEquals(([], {}), cpp_style.parse_arguments(['--v=0']))
1584 self.assertEquals((['foo.cpp'], {}),
1585 cpp_style.parse_arguments(['--v=1', 'foo.cpp']))
1586 self.assertEquals(1, cpp_style._cpp_style_state.verbose_level)
1587 self.assertEquals((['foo.h'], {}),
1588 cpp_style.parse_arguments(['--v=3', 'foo.h']))
1589 self.assertEquals(3, cpp_style._cpp_style_state.verbose_level)
1590 self.assertEquals((['foo.cpp'], {}),
1591 cpp_style.parse_arguments(['--verbose=5', 'foo.cpp']))
1592 self.assertEquals(5, cpp_style._cpp_style_state.verbose_level)
1593 self.assertRaises(ValueError,
1594 cpp_style.parse_arguments, ['--v=f', 'foo.cpp'])
1596 self.assertEquals((['foo.cpp'], {}),
1597 cpp_style.parse_arguments(['--output=emacs', 'foo.cpp']))
1598 self.assertEquals('emacs', cpp_style._cpp_style_state.output_format)
1599 self.assertEquals((['foo.h'], {}),
1600 cpp_style.parse_arguments(['--output=vs7', 'foo.h']))
1601 self.assertEquals('vs7', cpp_style._cpp_style_state.output_format)
1602 self.assertRaises(SystemExit,
1603 cpp_style.parse_arguments, ['--output=blah', 'foo.cpp'])
1605 filt = '-,+whitespace,-whitespace/indent'
1606 self.assertEquals((['foo.h'], {}),
1607 cpp_style.parse_arguments(['--filter='+filt, 'foo.h']))
1608 self.assertEquals(['-', '+whitespace', '-whitespace/indent'],
1609 cpp_style._cpp_style_state.filters)
1611 self.assertEquals((['foo.cpp', 'foo.h'], {}),
1612 cpp_style.parse_arguments(['foo.cpp', 'foo.h']))
1614 self.assertEquals((['foo.cpp'], {'--foo': ''}),
1615 cpp_style.parse_arguments(['--foo', 'foo.cpp'], ['foo']))
1616 self.assertEquals((['foo.cpp'], {'--foo': 'bar'}),
1617 cpp_style.parse_arguments(['--foo=bar', 'foo.cpp'], ['foo=']))
1618 self.assertEquals((['foo.cpp'], {}),
1619 cpp_style.parse_arguments(['foo.cpp'], ['foo=']))
1620 self.assertRaises(SystemExit,
1621 cpp_style.parse_arguments,
1622 ['--footypo=bar', 'foo.cpp'], ['foo='])
1624 cpp_style._USAGE = old_usage
1625 cpp_style._ERROR_CATEGORIES = old_error_categories
1626 cpp_style._cpp_style_state.output_format = old_output_format
1627 cpp_style._cpp_style_state.verbose_level = old_verbose_level
1628 cpp_style._cpp_style_state.filters = old_filters
1630 def test_filter(self):
1631 old_filters = cpp_style._cpp_style_state.filters
1633 cpp_style._cpp_style_state.set_filters('-,+whitespace,-whitespace/indent')
1636 'Line ends in whitespace. Consider deleting these extra spaces.'
1637 ' [whitespace/end_of_line] [4]')
1638 self.assert_lint('int a = (int)1.0;', '')
1639 self.assert_lint(' weird opening space', '')
1641 cpp_style._cpp_style_state.filters = old_filters
1643 def test_default_filter(self):
1644 default_filters = cpp_style._DEFAULT_FILTERS
1645 old_filters = cpp_style._cpp_style_state.filters
1646 cpp_style._DEFAULT_FILTERS = [ '-whitespace' ]
1649 cpp_style._cpp_style_state.set_filters('')
1650 self.assert_lint('// Hello there ', '')
1651 cpp_style._cpp_style_state.set_filters('+whitespace/end_of_line')
1654 'Line ends in whitespace. Consider deleting these extra spaces.'
1655 ' [whitespace/end_of_line] [4]')
1656 self.assert_lint(' weird opening space', '')
1658 cpp_style._cpp_style_state.filters = old_filters
1659 cpp_style._DEFAULT_FILTERS = default_filters
1661 def test_unnamed_namespaces_in_headers(self):
1662 self.assert_language_rules_check(
1663 'foo.h', 'namespace {',
1664 'Do not use unnamed namespaces in header files. See'
1665 ' http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
1666 ' for more information. [build/namespaces] [4]')
1667 # namespace registration macros are OK.
1668 self.assert_language_rules_check('foo.h', 'namespace { \\', '')
1669 # named namespaces are OK.
1670 self.assert_language_rules_check('foo.h', 'namespace foo {', '')
1671 self.assert_language_rules_check('foo.h', 'namespace foonamespace {', '')
1672 self.assert_language_rules_check('foo.cpp', 'namespace {', '')
1673 self.assert_language_rules_check('foo.cpp', 'namespace foo {', '')
1675 def test_build_class(self):
1676 # Test that the linter can parse to the end of class definitions,
1677 # and that it will report when it can't.
1678 # Use multi-line linter because it performs the ClassState check.
1679 self.assert_multi_line_lint(
1681 'Failed to find complete declaration of class Foo'
1682 ' [build/class] [5]')
1683 # Don't warn on forward declarations of various types.
1684 self.assert_multi_line_lint(
1687 self.assert_multi_line_lint(
1691 # Here is an example where the linter gets confused, even though
1692 # the code doesn't violate the style guide.
1693 self.assert_multi_line_lint(
1695 #ifdef DERIVE_FROM_GOO
1701 'Failed to find complete declaration of class Foo'
1702 ' [build/class] [5]')
1704 def test_build_end_comment(self):
1705 # The crosstool compiler we currently use will fail to compile the
1706 # code in this test, so we might consider removing the lint check.
1707 self.assert_lint('#endif Not a comment',
1708 'Uncommented text after #endif is non-standard.'
1710 ' [build/endif_comment] [5]')
1712 def test_build_forward_decl(self):
1713 # The crosstool compiler we currently use will fail to compile the
1714 # code in this test, so we might consider removing the lint check.
1715 self.assert_lint('class Foo::Goo;',
1716 'Inner-style forward declarations are invalid.'
1717 ' Remove this line.'
1718 ' [build/forward_decl] [5]')
1720 def test_build_header_guard(self):
1721 file_path = 'mydir/foo.h'
1723 # We can't rely on our internal stuff to get a sane path on the open source
1724 # side of things, so just parse out the suggested header guard. This
1725 # doesn't allow us to test the suggested header guard, but it does let us
1726 # test all the other header tests.
1727 error_collector = ErrorCollector(self.assert_)
1728 cpp_style.process_file_data(file_path, 'h', [], error_collector)
1730 matcher = re.compile(
1731 'No \#ifndef header guard found\, suggested CPP variable is\: ([A-Z_0-9]+) ')
1732 for error in error_collector.result_list():
1733 matches = matcher.match(error)
1735 expected_guard = matches.group(1)
1738 # Make sure we extracted something for our header guard.
1739 self.assertNotEqual(expected_guard, '')
1742 error_collector = ErrorCollector(self.assert_)
1743 cpp_style.process_file_data(file_path, 'h',
1744 ['#ifndef FOO_H', '#define FOO_H'], error_collector)
1747 error_collector.result_list().count(
1748 '#ifndef header guard has wrong style, please use: %s'
1749 ' [build/header_guard] [5]' % expected_guard),
1750 error_collector.result_list())
1753 error_collector = ErrorCollector(self.assert_)
1754 cpp_style.process_file_data(file_path, 'h',
1755 ['#ifndef %s' % expected_guard], error_collector)
1758 error_collector.result_list().count(
1759 'No #ifndef header guard found, suggested CPP variable is: %s'
1760 ' [build/header_guard] [5]' % expected_guard),
1761 error_collector.result_list())
1764 error_collector = ErrorCollector(self.assert_)
1765 cpp_style.process_file_data(file_path, 'h',
1766 ['#ifndef %s' % expected_guard,
1771 error_collector.result_list().count(
1772 'No #ifndef header guard found, suggested CPP variable is: %s'
1773 ' [build/header_guard] [5]' % expected_guard),
1774 error_collector.result_list())
1777 error_collector = ErrorCollector(self.assert_)
1778 cpp_style.process_file_data(file_path, 'h',
1779 ['#ifndef %s' % expected_guard,
1780 '#define %s' % expected_guard],
1784 error_collector.result_list().count(
1785 '#endif line should be "#endif // %s"'
1786 ' [build/header_guard] [5]' % expected_guard),
1787 error_collector.result_list())
1790 error_collector = ErrorCollector(self.assert_)
1791 cpp_style.process_file_data(file_path, 'h',
1792 ['#ifndef %s' % expected_guard,
1793 '#define %s' % expected_guard,
1798 error_collector.result_list().count(
1799 '#endif line should be "#endif // %s"'
1800 ' [build/header_guard] [5]' % expected_guard),
1801 error_collector.result_list())
1803 # Commentless endif for old-style guard
1804 error_collector = ErrorCollector(self.assert_)
1805 cpp_style.process_file_data(file_path, 'h',
1806 ['#ifndef %s_' % expected_guard,
1807 '#define %s_' % expected_guard,
1812 error_collector.result_list().count(
1813 '#endif line should be "#endif // %s"'
1814 ' [build/header_guard] [5]' % expected_guard),
1815 error_collector.result_list())
1817 # No header guard errors
1818 error_collector = ErrorCollector(self.assert_)
1819 cpp_style.process_file_data(file_path, 'h',
1820 ['#ifndef %s' % expected_guard,
1821 '#define %s' % expected_guard,
1822 '#endif // %s' % expected_guard],
1824 for line in error_collector.result_list():
1825 if line.find('build/header_guard') != -1:
1826 self.fail('Unexpected error: %s' % line)
1828 # No header guard errors for old-style guard
1829 error_collector = ErrorCollector(self.assert_)
1830 cpp_style.process_file_data(file_path, 'h',
1831 ['#ifndef %s_' % expected_guard,
1832 '#define %s_' % expected_guard,
1833 '#endif // %s_' % expected_guard],
1835 for line in error_collector.result_list():
1836 if line.find('build/header_guard') != -1:
1837 self.fail('Unexpected error: %s' % line)
1839 old_verbose_level = cpp_style._cpp_style_state.verbose_level
1841 cpp_style._cpp_style_state.verbose_level = 0
1842 # Warn on old-style guard if verbosity is 0.
1843 error_collector = ErrorCollector(self.assert_)
1844 cpp_style.process_file_data(file_path, 'h',
1845 ['#ifndef %s_' % expected_guard,
1846 '#define %s_' % expected_guard,
1847 '#endif // %s_' % expected_guard],
1851 error_collector.result_list().count(
1852 '#ifndef header guard has wrong style, please use: %s'
1853 ' [build/header_guard] [0]' % expected_guard),
1854 error_collector.result_list())
1856 cpp_style._cpp_style_state.verbose_level = old_verbose_level
1858 # Completely incorrect header guard
1859 error_collector = ErrorCollector(self.assert_)
1860 cpp_style.process_file_data(file_path, 'h',
1867 error_collector.result_list().count(
1868 '#ifndef header guard has wrong style, please use: %s'
1869 ' [build/header_guard] [5]' % expected_guard),
1870 error_collector.result_list())
1873 error_collector.result_list().count(
1874 '#endif line should be "#endif // %s"'
1875 ' [build/header_guard] [5]' % expected_guard),
1876 error_collector.result_list())
1878 def test_build_printf_format(self):
1880 r'printf("\%%d", value);',
1881 '%, [, (, and { are undefined character escapes. Unescape them.'
1882 ' [build/printf_format] [3]')
1885 r'snprintf(buffer, sizeof(buffer), "\[%d", value);',
1886 '%, [, (, and { are undefined character escapes. Unescape them.'
1887 ' [build/printf_format] [3]')
1890 r'fprintf(file, "\(%d", value);',
1891 '%, [, (, and { are undefined character escapes. Unescape them.'
1892 ' [build/printf_format] [3]')
1895 r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);',
1896 '%, [, (, and { are undefined character escapes. Unescape them.'
1897 ' [build/printf_format] [3]')
1899 # Don't warn if double-slash precedes the symbol
1900 self.assert_lint(r'printf("\\%%%d", value);',
1903 def test_runtime_printf_format(self):
1905 r'fprintf(file, "%q", value);',
1906 '%q in format strings is deprecated. Use %ll instead.'
1907 ' [runtime/printf_format] [3]')
1910 r'aprintf(file, "The number is %12q", value);',
1911 '%q in format strings is deprecated. Use %ll instead.'
1912 ' [runtime/printf_format] [3]')
1915 r'printf(file, "The number is" "%-12q", value);',
1916 '%q in format strings is deprecated. Use %ll instead.'
1917 ' [runtime/printf_format] [3]')
1920 r'printf(file, "The number is" "%+12q", value);',
1921 '%q in format strings is deprecated. Use %ll instead.'
1922 ' [runtime/printf_format] [3]')
1925 r'printf(file, "The number is" "% 12q", value);',
1926 '%q in format strings is deprecated. Use %ll instead.'
1927 ' [runtime/printf_format] [3]')
1930 r'snprintf(file, "Never mix %d and %1$d parmaeters!", value);',
1931 '%N$ formats are unconventional. Try rewriting to avoid them.'
1932 ' [runtime/printf_format] [2]')
1934 def assert_lintLogCodeOnError(self, code, expected_message):
1935 # Special assert_lint which logs the input code on error.
1936 result = self.perform_single_line_lint(code, 'foo.cpp')
1937 if result != expected_message:
1938 self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"'
1939 % (code, result, expected_message))
1941 def test_build_storage_class(self):
1942 qualifiers = [None, 'const', 'volatile']
1943 signs = [None, 'signed', 'unsigned']
1944 types = ['void', 'char', 'int', 'float', 'double',
1945 'schar', 'int8', 'uint8', 'int16', 'uint16',
1946 'int32', 'uint32', 'int64', 'uint64']
1947 storage_classes = ['auto', 'extern', 'register', 'static', 'typedef']
1949 build_storage_class_error_message = (
1950 'Storage class (static, extern, typedef, etc) should be first.'
1951 ' [build/storage_class] [5]')
1953 # Some explicit cases. Legal in C++, deprecated in C99.
1954 self.assert_lint('const int static foo = 5;',
1955 build_storage_class_error_message)
1957 self.assert_lint('char static foo;',
1958 build_storage_class_error_message)
1960 self.assert_lint('double const static foo = 2.0;',
1961 build_storage_class_error_message)
1963 self.assert_lint('uint64 typedef unsigned_long_long;',
1964 build_storage_class_error_message)
1966 self.assert_lint('int register foo = 0;',
1967 build_storage_class_error_message)
1969 # Since there are a very large number of possibilities, randomly
1970 # construct declarations.
1971 # Make sure that the declaration is logged if there's an error.
1972 # Seed generator with an integer for absolute reproducibility.
1974 for unused_i in range(10):
1975 # Build up random list of non-storage-class declaration specs.
1976 other_decl_specs = [random.choice(qualifiers), random.choice(signs),
1977 random.choice(types)]
1979 other_decl_specs = filter(lambda x: x is not None, other_decl_specs)
1982 random.shuffle(other_decl_specs)
1984 # insert storage class after the first
1985 storage_class = random.choice(storage_classes)
1986 insertion_point = random.randint(1, len(other_decl_specs))
1987 decl_specs = (other_decl_specs[0:insertion_point]
1989 + other_decl_specs[insertion_point:])
1991 self.assert_lintLogCodeOnError(
1992 ' '.join(decl_specs) + ';',
1993 build_storage_class_error_message)
1995 # but no error if storage class is first
1996 self.assert_lintLogCodeOnError(
1997 storage_class + ' ' + ' '.join(other_decl_specs),
2000 def test_legal_copyright(self):
2001 legal_copyright_message = (
2002 'No copyright message found. '
2003 'You should have a line: "Copyright [year] <Copyright Owner>"'
2004 ' [legal/copyright] [5]')
2006 copyright_line = '// Copyright 2008 Google Inc. All Rights Reserved.'
2008 file_path = 'mydir/googleclient/foo.cpp'
2010 # There should be a copyright message in the first 10 lines
2011 error_collector = ErrorCollector(self.assert_)
2012 cpp_style.process_file_data(file_path, 'cpp', [], error_collector)
2015 error_collector.result_list().count(legal_copyright_message))
2017 error_collector = ErrorCollector(self.assert_)
2018 cpp_style.process_file_data(
2020 ['' for unused_i in range(10)] + [copyright_line],
2024 error_collector.result_list().count(legal_copyright_message))
2026 # Test that warning isn't issued if Copyright line appears early enough.
2027 error_collector = ErrorCollector(self.assert_)
2028 cpp_style.process_file_data(file_path, 'cpp', [copyright_line], error_collector)
2029 for message in error_collector.result_list():
2030 if message.find('legal/copyright') != -1:
2031 self.fail('Unexpected error: %s' % message)
2033 error_collector = ErrorCollector(self.assert_)
2034 cpp_style.process_file_data(
2036 ['' for unused_i in range(9)] + [copyright_line],
2038 for message in error_collector.result_list():
2039 if message.find('legal/copyright') != -1:
2040 self.fail('Unexpected error: %s' % message)
2042 def test_invalid_increment(self):
2043 self.assert_lint('*count++;',
2044 'Changing pointer instead of value (or unused value of '
2045 'operator*). [runtime/invalid_increment] [5]')
2047 class CleansedLinesTest(unittest.TestCase):
2048 def test_init(self):
2051 'Line 3 // Comment test',
2054 clean_lines = cpp_style.CleansedLines(lines)
2055 self.assertEquals(lines, clean_lines.raw_lines)
2056 self.assertEquals(4, clean_lines.num_lines())
2058 self.assertEquals(['Line 1',
2064 self.assertEquals(['Line 1',
2070 def test_init_empty(self):
2071 clean_lines = cpp_style.CleansedLines([])
2072 self.assertEquals([], clean_lines.raw_lines)
2073 self.assertEquals(0, clean_lines.num_lines())
2075 def test_collapse_strings(self):
2076 collapse = cpp_style.CleansedLines.collapse_strings
2077 self.assertEquals('""', collapse('""')) # "" (empty)
2078 self.assertEquals('"""', collapse('"""')) # """ (bad)
2079 self.assertEquals('""', collapse('"xyz"')) # "xyz" (string)
2080 self.assertEquals('""', collapse('"\\\""')) # "\"" (string)
2081 self.assertEquals('""', collapse('"\'"')) # "'" (string)
2082 self.assertEquals('"\"', collapse('"\"')) # "\" (bad)
2083 self.assertEquals('""', collapse('"\\\\"')) # "\\" (string)
2084 self.assertEquals('"', collapse('"\\\\\\"')) # "\\\" (bad)
2085 self.assertEquals('""', collapse('"\\\\\\\\"')) # "\\\\" (string)
2087 self.assertEquals('\'\'', collapse('\'\'')) # '' (empty)
2088 self.assertEquals('\'\'', collapse('\'a\'')) # 'a' (char)
2089 self.assertEquals('\'\'', collapse('\'\\\'\'')) # '\'' (char)
2090 self.assertEquals('\'', collapse('\'\\\'')) # '\' (bad)
2091 self.assertEquals('', collapse('\\012')) # '\012' (char)
2092 self.assertEquals('', collapse('\\xfF0')) # '\xfF0' (char)
2093 self.assertEquals('', collapse('\\n')) # '\n' (char)
2094 self.assertEquals('\#', collapse('\\#')) # '\#' (bad)
2096 self.assertEquals('StringReplace(body, "", "");',
2097 collapse('StringReplace(body, "\\\\", "\\\\\\\\");'))
2098 self.assertEquals('\'\' ""',
2099 collapse('\'"\' "foo"'))
2102 class OrderOfIncludesTest(CppStyleTestBase):
2104 self.include_state = cpp_style._IncludeState()
2106 # Cheat os.path.abspath called in FileInfo class.
2107 self.os_path_abspath_orig = os.path.abspath
2108 os.path.abspath = lambda value: value
2111 os.path.abspath = self.os_path_abspath_orig
2113 def test_try_drop_common_suffixes(self):
2114 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h'))
2115 self.assertEqual('foo/bar/foo',
2116 cpp_style._drop_common_suffixes('foo/bar/foo_inl.h'))
2117 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp'))
2118 self.assertEqual('foo/foo_unusualinternal',
2119 cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h'))
2120 self.assertEqual('',
2121 cpp_style._drop_common_suffixes('_test.cpp'))
2122 self.assertEqual('test',
2123 cpp_style._drop_common_suffixes('test.cpp'))
2126 class OrderOfIncludesTest(CppStyleTestBase):
2128 self.include_state = cpp_style._IncludeState()
2130 # Cheat os.path.abspath called in FileInfo class.
2131 self.os_path_abspath_orig = os.path.abspath
2132 os.path.abspath = lambda value: value
2135 os.path.abspath = self.os_path_abspath_orig
2137 def test_check_next_include_order__no_config(self):
2138 self.assertEqual('Header file should not contain WebCore config.h.',
2139 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, True))
2141 def test_check_next_include_order__no_self(self):
2142 self.assertEqual('Header file should not contain itself.',
2143 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, True))
2144 # Test actual code to make sure that header types are correctly assigned.
2145 self.assert_language_rules_check('Foo.h',
2146 '#include "Foo.h"\n',
2147 'Header file should not contain itself. Should be: alphabetically sorted.'
2148 ' [build/include_order] [4]')
2149 self.assert_language_rules_check('FooBar.h',
2150 '#include "Foo.h"\n',
2153 def test_check_next_include_order__likely_then_config(self):
2154 self.assertEqual('Found header this file implements before WebCore config.h.',
2155 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False))
2156 self.assertEqual('Found WebCore config.h after a header this file implements.',
2157 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False))
2159 def test_check_next_include_order__other_then_config(self):
2160 self.assertEqual('Found other header before WebCore config.h.',
2161 self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False))
2162 self.assertEqual('Found WebCore config.h after other header.',
2163 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False))
2165 def test_check_next_include_order__config_then_other_then_likely(self):
2166 self.assertEqual('', self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False))
2167 self.assertEqual('Found other header before a header this file implements.',
2168 self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False))
2169 self.assertEqual('Found header this file implements after other header.',
2170 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False))
2172 def test_check_alphabetical_include_order(self):
2173 self.assert_language_rules_check('foo.h',
2177 'Alphabetical sorting problem. [build/include_order] [4]')
2179 self.assert_language_rules_check('foo.h',
2185 self.assert_language_rules_check('foo.h',
2186 '#include <assert.h>\n'
2187 '#include "bar.h"\n',
2188 'Alphabetical sorting problem. [build/include_order] [4]')
2190 self.assert_language_rules_check('foo.h',
2191 '#include "bar.h"\n'
2192 '#include <assert.h>\n',
2195 def test_check_line_break_after_own_header(self):
2196 self.assert_language_rules_check('foo.cpp',
2197 '#include "config.h"\n'
2198 '#include "foo.h"\n'
2199 '#include "bar.h"\n',
2200 'You should add a blank line after implementation file\'s own header. [build/include_order] [4]')
2202 self.assert_language_rules_check('foo.cpp',
2203 '#include "config.h"\n'
2204 '#include "foo.h"\n'
2206 '#include "bar.h"\n',
2209 def test_check_preprocessor_in_include_section(self):
2210 self.assert_language_rules_check('foo.cpp',
2211 '#include "config.h"\n'
2212 '#include "foo.h"\n'
2215 '#include "baz.h"\n'
2217 '#include "foobar.h"\n'
2219 '#include "bar.h"\n', # No flag because previous is in preprocessor section
2222 self.assert_language_rules_check('foo.cpp',
2223 '#include "config.h"\n'
2224 '#include "foo.h"\n'
2227 '#include "baz.h"\n'
2229 '#include "bar.h"\n'
2230 '#include "a.h"\n', # Should still flag this.
2231 'Alphabetical sorting problem. [build/include_order] [4]')
2233 self.assert_language_rules_check('foo.cpp',
2234 '#include "config.h"\n'
2235 '#include "foo.h"\n'
2238 '#include "baz.h"\n'
2239 '#include "bar.h"\n' #Should still flag this
2241 'Alphabetical sorting problem. [build/include_order] [4]')
2243 self.assert_language_rules_check('foo.cpp',
2244 '#include "config.h"\n'
2245 '#include "foo.h"\n'
2248 '#include "baz.h"\n'
2251 '#include "foobar.h"\n'
2253 '#include "bar.h"\n'
2254 '#include "a.h"\n', # Should still flag this.
2255 'Alphabetical sorting problem. [build/include_order] [4]')
2257 # Check that after an already included error, the sorting rules still work.
2258 self.assert_language_rules_check('foo.cpp',
2259 '#include "config.h"\n'
2260 '#include "foo.h"\n'
2262 '#include "foo.h"\n'
2264 '"foo.h" already included at foo.cpp:1 [build/include] [4]')
2266 def test_check_wtf_includes(self):
2267 self.assert_language_rules_check('foo.cpp',
2268 '#include "config.h"\n'
2269 '#include "foo.h"\n'
2271 '#include <wtf/Assertions.h>\n',
2273 self.assert_language_rules_check('foo.cpp',
2274 '#include "config.h"\n'
2275 '#include "foo.h"\n'
2277 '#include "wtf/Assertions.h"\n',
2278 'wtf includes should be <wtf/file.h> instead of "wtf/file.h".'
2279 ' [build/include] [4]')
2281 def test_classify_include(self):
2282 classify_include = cpp_style._classify_include
2283 include_state = cpp_style._IncludeState()
2284 self.assertEqual(cpp_style._CONFIG_HEADER,
2285 classify_include('foo/foo.cpp',
2287 False, include_state))
2288 self.assertEqual(cpp_style._PRIMARY_HEADER,
2289 classify_include('foo/internal/foo.cpp',
2291 False, include_state))
2292 self.assertEqual(cpp_style._PRIMARY_HEADER,
2293 classify_include('foo/internal/foo.cpp',
2294 'foo/other/public/foo.h',
2295 False, include_state))
2296 self.assertEqual(cpp_style._OTHER_HEADER,
2297 classify_include('foo/internal/foo.cpp',
2298 'foo/other/public/foop.h',
2299 False, include_state))
2300 self.assertEqual(cpp_style._OTHER_HEADER,
2301 classify_include('foo/foo.cpp',
2303 True, include_state))
2304 self.assertEqual(cpp_style._PRIMARY_HEADER,
2305 classify_include('fooCustom.cpp',
2307 False, include_state))
2308 # Tricky example where both includes might be classified as primary.
2309 self.assert_language_rules_check('ScrollbarThemeWince.cpp',
2310 '#include "config.h"\n'
2311 '#include "ScrollbarThemeWince.h"\n'
2313 '#include "Scrollbar.h"\n',
2315 self.assert_language_rules_check('ScrollbarThemeWince.cpp',
2316 '#include "config.h"\n'
2317 '#include "Scrollbar.h"\n'
2319 '#include "ScrollbarThemeWince.h"\n',
2320 'Found header this file implements after a header this file implements.'
2321 ' Should be: config.h, primary header, blank line, and then alphabetically sorted.'
2322 ' [build/include_order] [4]')
2324 def test_try_drop_common_suffixes(self):
2325 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h'))
2326 self.assertEqual('foo/bar/foo',
2327 cpp_style._drop_common_suffixes('foo/bar/foo_inl.h'))
2328 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp'))
2329 self.assertEqual('foo/foo_unusualinternal',
2330 cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h'))
2331 self.assertEqual('',
2332 cpp_style._drop_common_suffixes('_test.cpp'))
2333 self.assertEqual('test',
2334 cpp_style._drop_common_suffixes('test.cpp'))
2335 self.assertEqual('test',
2336 cpp_style._drop_common_suffixes('test.cpp'))
2338 class CheckForFunctionLengthsTest(CppStyleTestBase):
2340 # Reducing these thresholds for the tests speeds up tests significantly.
2341 self.old_normal_trigger = cpp_style._FunctionState._NORMAL_TRIGGER
2342 self.old_test_trigger = cpp_style._FunctionState._TEST_TRIGGER
2344 cpp_style._FunctionState._NORMAL_TRIGGER = 10
2345 cpp_style._FunctionState._TEST_TRIGGER = 25
2348 cpp_style._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger
2349 cpp_style._FunctionState._TEST_TRIGGER = self.old_test_trigger
2351 def assert_function_lengths_check(self, code, expected_message):
2352 """Check warnings for long function bodies are as expected.
2355 code: C++ source code expected to generate a warning message.
2356 expected_message: Message expected to be generated by the C++ code.
2358 self.assertEquals(expected_message,
2359 self.perform_function_lengths_check(code))
2361 def trigger_lines(self, error_level):
2362 """Return number of lines needed to trigger a function length warning.
2365 error_level: --v setting for cpp_style.
2368 Number of lines needed to trigger a function length warning.
2370 return cpp_style._FunctionState._NORMAL_TRIGGER * 2 ** error_level
2372 def trigger_test_lines(self, error_level):
2373 """Return number of lines needed to trigger a test function length warning.
2376 error_level: --v setting for cpp_style.
2379 Number of lines needed to trigger a test function length warning.
2381 return cpp_style._FunctionState._TEST_TRIGGER * 2 ** error_level
2383 def assert_function_length_check_definition(self, lines, error_level):
2384 """Generate long function definition and check warnings are as expected.
2387 lines: Number of lines to generate.
2388 error_level: --v setting for cpp_style.
2390 trigger_level = self.trigger_lines(cpp_style._verbose_level())
2391 self.assert_function_lengths_check(
2392 'void test(int x)' + self.function_body(lines),
2393 ('Small and focused functions are preferred: '
2394 'test() has %d non-comment lines '
2395 '(error triggered by exceeding %d lines).'
2396 ' [readability/fn_size] [%d]'
2397 % (lines, trigger_level, error_level)))
2399 def assert_function_length_check_definition_ok(self, lines):
2400 """Generate shorter function definition and check no warning is produced.
2403 lines: Number of lines to generate.
2405 self.assert_function_lengths_check(
2406 'void test(int x)' + self.function_body(lines),
2409 def assert_function_length_check_at_error_level(self, error_level):
2410 """Generate and check function at the trigger level for --v setting.
2413 error_level: --v setting for cpp_style.
2415 self.assert_function_length_check_definition(self.trigger_lines(error_level),
2418 def assert_function_length_check_below_error_level(self, error_level):
2419 """Generate and check function just below the trigger level for --v setting.
2422 error_level: --v setting for cpp_style.
2424 self.assert_function_length_check_definition(self.trigger_lines(error_level) - 1,
2427 def assert_function_length_check_above_error_level(self, error_level):
2428 """Generate and check function just above the trigger level for --v setting.
2431 error_level: --v setting for cpp_style.
2433 self.assert_function_length_check_definition(self.trigger_lines(error_level) + 1,
2436 def function_body(self, number_of_lines):
2437 return ' {\n' + ' this_is_just_a_test();\n' * number_of_lines + '}'
2439 def function_body_with_blank_lines(self, number_of_lines):
2440 return ' {\n' + ' this_is_just_a_test();\n\n' * number_of_lines + '}'
2442 def function_body_with_no_lints(self, number_of_lines):
2443 return ' {\n' + ' this_is_just_a_test(); // NOLINT\n' * number_of_lines + '}'
2445 # Test line length checks.
2446 def test_function_length_check_declaration(self):
2447 self.assert_function_lengths_check(
2448 'void test();', # Not a function definition
2451 def test_function_length_check_declaration_with_block_following(self):
2452 self.assert_function_lengths_check(
2454 + self.function_body(66)), # Not a function definition
2457 def test_function_length_check_class_definition(self):
2458 self.assert_function_lengths_check( # Not a function definition
2459 'class Test' + self.function_body(66) + ';',
2462 def test_function_length_check_trivial(self):
2463 self.assert_function_lengths_check(
2464 'void test() {}', # Not counted
2467 def test_function_length_check_empty(self):
2468 self.assert_function_lengths_check(
2472 def test_function_length_check_definition_below_severity0(self):
2473 old_verbosity = cpp_style._set_verbose_level(0)
2474 self.assert_function_length_check_definition_ok(self.trigger_lines(0) - 1)
2475 cpp_style._set_verbose_level(old_verbosity)
2477 def test_function_length_check_definition_at_severity0(self):
2478 old_verbosity = cpp_style._set_verbose_level(0)
2479 self.assert_function_length_check_definition_ok(self.trigger_lines(0))
2480 cpp_style._set_verbose_level(old_verbosity)
2482 def test_function_length_check_definition_above_severity0(self):
2483 old_verbosity = cpp_style._set_verbose_level(0)
2484 self.assert_function_length_check_above_error_level(0)
2485 cpp_style._set_verbose_level(old_verbosity)
2487 def test_function_length_check_definition_below_severity1v0(self):
2488 old_verbosity = cpp_style._set_verbose_level(0)
2489 self.assert_function_length_check_below_error_level(1)
2490 cpp_style._set_verbose_level(old_verbosity)
2492 def test_function_length_check_definition_at_severity1v0(self):
2493 old_verbosity = cpp_style._set_verbose_level(0)
2494 self.assert_function_length_check_at_error_level(1)
2495 cpp_style._set_verbose_level(old_verbosity)
2497 def test_function_length_check_definition_below_severity1(self):
2498 self.assert_function_length_check_definition_ok(self.trigger_lines(1) - 1)
2500 def test_function_length_check_definition_at_severity1(self):
2501 self.assert_function_length_check_definition_ok(self.trigger_lines(1))
2503 def test_function_length_check_definition_above_severity1(self):
2504 self.assert_function_length_check_above_error_level(1)
2506 def test_function_length_check_definition_severity1_plus_blanks(self):
2508 error_lines = self.trigger_lines(error_level) + 1
2509 trigger_level = self.trigger_lines(cpp_style._verbose_level())
2510 self.assert_function_lengths_check(
2511 'void test_blanks(int x)' + self.function_body(error_lines),
2512 ('Small and focused functions are preferred: '
2513 'test_blanks() has %d non-comment lines '
2514 '(error triggered by exceeding %d lines).'
2515 ' [readability/fn_size] [%d]')
2516 % (error_lines, trigger_level, error_level))
2518 def test_function_length_check_complex_definition_severity1(self):
2520 error_lines = self.trigger_lines(error_level) + 1
2521 trigger_level = self.trigger_lines(cpp_style._verbose_level())
2522 self.assert_function_lengths_check(
2523 ('my_namespace::my_other_namespace::MyVeryLongTypeName*\n'
2524 'my_namespace::my_other_namespace::MyFunction(int arg1, char* arg2)'
2525 + self.function_body(error_lines)),
2526 ('Small and focused functions are preferred: '
2527 'my_namespace::my_other_namespace::MyFunction()'
2528 ' has %d non-comment lines '
2529 '(error triggered by exceeding %d lines).'
2530 ' [readability/fn_size] [%d]')
2531 % (error_lines, trigger_level, error_level))
2533 def test_function_length_check_definition_severity1_for_test(self):
2535 error_lines = self.trigger_test_lines(error_level) + 1
2536 trigger_level = self.trigger_test_lines(cpp_style._verbose_level())
2537 self.assert_function_lengths_check(
2538 'TEST_F(Test, Mutator)' + self.function_body(error_lines),
2539 ('Small and focused functions are preferred: '
2540 'TEST_F(Test, Mutator) has %d non-comment lines '
2541 '(error triggered by exceeding %d lines).'
2542 ' [readability/fn_size] [%d]')
2543 % (error_lines, trigger_level, error_level))
2545 def test_function_length_check_definition_severity1_for_split_line_test(self):
2547 error_lines = self.trigger_test_lines(error_level) + 1
2548 trigger_level = self.trigger_test_lines(cpp_style._verbose_level())
2549 self.assert_function_lengths_check(
2550 ('TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,\n'
2551 ' FixGoogleUpdate_AllValues_MachineApp)' # note: 4 spaces
2552 + self.function_body(error_lines)),
2553 ('Small and focused functions are preferred: '
2554 'TEST_F(GoogleUpdateRecoveryRegistryProtectedTest, ' # 1 space
2555 'FixGoogleUpdate_AllValues_MachineApp) has %d non-comment lines '
2556 '(error triggered by exceeding %d lines).'
2557 ' [readability/fn_size] [%d]')
2558 % (error_lines+1, trigger_level, error_level))
2560 def test_function_length_check_definition_severity1_for_bad_test_doesnt_break(self):
2562 error_lines = self.trigger_test_lines(error_level) + 1
2563 trigger_level = self.trigger_test_lines(cpp_style._verbose_level())
2564 self.assert_function_lengths_check(
2566 + self.function_body(error_lines)),
2567 ('Small and focused functions are preferred: '
2568 'TEST_F has %d non-comment lines '
2569 '(error triggered by exceeding %d lines).'
2570 ' [readability/fn_size] [%d]')
2571 % (error_lines, trigger_level, error_level))
2573 def test_function_length_check_definition_severity1_with_embedded_no_lints(self):
2575 error_lines = self.trigger_lines(error_level) + 1
2576 trigger_level = self.trigger_lines(cpp_style._verbose_level())
2577 self.assert_function_lengths_check(
2578 'void test(int x)' + self.function_body_with_no_lints(error_lines),
2579 ('Small and focused functions are preferred: '
2580 'test() has %d non-comment lines '
2581 '(error triggered by exceeding %d lines).'
2582 ' [readability/fn_size] [%d]')
2583 % (error_lines, trigger_level, error_level))
2585 def test_function_length_check_definition_severity1_with_no_lint(self):
2586 self.assert_function_lengths_check(
2587 ('void test(int x)' + self.function_body(self.trigger_lines(1))
2588 + ' // NOLINT -- long function'),
2591 def test_function_length_check_definition_below_severity2(self):
2592 self.assert_function_length_check_below_error_level(2)
2594 def test_function_length_check_definition_severity2(self):
2595 self.assert_function_length_check_at_error_level(2)
2597 def test_function_length_check_definition_above_severity2(self):
2598 self.assert_function_length_check_above_error_level(2)
2600 def test_function_length_check_definition_below_severity3(self):
2601 self.assert_function_length_check_below_error_level(3)
2603 def test_function_length_check_definition_severity3(self):
2604 self.assert_function_length_check_at_error_level(3)
2606 def test_function_length_check_definition_above_severity3(self):
2607 self.assert_function_length_check_above_error_level(3)
2609 def test_function_length_check_definition_below_severity4(self):
2610 self.assert_function_length_check_below_error_level(4)
2612 def test_function_length_check_definition_severity4(self):
2613 self.assert_function_length_check_at_error_level(4)
2615 def test_function_length_check_definition_above_severity4(self):
2616 self.assert_function_length_check_above_error_level(4)
2618 def test_function_length_check_definition_below_severity5(self):
2619 self.assert_function_length_check_below_error_level(5)
2621 def test_function_length_check_definition_at_severity5(self):
2622 self.assert_function_length_check_at_error_level(5)
2624 def test_function_length_check_definition_above_severity5(self):
2625 self.assert_function_length_check_above_error_level(5)
2627 def test_function_length_check_definition_huge_lines(self):
2629 self.assert_function_length_check_definition(self.trigger_lines(10), 5)
2631 def test_function_length_not_determinable(self):
2632 # Macro invocation without terminating semicolon.
2633 self.assert_function_lengths_check(
2637 # Macro with underscores
2638 self.assert_function_lengths_check(
2639 'MACRO_WITH_UNDERSCORES(arg1, arg2, arg3)',
2642 self.assert_function_lengths_check(
2644 'Lint failed to find start of function body.'
2645 ' [readability/fn_size] [5]')
2648 class NoNonVirtualDestructorsTest(CppStyleTestBase):
2650 def test_no_error(self):
2651 self.assert_multi_line_lint(
2658 self.assert_multi_line_lint(
2660 virtual inline ~Foo();
2665 self.assert_multi_line_lint(
2667 inline virtual ~Foo();
2672 self.assert_multi_line_lint(
2678 self.assert_multi_line_lint(
2679 'class Foo { void foo(); };',
2680 'More than one command on the same line [whitespace/newline] [4]')
2682 self.assert_multi_line_lint(
2683 '''class Qualified::Goo : public Foo {
2688 self.assert_multi_line_lint(
2694 'Labels should always be indented at least one space. If this is a '
2695 'member-initializer list in a constructor, the colon should be on the '
2696 'line after the definition header. [whitespace/labels] [4]')
2698 def test_no_destructor_when_virtual_needed(self):
2699 self.assert_multi_line_lint_re(
2703 'The class Foo probably needs a virtual destructor')
2705 def test_destructor_non_virtual_when_virtual_needed(self):
2706 self.assert_multi_line_lint_re(
2711 'The class Foo probably needs a virtual destructor')
2713 def test_no_warn_when_derived(self):
2714 self.assert_multi_line_lint(
2715 '''class Foo : public Goo {
2720 def test_internal_braces(self):
2721 self.assert_multi_line_lint_re(
2728 'The class Foo probably needs a virtual destructor')
2730 def test_inner_class_needs_virtual_destructor(self):
2731 self.assert_multi_line_lint_re(
2737 'The class Goo probably needs a virtual destructor')
2739 def test_outer_class_needs_virtual_destructor(self):
2740 self.assert_multi_line_lint_re(
2746 'The class Foo probably needs a virtual destructor')
2748 def test_qualified_class_needs_virtual_destructor(self):
2749 self.assert_multi_line_lint_re(
2750 '''class Qualified::Foo {
2753 'The class Qualified::Foo probably needs a virtual destructor')
2755 def test_multi_line_declaration_no_error(self):
2756 self.assert_multi_line_lint_re(
2763 def test_multi_line_declaration_with_error(self):
2764 self.assert_multi_line_lint(
2769 ['This { should be at the end of the previous line '
2770 '[whitespace/braces] [4]',
2771 'The class Foo probably needs a virtual destructor due to having '
2772 'virtual method(s), one declared at line 2. [runtime/virtual] [4]'])
2775 class CppStyleStateTest(unittest.TestCase):
2776 def test_error_count(self):
2777 self.assertEquals(0, cpp_style.error_count())
2778 cpp_style._cpp_style_state.increment_error_count()
2779 cpp_style._cpp_style_state.increment_error_count()
2780 self.assertEquals(2, cpp_style.error_count())
2781 cpp_style._cpp_style_state.reset_error_count()
2782 self.assertEquals(0, cpp_style.error_count())
2785 class WebKitStyleTest(CppStyleTestBase):
2787 # for http://webkit.org/coding/coding-style.html
2788 def test_indentation(self):
2789 # 1. Use spaces, not tabs. Tabs should only appear in files that
2790 # require them for semantic meaning, like Makefiles.
2791 self.assert_multi_line_lint(
2796 self.assert_multi_line_lint(
2800 'Tab found; better to use spaces [whitespace/tab] [1]')
2802 # 2. The indent size is 4 spaces.
2803 self.assert_multi_line_lint(
2808 self.assert_multi_line_lint(
2812 'Weird number of spaces at line-start. Are you using a 4-space indent? [whitespace/indent] [3]')
2813 # FIXME: No tests for 8-spaces.
2815 # 3. In a header, code inside a namespace should not be indented.
2816 self.assert_multi_line_lint(
2817 'namespace WebCore {\n\n'
2818 'class Document {\n'
2819 ' int myVariable;\n'
2824 self.assert_multi_line_lint(
2825 'namespace OuterNamespace {\n'
2826 ' namespace InnerNamespace {\n'
2827 ' class Document {\n'
2831 ['Code inside a namespace should not be indented. [whitespace/indent] [4]', 'namespace should never be indented. [whitespace/indent] [4]'],
2833 self.assert_multi_line_lint(
2834 'namespace WebCore {\n'
2836 ' class Document {\n'
2840 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
2842 self.assert_multi_line_lint(
2843 'namespace WebCore {\n'
2844 'class Document {\n'
2850 # 4. In an implementation file (files with the extension .cpp, .c
2851 # or .mm), code inside a namespace should not be indented.
2852 self.assert_multi_line_lint(
2853 'namespace WebCore {\n\n'
2862 self.assert_multi_line_lint(
2863 'namespace OuterNamespace {\n'
2864 'namespace InnerNamespace {\n'
2865 'Document::Foo() { }\n'
2869 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
2871 self.assert_multi_line_lint(
2872 'namespace OuterNamespace {\n'
2873 'namespace InnerNamespace {\n'
2874 'Document::Foo() { }\n'
2878 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
2880 self.assert_multi_line_lint(
2881 'namespace WebCore {\n\n'
2882 ' const char* foo = "start:;"\n'
2885 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
2887 self.assert_multi_line_lint(
2888 'namespace WebCore {\n\n'
2889 'const char* foo(void* a = ";", // ;\n'
2893 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
2895 self.assert_multi_line_lint(
2896 'namespace WebCore {\n\n'
2897 'const char* foo[] = {\n'
2898 ' "void* b);", // ;\n'