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',
1274 self.assert_multi_line_lint('#include "config.h"\n#import <foo/bar.h>\n',
1277 def test_spacing_before_last_semicolon(self):
1278 self.assert_lint('call_function() ;',
1279 'Extra space before last semicolon. If this should be an '
1280 'empty statement, use { } instead.'
1281 ' [whitespace/semicolon] [5]')
1282 self.assert_lint('while (true) ;',
1283 'Extra space before last semicolon. If this should be an '
1284 'empty statement, use { } instead.'
1285 ' [whitespace/semicolon] [5]')
1286 self.assert_lint('default:;',
1287 'Semicolon defining empty statement. Use { } instead.'
1288 ' [whitespace/semicolon] [5]')
1289 self.assert_lint(' ;',
1290 'Line contains only semicolon. If this should be an empty '
1291 'statement, use { } instead.'
1292 ' [whitespace/semicolon] [5]')
1293 self.assert_lint('for (int i = 0; ;', '')
1295 # Static or global STL strings.
1296 def test_static_or_global_stlstrings(self):
1297 self.assert_lint('string foo;',
1298 'For a static/global string constant, use a C style '
1299 'string instead: "char foo[]".'
1300 ' [runtime/string] [4]')
1301 self.assert_lint('string kFoo = "hello"; // English',
1302 'For a static/global string constant, use a C style '
1303 'string instead: "char kFoo[]".'
1304 ' [runtime/string] [4]')
1305 self.assert_lint('static string foo;',
1306 'For a static/global string constant, use a C style '
1307 'string instead: "static char foo[]".'
1308 ' [runtime/string] [4]')
1309 self.assert_lint('static const string foo;',
1310 'For a static/global string constant, use a C style '
1311 'string instead: "static const char foo[]".'
1312 ' [runtime/string] [4]')
1313 self.assert_lint('string Foo::bar;',
1314 'For a static/global string constant, use a C style '
1315 'string instead: "char Foo::bar[]".'
1316 ' [runtime/string] [4]')
1318 self.assert_lint('string foo("foobar");',
1319 'For a static/global string constant, use a C style '
1320 'string instead: "char foo[]".'
1321 ' [runtime/string] [4]')
1322 # Should not catch local or member variables.
1323 self.assert_lint(' string foo', '')
1324 # Should not catch functions.
1325 self.assert_lint('string EmptyString() { return ""; }', '')
1326 self.assert_lint('string EmptyString () { return ""; }', '')
1327 self.assert_lint('string VeryLongNameFunctionSometimesEndsWith(\n'
1328 ' VeryLongNameType very_long_name_variable) {}', '')
1329 self.assert_lint('template<>\n'
1330 'string FunctionTemplateSpecialization<SomeType>(\n'
1331 ' int x) { return ""; }', '')
1332 self.assert_lint('template<>\n'
1333 'string FunctionTemplateSpecialization<vector<A::B>* >(\n'
1334 ' int x) { return ""; }', '')
1336 # should not catch methods of template classes.
1337 self.assert_lint('string Class<Type>::Method() const\n'
1341 self.assert_lint('string Class<Type>::Method(\n'
1347 def test_no_spaces_in_function_calls(self):
1348 self.assert_lint('TellStory(1, 3);',
1350 self.assert_lint('TellStory(1, 3 );',
1351 'Extra space before )'
1352 ' [whitespace/parens] [2]')
1353 self.assert_lint('TellStory(1 /* wolf */, 3 /* pigs */);',
1355 self.assert_multi_line_lint('#endif\n );',
1358 def test_two_spaces_between_code_and_comments(self):
1359 self.assert_lint('} // namespace foo',
1360 'At least two spaces is best between code and comments'
1361 ' [whitespace/comments] [2]')
1362 self.assert_lint('}// namespace foo',
1363 'At least two spaces is best between code and comments'
1364 ' [whitespace/comments] [2]')
1365 self.assert_lint('printf("foo"); // Outside quotes.',
1366 'At least two spaces is best between code and comments'
1367 ' [whitespace/comments] [2]')
1368 self.assert_lint('int i = 0; // Having two spaces is fine.', '')
1369 self.assert_lint('int i = 0; // Having three spaces is OK.', '')
1370 self.assert_lint('// Top level comment', '')
1371 self.assert_lint(' // Line starts with four spaces.', '')
1372 self.assert_lint('foo();\n'
1373 '{ // A scope is opening.', '')
1374 self.assert_lint(' foo();\n'
1375 ' { // An indented scope is opening.', '')
1376 self.assert_lint('if (foo) { // not a pure scope; comment is too close!',
1377 'At least two spaces is best between code and comments'
1378 ' [whitespace/comments] [2]')
1379 self.assert_lint('printf("// In quotes.")', '')
1380 self.assert_lint('printf("\\"%s // In quotes.")', '')
1381 self.assert_lint('printf("%s", "// In quotes.")', '')
1383 def test_space_after_comment_marker(self):
1384 self.assert_lint('//', '')
1385 self.assert_lint('//x', 'Should have a space between // and comment'
1386 ' [whitespace/comments] [4]')
1387 self.assert_lint('// x', '')
1388 self.assert_lint('//----', '')
1389 self.assert_lint('//====', '')
1390 self.assert_lint('//////', '')
1391 self.assert_lint('////// x', '')
1392 self.assert_lint('/// x', '')
1393 self.assert_lint('////x', 'Should have a space between // and comment'
1394 ' [whitespace/comments] [4]')
1396 def test_newline_at_eof(self):
1397 def do_test(self, data, is_missing_eof):
1398 error_collector = ErrorCollector(self.assert_)
1399 cpp_style.process_file_data('foo.cpp', 'cpp', data.split('\n'),
1401 # The warning appears only once.
1403 int(is_missing_eof),
1404 error_collector.results().count(
1405 'Could not find a newline character at the end of the file.'
1406 ' [whitespace/ending_newline] [5]'))
1408 do_test(self, '// Newline\n// at EOF\n', False)
1409 do_test(self, '// No newline\n// at EOF', True)
1411 def test_invalid_utf8(self):
1412 def do_test(self, raw_bytes, has_invalid_utf8):
1413 error_collector = ErrorCollector(self.assert_)
1414 cpp_style.process_file_data(
1416 unicode(raw_bytes, 'utf8', 'replace').split('\n'),
1418 # The warning appears only once.
1420 int(has_invalid_utf8),
1421 error_collector.results().count(
1422 'Line contains invalid UTF-8'
1423 ' (or Unicode replacement character).'
1424 ' [readability/utf8] [5]'))
1426 do_test(self, 'Hello world\n', False)
1427 do_test(self, '\xe9\x8e\xbd\n', False)
1428 do_test(self, '\xe9x\x8e\xbd\n', True)
1429 # This is the encoding of the replacement character itself (which
1430 # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')).
1431 do_test(self, '\xef\xbf\xbd\n', True)
1433 def test_is_blank_line(self):
1434 self.assert_(cpp_style.is_blank_line(''))
1435 self.assert_(cpp_style.is_blank_line(' '))
1436 self.assert_(cpp_style.is_blank_line(' \t\r\n'))
1437 self.assert_(not cpp_style.is_blank_line('int a;'))
1438 self.assert_(not cpp_style.is_blank_line('{'))
1440 def test_blank_lines_check(self):
1441 self.assert_blank_lines_check(['{\n', '\n', '\n', '}\n'], 1, 1)
1442 self.assert_blank_lines_check([' if (foo) {\n', '\n', ' }\n'], 1, 1)
1443 self.assert_blank_lines_check(
1444 ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0)
1445 self.assert_blank_lines_check(['\n', 'run("{");\n', '\n'], 0, 0)
1446 self.assert_blank_lines_check(['\n', ' if (foo) { return 0; }\n', '\n'], 0, 0)
1448 def test_allow_blank_line_before_closing_namespace(self):
1449 error_collector = ErrorCollector(self.assert_)
1450 cpp_style.process_file_data('foo.cpp', 'cpp',
1451 ['namespace {', '', '} // namespace'],
1453 self.assertEquals(0, error_collector.results().count(
1454 'Blank line at the end of a code block. Is this needed?'
1455 ' [whitespace/blank_line] [3]'))
1457 def test_allow_blank_line_before_if_else_chain(self):
1458 error_collector = ErrorCollector(self.assert_)
1459 cpp_style.process_file_data('foo.cpp', 'cpp',
1462 '} else if (piyo) {',
1464 '} else if (piyopiyo) {',
1465 ' hoge = true;', # No warning
1467 '', # Warning on this line
1470 self.assertEquals(1, error_collector.results().count(
1471 'Blank line at the end of a code block. Is this needed?'
1472 ' [whitespace/blank_line] [3]'))
1474 def test_else_on_same_line_as_closing_braces(self):
1475 error_collector = ErrorCollector(self.assert_)
1476 cpp_style.process_file_data('foo.cpp', 'cpp',
1480 ' else {' # Warning on this line
1484 self.assertEquals(1, error_collector.results().count(
1485 'An else should appear on the same line as the preceding }'
1486 ' [whitespace/newline] [4]'))
1488 def test_else_clause_not_on_same_line_as_else(self):
1489 self.assert_lint(' else DoSomethingElse();',
1490 'Else clause should never be on same line as else '
1491 '(use 2 lines) [whitespace/newline] [4]')
1492 self.assert_lint(' else ifDoSomethingElse();',
1493 'Else clause should never be on same line as else '
1494 '(use 2 lines) [whitespace/newline] [4]')
1495 self.assert_lint(' else if (blah) {', '')
1496 self.assert_lint(' variable_ends_in_else = true;', '')
1498 def test_comma(self):
1499 self.assert_lint('a = f(1,2);',
1500 'Missing space after , [whitespace/comma] [3]')
1501 self.assert_lint('int tmp=a,a=b,b=tmp;',
1502 ['Missing spaces around = [whitespace/operators] [4]',
1503 'Missing space after , [whitespace/comma] [3]'])
1504 self.assert_lint('f(a, /* name */ b);', '')
1505 self.assert_lint('f(a, /* name */b);', '')
1507 def test_pointer_reference_marker_location(self):
1508 self.assert_lint('int* b;', '', 'foo.cpp')
1509 self.assert_lint('int *b;',
1510 'Declaration has space between type name and * in int *b [whitespace/declaration] [3]',
1512 self.assert_lint('return *b;', '', 'foo.cpp')
1513 self.assert_lint('int *b;', '', 'foo.c')
1514 self.assert_lint('int* b;',
1515 'Declaration has space between * and variable name in int* b [whitespace/declaration] [3]',
1517 self.assert_lint('int& b;', '', 'foo.cpp')
1518 self.assert_lint('int &b;',
1519 'Declaration has space between type name and & in int &b [whitespace/declaration] [3]',
1521 self.assert_lint('return &b;', '', 'foo.cpp')
1523 def test_indent(self):
1524 self.assert_lint('static int noindent;', '')
1525 self.assert_lint(' int four_space_indent;', '')
1526 self.assert_lint(' int one_space_indent;',
1527 'Weird number of spaces at line-start. '
1528 'Are you using a 4-space indent? [whitespace/indent] [3]')
1529 self.assert_lint(' int three_space_indent;',
1530 'Weird number of spaces at line-start. '
1531 'Are you using a 4-space indent? [whitespace/indent] [3]')
1532 self.assert_lint(' char* one_space_indent = "public:";',
1533 'Weird number of spaces at line-start. '
1534 'Are you using a 4-space indent? [whitespace/indent] [3]')
1535 self.assert_lint(' public:', '')
1536 self.assert_lint(' public:', '')
1537 self.assert_lint(' public:', '')
1539 def test_label(self):
1540 self.assert_lint('public:',
1541 'Labels should always be indented at least one space. '
1542 'If this is a member-initializer list in a constructor, '
1543 'the colon should be on the line after the definition '
1544 'header. [whitespace/labels] [4]')
1545 self.assert_lint(' public:', '')
1546 self.assert_lint(' public:', '')
1547 self.assert_lint(' public:', '')
1548 self.assert_lint(' public:', '')
1549 self.assert_lint(' public:', '')
1551 def test_not_alabel(self):
1552 self.assert_lint('MyVeryLongNamespace::MyVeryLongClassName::', '')
1555 self.assert_lint('\tint a;',
1556 'Tab found; better to use spaces [whitespace/tab] [1]')
1557 self.assert_lint('int a = 5;\t\t// set a to 5',
1558 'Tab found; better to use spaces [whitespace/tab] [1]')
1560 def test_parse_arguments(self):
1561 old_usage = cpp_style._USAGE
1562 old_error_categories = cpp_style._ERROR_CATEGORIES
1563 old_output_format = cpp_style._cpp_style_state.output_format
1564 old_verbose_level = cpp_style._cpp_style_state.verbose_level
1565 old_filters = cpp_style._cpp_style_state.filters
1567 # Don't print usage during the tests, or filter categories
1568 cpp_style._USAGE = ''
1569 cpp_style._ERROR_CATEGORIES = ''
1571 self.assertRaises(SystemExit, cpp_style.parse_arguments, ['--badopt'])
1572 self.assertRaises(SystemExit, cpp_style.parse_arguments, ['--help'])
1573 self.assertRaises(SystemExit, cpp_style.parse_arguments, ['--filter='])
1574 # This is illegal because all filters must start with + or -
1575 self.assertRaises(ValueError, cpp_style.parse_arguments, ['--filter=foo'])
1576 self.assertRaises(ValueError, cpp_style.parse_arguments,
1577 ['--filter=+a,b,-c'])
1579 self.assertEquals((['foo.cpp'], {}), cpp_style.parse_arguments(['foo.cpp']))
1580 self.assertEquals(old_output_format, cpp_style._cpp_style_state.output_format)
1581 self.assertEquals(old_verbose_level, cpp_style._cpp_style_state.verbose_level)
1583 self.assertEquals(([], {}), cpp_style.parse_arguments([]))
1584 self.assertEquals(([], {}), cpp_style.parse_arguments(['--v=0']))
1586 self.assertEquals((['foo.cpp'], {}),
1587 cpp_style.parse_arguments(['--v=1', 'foo.cpp']))
1588 self.assertEquals(1, cpp_style._cpp_style_state.verbose_level)
1589 self.assertEquals((['foo.h'], {}),
1590 cpp_style.parse_arguments(['--v=3', 'foo.h']))
1591 self.assertEquals(3, cpp_style._cpp_style_state.verbose_level)
1592 self.assertEquals((['foo.cpp'], {}),
1593 cpp_style.parse_arguments(['--verbose=5', 'foo.cpp']))
1594 self.assertEquals(5, cpp_style._cpp_style_state.verbose_level)
1595 self.assertRaises(ValueError,
1596 cpp_style.parse_arguments, ['--v=f', 'foo.cpp'])
1598 self.assertEquals((['foo.cpp'], {}),
1599 cpp_style.parse_arguments(['--output=emacs', 'foo.cpp']))
1600 self.assertEquals('emacs', cpp_style._cpp_style_state.output_format)
1601 self.assertEquals((['foo.h'], {}),
1602 cpp_style.parse_arguments(['--output=vs7', 'foo.h']))
1603 self.assertEquals('vs7', cpp_style._cpp_style_state.output_format)
1604 self.assertRaises(SystemExit,
1605 cpp_style.parse_arguments, ['--output=blah', 'foo.cpp'])
1607 filt = '-,+whitespace,-whitespace/indent'
1608 self.assertEquals((['foo.h'], {}),
1609 cpp_style.parse_arguments(['--filter='+filt, 'foo.h']))
1610 self.assertEquals(['-', '+whitespace', '-whitespace/indent'],
1611 cpp_style._cpp_style_state.filters)
1613 self.assertEquals((['foo.cpp', 'foo.h'], {}),
1614 cpp_style.parse_arguments(['foo.cpp', 'foo.h']))
1616 self.assertEquals((['foo.cpp'], {'--foo': ''}),
1617 cpp_style.parse_arguments(['--foo', 'foo.cpp'], ['foo']))
1618 self.assertEquals((['foo.cpp'], {'--foo': 'bar'}),
1619 cpp_style.parse_arguments(['--foo=bar', 'foo.cpp'], ['foo=']))
1620 self.assertEquals((['foo.cpp'], {}),
1621 cpp_style.parse_arguments(['foo.cpp'], ['foo=']))
1622 self.assertRaises(SystemExit,
1623 cpp_style.parse_arguments,
1624 ['--footypo=bar', 'foo.cpp'], ['foo='])
1626 cpp_style._USAGE = old_usage
1627 cpp_style._ERROR_CATEGORIES = old_error_categories
1628 cpp_style._cpp_style_state.output_format = old_output_format
1629 cpp_style._cpp_style_state.verbose_level = old_verbose_level
1630 cpp_style._cpp_style_state.filters = old_filters
1632 def test_filter(self):
1633 old_filters = cpp_style._cpp_style_state.filters
1635 cpp_style._cpp_style_state.set_filters('-,+whitespace,-whitespace/indent')
1638 'Line ends in whitespace. Consider deleting these extra spaces.'
1639 ' [whitespace/end_of_line] [4]')
1640 self.assert_lint('int a = (int)1.0;', '')
1641 self.assert_lint(' weird opening space', '')
1643 cpp_style._cpp_style_state.filters = old_filters
1645 def test_default_filter(self):
1646 default_filters = cpp_style._DEFAULT_FILTERS
1647 old_filters = cpp_style._cpp_style_state.filters
1648 cpp_style._DEFAULT_FILTERS = [ '-whitespace' ]
1651 cpp_style._cpp_style_state.set_filters('')
1652 self.assert_lint('// Hello there ', '')
1653 cpp_style._cpp_style_state.set_filters('+whitespace/end_of_line')
1656 'Line ends in whitespace. Consider deleting these extra spaces.'
1657 ' [whitespace/end_of_line] [4]')
1658 self.assert_lint(' weird opening space', '')
1660 cpp_style._cpp_style_state.filters = old_filters
1661 cpp_style._DEFAULT_FILTERS = default_filters
1663 def test_unnamed_namespaces_in_headers(self):
1664 self.assert_language_rules_check(
1665 'foo.h', 'namespace {',
1666 'Do not use unnamed namespaces in header files. See'
1667 ' http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
1668 ' for more information. [build/namespaces] [4]')
1669 # namespace registration macros are OK.
1670 self.assert_language_rules_check('foo.h', 'namespace { \\', '')
1671 # named namespaces are OK.
1672 self.assert_language_rules_check('foo.h', 'namespace foo {', '')
1673 self.assert_language_rules_check('foo.h', 'namespace foonamespace {', '')
1674 self.assert_language_rules_check('foo.cpp', 'namespace {', '')
1675 self.assert_language_rules_check('foo.cpp', 'namespace foo {', '')
1677 def test_build_class(self):
1678 # Test that the linter can parse to the end of class definitions,
1679 # and that it will report when it can't.
1680 # Use multi-line linter because it performs the ClassState check.
1681 self.assert_multi_line_lint(
1683 'Failed to find complete declaration of class Foo'
1684 ' [build/class] [5]')
1685 # Don't warn on forward declarations of various types.
1686 self.assert_multi_line_lint(
1689 self.assert_multi_line_lint(
1693 # Here is an example where the linter gets confused, even though
1694 # the code doesn't violate the style guide.
1695 self.assert_multi_line_lint(
1697 #ifdef DERIVE_FROM_GOO
1703 'Failed to find complete declaration of class Foo'
1704 ' [build/class] [5]')
1706 def test_build_end_comment(self):
1707 # The crosstool compiler we currently use will fail to compile the
1708 # code in this test, so we might consider removing the lint check.
1709 self.assert_lint('#endif Not a comment',
1710 'Uncommented text after #endif is non-standard.'
1712 ' [build/endif_comment] [5]')
1714 def test_build_forward_decl(self):
1715 # The crosstool compiler we currently use will fail to compile the
1716 # code in this test, so we might consider removing the lint check.
1717 self.assert_lint('class Foo::Goo;',
1718 'Inner-style forward declarations are invalid.'
1719 ' Remove this line.'
1720 ' [build/forward_decl] [5]')
1722 def test_build_header_guard(self):
1723 file_path = 'mydir/foo.h'
1725 # We can't rely on our internal stuff to get a sane path on the open source
1726 # side of things, so just parse out the suggested header guard. This
1727 # doesn't allow us to test the suggested header guard, but it does let us
1728 # test all the other header tests.
1729 error_collector = ErrorCollector(self.assert_)
1730 cpp_style.process_file_data(file_path, 'h', [], error_collector)
1732 matcher = re.compile(
1733 'No \#ifndef header guard found\, suggested CPP variable is\: ([A-Z_0-9]+) ')
1734 for error in error_collector.result_list():
1735 matches = matcher.match(error)
1737 expected_guard = matches.group(1)
1740 # Make sure we extracted something for our header guard.
1741 self.assertNotEqual(expected_guard, '')
1744 error_collector = ErrorCollector(self.assert_)
1745 cpp_style.process_file_data(file_path, 'h',
1746 ['#ifndef FOO_H', '#define FOO_H'], error_collector)
1749 error_collector.result_list().count(
1750 '#ifndef header guard has wrong style, please use: %s'
1751 ' [build/header_guard] [5]' % expected_guard),
1752 error_collector.result_list())
1755 error_collector = ErrorCollector(self.assert_)
1756 cpp_style.process_file_data(file_path, 'h',
1757 ['#ifndef %s' % expected_guard], error_collector)
1760 error_collector.result_list().count(
1761 'No #ifndef header guard found, suggested CPP variable is: %s'
1762 ' [build/header_guard] [5]' % expected_guard),
1763 error_collector.result_list())
1766 error_collector = ErrorCollector(self.assert_)
1767 cpp_style.process_file_data(file_path, 'h',
1768 ['#ifndef %s' % expected_guard,
1773 error_collector.result_list().count(
1774 'No #ifndef header guard found, suggested CPP variable is: %s'
1775 ' [build/header_guard] [5]' % expected_guard),
1776 error_collector.result_list())
1779 error_collector = ErrorCollector(self.assert_)
1780 cpp_style.process_file_data(file_path, 'h',
1781 ['#ifndef %s' % expected_guard,
1782 '#define %s' % expected_guard],
1786 error_collector.result_list().count(
1787 '#endif line should be "#endif // %s"'
1788 ' [build/header_guard] [5]' % expected_guard),
1789 error_collector.result_list())
1792 error_collector = ErrorCollector(self.assert_)
1793 cpp_style.process_file_data(file_path, 'h',
1794 ['#ifndef %s' % expected_guard,
1795 '#define %s' % expected_guard,
1800 error_collector.result_list().count(
1801 '#endif line should be "#endif // %s"'
1802 ' [build/header_guard] [5]' % expected_guard),
1803 error_collector.result_list())
1805 # Commentless endif for old-style guard
1806 error_collector = ErrorCollector(self.assert_)
1807 cpp_style.process_file_data(file_path, 'h',
1808 ['#ifndef %s_' % expected_guard,
1809 '#define %s_' % expected_guard,
1814 error_collector.result_list().count(
1815 '#endif line should be "#endif // %s"'
1816 ' [build/header_guard] [5]' % expected_guard),
1817 error_collector.result_list())
1819 # No header guard errors
1820 error_collector = ErrorCollector(self.assert_)
1821 cpp_style.process_file_data(file_path, 'h',
1822 ['#ifndef %s' % expected_guard,
1823 '#define %s' % expected_guard,
1824 '#endif // %s' % expected_guard],
1826 for line in error_collector.result_list():
1827 if line.find('build/header_guard') != -1:
1828 self.fail('Unexpected error: %s' % line)
1830 # No header guard errors for old-style guard
1831 error_collector = ErrorCollector(self.assert_)
1832 cpp_style.process_file_data(file_path, 'h',
1833 ['#ifndef %s_' % expected_guard,
1834 '#define %s_' % expected_guard,
1835 '#endif // %s_' % expected_guard],
1837 for line in error_collector.result_list():
1838 if line.find('build/header_guard') != -1:
1839 self.fail('Unexpected error: %s' % line)
1841 old_verbose_level = cpp_style._cpp_style_state.verbose_level
1843 cpp_style._cpp_style_state.verbose_level = 0
1844 # Warn on old-style guard if verbosity is 0.
1845 error_collector = ErrorCollector(self.assert_)
1846 cpp_style.process_file_data(file_path, 'h',
1847 ['#ifndef %s_' % expected_guard,
1848 '#define %s_' % expected_guard,
1849 '#endif // %s_' % expected_guard],
1853 error_collector.result_list().count(
1854 '#ifndef header guard has wrong style, please use: %s'
1855 ' [build/header_guard] [0]' % expected_guard),
1856 error_collector.result_list())
1858 cpp_style._cpp_style_state.verbose_level = old_verbose_level
1860 # Completely incorrect header guard
1861 error_collector = ErrorCollector(self.assert_)
1862 cpp_style.process_file_data(file_path, 'h',
1869 error_collector.result_list().count(
1870 '#ifndef header guard has wrong style, please use: %s'
1871 ' [build/header_guard] [5]' % expected_guard),
1872 error_collector.result_list())
1875 error_collector.result_list().count(
1876 '#endif line should be "#endif // %s"'
1877 ' [build/header_guard] [5]' % expected_guard),
1878 error_collector.result_list())
1880 def test_build_printf_format(self):
1882 r'printf("\%%d", value);',
1883 '%, [, (, and { are undefined character escapes. Unescape them.'
1884 ' [build/printf_format] [3]')
1887 r'snprintf(buffer, sizeof(buffer), "\[%d", value);',
1888 '%, [, (, and { are undefined character escapes. Unescape them.'
1889 ' [build/printf_format] [3]')
1892 r'fprintf(file, "\(%d", value);',
1893 '%, [, (, and { are undefined character escapes. Unescape them.'
1894 ' [build/printf_format] [3]')
1897 r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);',
1898 '%, [, (, and { are undefined character escapes. Unescape them.'
1899 ' [build/printf_format] [3]')
1901 # Don't warn if double-slash precedes the symbol
1902 self.assert_lint(r'printf("\\%%%d", value);',
1905 def test_runtime_printf_format(self):
1907 r'fprintf(file, "%q", value);',
1908 '%q in format strings is deprecated. Use %ll instead.'
1909 ' [runtime/printf_format] [3]')
1912 r'aprintf(file, "The number is %12q", value);',
1913 '%q in format strings is deprecated. Use %ll instead.'
1914 ' [runtime/printf_format] [3]')
1917 r'printf(file, "The number is" "%-12q", value);',
1918 '%q in format strings is deprecated. Use %ll instead.'
1919 ' [runtime/printf_format] [3]')
1922 r'printf(file, "The number is" "%+12q", value);',
1923 '%q in format strings is deprecated. Use %ll instead.'
1924 ' [runtime/printf_format] [3]')
1927 r'printf(file, "The number is" "% 12q", value);',
1928 '%q in format strings is deprecated. Use %ll instead.'
1929 ' [runtime/printf_format] [3]')
1932 r'snprintf(file, "Never mix %d and %1$d parmaeters!", value);',
1933 '%N$ formats are unconventional. Try rewriting to avoid them.'
1934 ' [runtime/printf_format] [2]')
1936 def assert_lintLogCodeOnError(self, code, expected_message):
1937 # Special assert_lint which logs the input code on error.
1938 result = self.perform_single_line_lint(code, 'foo.cpp')
1939 if result != expected_message:
1940 self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"'
1941 % (code, result, expected_message))
1943 def test_build_storage_class(self):
1944 qualifiers = [None, 'const', 'volatile']
1945 signs = [None, 'signed', 'unsigned']
1946 types = ['void', 'char', 'int', 'float', 'double',
1947 'schar', 'int8', 'uint8', 'int16', 'uint16',
1948 'int32', 'uint32', 'int64', 'uint64']
1949 storage_classes = ['auto', 'extern', 'register', 'static', 'typedef']
1951 build_storage_class_error_message = (
1952 'Storage class (static, extern, typedef, etc) should be first.'
1953 ' [build/storage_class] [5]')
1955 # Some explicit cases. Legal in C++, deprecated in C99.
1956 self.assert_lint('const int static foo = 5;',
1957 build_storage_class_error_message)
1959 self.assert_lint('char static foo;',
1960 build_storage_class_error_message)
1962 self.assert_lint('double const static foo = 2.0;',
1963 build_storage_class_error_message)
1965 self.assert_lint('uint64 typedef unsigned_long_long;',
1966 build_storage_class_error_message)
1968 self.assert_lint('int register foo = 0;',
1969 build_storage_class_error_message)
1971 # Since there are a very large number of possibilities, randomly
1972 # construct declarations.
1973 # Make sure that the declaration is logged if there's an error.
1974 # Seed generator with an integer for absolute reproducibility.
1976 for unused_i in range(10):
1977 # Build up random list of non-storage-class declaration specs.
1978 other_decl_specs = [random.choice(qualifiers), random.choice(signs),
1979 random.choice(types)]
1981 other_decl_specs = filter(lambda x: x is not None, other_decl_specs)
1984 random.shuffle(other_decl_specs)
1986 # insert storage class after the first
1987 storage_class = random.choice(storage_classes)
1988 insertion_point = random.randint(1, len(other_decl_specs))
1989 decl_specs = (other_decl_specs[0:insertion_point]
1991 + other_decl_specs[insertion_point:])
1993 self.assert_lintLogCodeOnError(
1994 ' '.join(decl_specs) + ';',
1995 build_storage_class_error_message)
1997 # but no error if storage class is first
1998 self.assert_lintLogCodeOnError(
1999 storage_class + ' ' + ' '.join(other_decl_specs),
2002 def test_legal_copyright(self):
2003 legal_copyright_message = (
2004 'No copyright message found. '
2005 'You should have a line: "Copyright [year] <Copyright Owner>"'
2006 ' [legal/copyright] [5]')
2008 copyright_line = '// Copyright 2008 Google Inc. All Rights Reserved.'
2010 file_path = 'mydir/googleclient/foo.cpp'
2012 # There should be a copyright message in the first 10 lines
2013 error_collector = ErrorCollector(self.assert_)
2014 cpp_style.process_file_data(file_path, 'cpp', [], error_collector)
2017 error_collector.result_list().count(legal_copyright_message))
2019 error_collector = ErrorCollector(self.assert_)
2020 cpp_style.process_file_data(
2022 ['' for unused_i in range(10)] + [copyright_line],
2026 error_collector.result_list().count(legal_copyright_message))
2028 # Test that warning isn't issued if Copyright line appears early enough.
2029 error_collector = ErrorCollector(self.assert_)
2030 cpp_style.process_file_data(file_path, 'cpp', [copyright_line], error_collector)
2031 for message in error_collector.result_list():
2032 if message.find('legal/copyright') != -1:
2033 self.fail('Unexpected error: %s' % message)
2035 error_collector = ErrorCollector(self.assert_)
2036 cpp_style.process_file_data(
2038 ['' for unused_i in range(9)] + [copyright_line],
2040 for message in error_collector.result_list():
2041 if message.find('legal/copyright') != -1:
2042 self.fail('Unexpected error: %s' % message)
2044 def test_invalid_increment(self):
2045 self.assert_lint('*count++;',
2046 'Changing pointer instead of value (or unused value of '
2047 'operator*). [runtime/invalid_increment] [5]')
2049 class CleansedLinesTest(unittest.TestCase):
2050 def test_init(self):
2053 'Line 3 // Comment test',
2056 clean_lines = cpp_style.CleansedLines(lines)
2057 self.assertEquals(lines, clean_lines.raw_lines)
2058 self.assertEquals(4, clean_lines.num_lines())
2060 self.assertEquals(['Line 1',
2066 self.assertEquals(['Line 1',
2072 def test_init_empty(self):
2073 clean_lines = cpp_style.CleansedLines([])
2074 self.assertEquals([], clean_lines.raw_lines)
2075 self.assertEquals(0, clean_lines.num_lines())
2077 def test_collapse_strings(self):
2078 collapse = cpp_style.CleansedLines.collapse_strings
2079 self.assertEquals('""', collapse('""')) # "" (empty)
2080 self.assertEquals('"""', collapse('"""')) # """ (bad)
2081 self.assertEquals('""', collapse('"xyz"')) # "xyz" (string)
2082 self.assertEquals('""', collapse('"\\\""')) # "\"" (string)
2083 self.assertEquals('""', collapse('"\'"')) # "'" (string)
2084 self.assertEquals('"\"', collapse('"\"')) # "\" (bad)
2085 self.assertEquals('""', collapse('"\\\\"')) # "\\" (string)
2086 self.assertEquals('"', collapse('"\\\\\\"')) # "\\\" (bad)
2087 self.assertEquals('""', collapse('"\\\\\\\\"')) # "\\\\" (string)
2089 self.assertEquals('\'\'', collapse('\'\'')) # '' (empty)
2090 self.assertEquals('\'\'', collapse('\'a\'')) # 'a' (char)
2091 self.assertEquals('\'\'', collapse('\'\\\'\'')) # '\'' (char)
2092 self.assertEquals('\'', collapse('\'\\\'')) # '\' (bad)
2093 self.assertEquals('', collapse('\\012')) # '\012' (char)
2094 self.assertEquals('', collapse('\\xfF0')) # '\xfF0' (char)
2095 self.assertEquals('', collapse('\\n')) # '\n' (char)
2096 self.assertEquals('\#', collapse('\\#')) # '\#' (bad)
2098 self.assertEquals('StringReplace(body, "", "");',
2099 collapse('StringReplace(body, "\\\\", "\\\\\\\\");'))
2100 self.assertEquals('\'\' ""',
2101 collapse('\'"\' "foo"'))
2104 class OrderOfIncludesTest(CppStyleTestBase):
2106 self.include_state = cpp_style._IncludeState()
2108 # Cheat os.path.abspath called in FileInfo class.
2109 self.os_path_abspath_orig = os.path.abspath
2110 os.path.abspath = lambda value: value
2113 os.path.abspath = self.os_path_abspath_orig
2115 def test_try_drop_common_suffixes(self):
2116 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h'))
2117 self.assertEqual('foo/bar/foo',
2118 cpp_style._drop_common_suffixes('foo/bar/foo_inl.h'))
2119 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp'))
2120 self.assertEqual('foo/foo_unusualinternal',
2121 cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h'))
2122 self.assertEqual('',
2123 cpp_style._drop_common_suffixes('_test.cpp'))
2124 self.assertEqual('test',
2125 cpp_style._drop_common_suffixes('test.cpp'))
2128 class OrderOfIncludesTest(CppStyleTestBase):
2130 self.include_state = cpp_style._IncludeState()
2132 # Cheat os.path.abspath called in FileInfo class.
2133 self.os_path_abspath_orig = os.path.abspath
2134 os.path.abspath = lambda value: value
2137 os.path.abspath = self.os_path_abspath_orig
2139 def test_check_next_include_order__no_config(self):
2140 self.assertEqual('Header file should not contain WebCore config.h.',
2141 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, True))
2143 def test_check_next_include_order__no_self(self):
2144 self.assertEqual('Header file should not contain itself.',
2145 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, True))
2146 # Test actual code to make sure that header types are correctly assigned.
2147 self.assert_language_rules_check('Foo.h',
2148 '#include "Foo.h"\n',
2149 'Header file should not contain itself. Should be: alphabetically sorted.'
2150 ' [build/include_order] [4]')
2151 self.assert_language_rules_check('FooBar.h',
2152 '#include "Foo.h"\n',
2155 def test_check_next_include_order__likely_then_config(self):
2156 self.assertEqual('Found header this file implements before WebCore config.h.',
2157 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False))
2158 self.assertEqual('Found WebCore config.h after a header this file implements.',
2159 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False))
2161 def test_check_next_include_order__other_then_config(self):
2162 self.assertEqual('Found other header before WebCore config.h.',
2163 self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False))
2164 self.assertEqual('Found WebCore config.h after other header.',
2165 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False))
2167 def test_check_next_include_order__config_then_other_then_likely(self):
2168 self.assertEqual('', self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False))
2169 self.assertEqual('Found other header before a header this file implements.',
2170 self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False))
2171 self.assertEqual('Found header this file implements after other header.',
2172 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False))
2174 def test_check_alphabetical_include_order(self):
2175 self.assert_language_rules_check('foo.h',
2179 'Alphabetical sorting problem. [build/include_order] [4]')
2181 self.assert_language_rules_check('foo.h',
2187 self.assert_language_rules_check('foo.h',
2188 '#include <assert.h>\n'
2189 '#include "bar.h"\n',
2190 'Alphabetical sorting problem. [build/include_order] [4]')
2192 self.assert_language_rules_check('foo.h',
2193 '#include "bar.h"\n'
2194 '#include <assert.h>\n',
2197 def test_check_line_break_after_own_header(self):
2198 self.assert_language_rules_check('foo.cpp',
2199 '#include "config.h"\n'
2200 '#include "foo.h"\n'
2201 '#include "bar.h"\n',
2202 'You should add a blank line after implementation file\'s own header. [build/include_order] [4]')
2204 self.assert_language_rules_check('foo.cpp',
2205 '#include "config.h"\n'
2206 '#include "foo.h"\n'
2208 '#include "bar.h"\n',
2211 def test_check_preprocessor_in_include_section(self):
2212 self.assert_language_rules_check('foo.cpp',
2213 '#include "config.h"\n'
2214 '#include "foo.h"\n'
2217 '#include "baz.h"\n'
2219 '#include "foobar.h"\n'
2221 '#include "bar.h"\n', # No flag because previous is in preprocessor section
2224 self.assert_language_rules_check('foo.cpp',
2225 '#include "config.h"\n'
2226 '#include "foo.h"\n'
2229 '#include "baz.h"\n'
2231 '#include "bar.h"\n'
2232 '#include "a.h"\n', # Should still flag this.
2233 'Alphabetical sorting problem. [build/include_order] [4]')
2235 self.assert_language_rules_check('foo.cpp',
2236 '#include "config.h"\n'
2237 '#include "foo.h"\n'
2240 '#include "baz.h"\n'
2241 '#include "bar.h"\n' #Should still flag this
2243 'Alphabetical sorting problem. [build/include_order] [4]')
2245 self.assert_language_rules_check('foo.cpp',
2246 '#include "config.h"\n'
2247 '#include "foo.h"\n'
2250 '#include "baz.h"\n'
2253 '#include "foobar.h"\n'
2255 '#include "bar.h"\n'
2256 '#include "a.h"\n', # Should still flag this.
2257 'Alphabetical sorting problem. [build/include_order] [4]')
2259 # Check that after an already included error, the sorting rules still work.
2260 self.assert_language_rules_check('foo.cpp',
2261 '#include "config.h"\n'
2262 '#include "foo.h"\n'
2264 '#include "foo.h"\n'
2266 '"foo.h" already included at foo.cpp:1 [build/include] [4]')
2268 def test_check_wtf_includes(self):
2269 self.assert_language_rules_check('foo.cpp',
2270 '#include "config.h"\n'
2271 '#include "foo.h"\n'
2273 '#include <wtf/Assertions.h>\n',
2275 self.assert_language_rules_check('foo.cpp',
2276 '#include "config.h"\n'
2277 '#include "foo.h"\n'
2279 '#include "wtf/Assertions.h"\n',
2280 'wtf includes should be <wtf/file.h> instead of "wtf/file.h".'
2281 ' [build/include] [4]')
2283 def test_classify_include(self):
2284 classify_include = cpp_style._classify_include
2285 include_state = cpp_style._IncludeState()
2286 self.assertEqual(cpp_style._CONFIG_HEADER,
2287 classify_include('foo/foo.cpp',
2289 False, include_state))
2290 self.assertEqual(cpp_style._PRIMARY_HEADER,
2291 classify_include('foo/internal/foo.cpp',
2293 False, include_state))
2294 self.assertEqual(cpp_style._PRIMARY_HEADER,
2295 classify_include('foo/internal/foo.cpp',
2296 'foo/other/public/foo.h',
2297 False, include_state))
2298 self.assertEqual(cpp_style._OTHER_HEADER,
2299 classify_include('foo/internal/foo.cpp',
2300 'foo/other/public/foop.h',
2301 False, include_state))
2302 self.assertEqual(cpp_style._OTHER_HEADER,
2303 classify_include('foo/foo.cpp',
2305 True, include_state))
2306 self.assertEqual(cpp_style._PRIMARY_HEADER,
2307 classify_include('fooCustom.cpp',
2309 False, include_state))
2310 # Tricky example where both includes might be classified as primary.
2311 self.assert_language_rules_check('ScrollbarThemeWince.cpp',
2312 '#include "config.h"\n'
2313 '#include "ScrollbarThemeWince.h"\n'
2315 '#include "Scrollbar.h"\n',
2317 self.assert_language_rules_check('ScrollbarThemeWince.cpp',
2318 '#include "config.h"\n'
2319 '#include "Scrollbar.h"\n'
2321 '#include "ScrollbarThemeWince.h"\n',
2322 'Found header this file implements after a header this file implements.'
2323 ' Should be: config.h, primary header, blank line, and then alphabetically sorted.'
2324 ' [build/include_order] [4]')
2326 def test_try_drop_common_suffixes(self):
2327 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h'))
2328 self.assertEqual('foo/bar/foo',
2329 cpp_style._drop_common_suffixes('foo/bar/foo_inl.h'))
2330 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp'))
2331 self.assertEqual('foo/foo_unusualinternal',
2332 cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h'))
2333 self.assertEqual('',
2334 cpp_style._drop_common_suffixes('_test.cpp'))
2335 self.assertEqual('test',
2336 cpp_style._drop_common_suffixes('test.cpp'))
2337 self.assertEqual('test',
2338 cpp_style._drop_common_suffixes('test.cpp'))
2340 class CheckForFunctionLengthsTest(CppStyleTestBase):
2342 # Reducing these thresholds for the tests speeds up tests significantly.
2343 self.old_normal_trigger = cpp_style._FunctionState._NORMAL_TRIGGER
2344 self.old_test_trigger = cpp_style._FunctionState._TEST_TRIGGER
2346 cpp_style._FunctionState._NORMAL_TRIGGER = 10
2347 cpp_style._FunctionState._TEST_TRIGGER = 25
2350 cpp_style._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger
2351 cpp_style._FunctionState._TEST_TRIGGER = self.old_test_trigger
2353 def assert_function_lengths_check(self, code, expected_message):
2354 """Check warnings for long function bodies are as expected.
2357 code: C++ source code expected to generate a warning message.
2358 expected_message: Message expected to be generated by the C++ code.
2360 self.assertEquals(expected_message,
2361 self.perform_function_lengths_check(code))
2363 def trigger_lines(self, error_level):
2364 """Return number of lines needed to trigger a function length warning.
2367 error_level: --v setting for cpp_style.
2370 Number of lines needed to trigger a function length warning.
2372 return cpp_style._FunctionState._NORMAL_TRIGGER * 2 ** error_level
2374 def trigger_test_lines(self, error_level):
2375 """Return number of lines needed to trigger a test function length warning.
2378 error_level: --v setting for cpp_style.
2381 Number of lines needed to trigger a test function length warning.
2383 return cpp_style._FunctionState._TEST_TRIGGER * 2 ** error_level
2385 def assert_function_length_check_definition(self, lines, error_level):
2386 """Generate long function definition and check warnings are as expected.
2389 lines: Number of lines to generate.
2390 error_level: --v setting for cpp_style.
2392 trigger_level = self.trigger_lines(cpp_style._verbose_level())
2393 self.assert_function_lengths_check(
2394 'void test(int x)' + self.function_body(lines),
2395 ('Small and focused functions are preferred: '
2396 'test() has %d non-comment lines '
2397 '(error triggered by exceeding %d lines).'
2398 ' [readability/fn_size] [%d]'
2399 % (lines, trigger_level, error_level)))
2401 def assert_function_length_check_definition_ok(self, lines):
2402 """Generate shorter function definition and check no warning is produced.
2405 lines: Number of lines to generate.
2407 self.assert_function_lengths_check(
2408 'void test(int x)' + self.function_body(lines),
2411 def assert_function_length_check_at_error_level(self, error_level):
2412 """Generate and check function at the trigger level for --v setting.
2415 error_level: --v setting for cpp_style.
2417 self.assert_function_length_check_definition(self.trigger_lines(error_level),
2420 def assert_function_length_check_below_error_level(self, error_level):
2421 """Generate and check function just below the trigger level for --v setting.
2424 error_level: --v setting for cpp_style.
2426 self.assert_function_length_check_definition(self.trigger_lines(error_level) - 1,
2429 def assert_function_length_check_above_error_level(self, error_level):
2430 """Generate and check function just above the trigger level for --v setting.
2433 error_level: --v setting for cpp_style.
2435 self.assert_function_length_check_definition(self.trigger_lines(error_level) + 1,
2438 def function_body(self, number_of_lines):
2439 return ' {\n' + ' this_is_just_a_test();\n' * number_of_lines + '}'
2441 def function_body_with_blank_lines(self, number_of_lines):
2442 return ' {\n' + ' this_is_just_a_test();\n\n' * number_of_lines + '}'
2444 def function_body_with_no_lints(self, number_of_lines):
2445 return ' {\n' + ' this_is_just_a_test(); // NOLINT\n' * number_of_lines + '}'
2447 # Test line length checks.
2448 def test_function_length_check_declaration(self):
2449 self.assert_function_lengths_check(
2450 'void test();', # Not a function definition
2453 def test_function_length_check_declaration_with_block_following(self):
2454 self.assert_function_lengths_check(
2456 + self.function_body(66)), # Not a function definition
2459 def test_function_length_check_class_definition(self):
2460 self.assert_function_lengths_check( # Not a function definition
2461 'class Test' + self.function_body(66) + ';',
2464 def test_function_length_check_trivial(self):
2465 self.assert_function_lengths_check(
2466 'void test() {}', # Not counted
2469 def test_function_length_check_empty(self):
2470 self.assert_function_lengths_check(
2474 def test_function_length_check_definition_below_severity0(self):
2475 old_verbosity = cpp_style._set_verbose_level(0)
2476 self.assert_function_length_check_definition_ok(self.trigger_lines(0) - 1)
2477 cpp_style._set_verbose_level(old_verbosity)
2479 def test_function_length_check_definition_at_severity0(self):
2480 old_verbosity = cpp_style._set_verbose_level(0)
2481 self.assert_function_length_check_definition_ok(self.trigger_lines(0))
2482 cpp_style._set_verbose_level(old_verbosity)
2484 def test_function_length_check_definition_above_severity0(self):
2485 old_verbosity = cpp_style._set_verbose_level(0)
2486 self.assert_function_length_check_above_error_level(0)
2487 cpp_style._set_verbose_level(old_verbosity)
2489 def test_function_length_check_definition_below_severity1v0(self):
2490 old_verbosity = cpp_style._set_verbose_level(0)
2491 self.assert_function_length_check_below_error_level(1)
2492 cpp_style._set_verbose_level(old_verbosity)
2494 def test_function_length_check_definition_at_severity1v0(self):
2495 old_verbosity = cpp_style._set_verbose_level(0)
2496 self.assert_function_length_check_at_error_level(1)
2497 cpp_style._set_verbose_level(old_verbosity)
2499 def test_function_length_check_definition_below_severity1(self):
2500 self.assert_function_length_check_definition_ok(self.trigger_lines(1) - 1)
2502 def test_function_length_check_definition_at_severity1(self):
2503 self.assert_function_length_check_definition_ok(self.trigger_lines(1))
2505 def test_function_length_check_definition_above_severity1(self):
2506 self.assert_function_length_check_above_error_level(1)
2508 def test_function_length_check_definition_severity1_plus_blanks(self):
2510 error_lines = self.trigger_lines(error_level) + 1
2511 trigger_level = self.trigger_lines(cpp_style._verbose_level())
2512 self.assert_function_lengths_check(
2513 'void test_blanks(int x)' + self.function_body(error_lines),
2514 ('Small and focused functions are preferred: '
2515 'test_blanks() has %d non-comment lines '
2516 '(error triggered by exceeding %d lines).'
2517 ' [readability/fn_size] [%d]')
2518 % (error_lines, trigger_level, error_level))
2520 def test_function_length_check_complex_definition_severity1(self):
2522 error_lines = self.trigger_lines(error_level) + 1
2523 trigger_level = self.trigger_lines(cpp_style._verbose_level())
2524 self.assert_function_lengths_check(
2525 ('my_namespace::my_other_namespace::MyVeryLongTypeName*\n'
2526 'my_namespace::my_other_namespace::MyFunction(int arg1, char* arg2)'
2527 + self.function_body(error_lines)),
2528 ('Small and focused functions are preferred: '
2529 'my_namespace::my_other_namespace::MyFunction()'
2530 ' has %d non-comment lines '
2531 '(error triggered by exceeding %d lines).'
2532 ' [readability/fn_size] [%d]')
2533 % (error_lines, trigger_level, error_level))
2535 def test_function_length_check_definition_severity1_for_test(self):
2537 error_lines = self.trigger_test_lines(error_level) + 1
2538 trigger_level = self.trigger_test_lines(cpp_style._verbose_level())
2539 self.assert_function_lengths_check(
2540 'TEST_F(Test, Mutator)' + self.function_body(error_lines),
2541 ('Small and focused functions are preferred: '
2542 'TEST_F(Test, Mutator) has %d non-comment lines '
2543 '(error triggered by exceeding %d lines).'
2544 ' [readability/fn_size] [%d]')
2545 % (error_lines, trigger_level, error_level))
2547 def test_function_length_check_definition_severity1_for_split_line_test(self):
2549 error_lines = self.trigger_test_lines(error_level) + 1
2550 trigger_level = self.trigger_test_lines(cpp_style._verbose_level())
2551 self.assert_function_lengths_check(
2552 ('TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,\n'
2553 ' FixGoogleUpdate_AllValues_MachineApp)' # note: 4 spaces
2554 + self.function_body(error_lines)),
2555 ('Small and focused functions are preferred: '
2556 'TEST_F(GoogleUpdateRecoveryRegistryProtectedTest, ' # 1 space
2557 'FixGoogleUpdate_AllValues_MachineApp) has %d non-comment lines '
2558 '(error triggered by exceeding %d lines).'
2559 ' [readability/fn_size] [%d]')
2560 % (error_lines+1, trigger_level, error_level))
2562 def test_function_length_check_definition_severity1_for_bad_test_doesnt_break(self):
2564 error_lines = self.trigger_test_lines(error_level) + 1
2565 trigger_level = self.trigger_test_lines(cpp_style._verbose_level())
2566 self.assert_function_lengths_check(
2568 + self.function_body(error_lines)),
2569 ('Small and focused functions are preferred: '
2570 'TEST_F has %d non-comment lines '
2571 '(error triggered by exceeding %d lines).'
2572 ' [readability/fn_size] [%d]')
2573 % (error_lines, trigger_level, error_level))
2575 def test_function_length_check_definition_severity1_with_embedded_no_lints(self):
2577 error_lines = self.trigger_lines(error_level) + 1
2578 trigger_level = self.trigger_lines(cpp_style._verbose_level())
2579 self.assert_function_lengths_check(
2580 'void test(int x)' + self.function_body_with_no_lints(error_lines),
2581 ('Small and focused functions are preferred: '
2582 'test() has %d non-comment lines '
2583 '(error triggered by exceeding %d lines).'
2584 ' [readability/fn_size] [%d]')
2585 % (error_lines, trigger_level, error_level))
2587 def test_function_length_check_definition_severity1_with_no_lint(self):
2588 self.assert_function_lengths_check(
2589 ('void test(int x)' + self.function_body(self.trigger_lines(1))
2590 + ' // NOLINT -- long function'),
2593 def test_function_length_check_definition_below_severity2(self):
2594 self.assert_function_length_check_below_error_level(2)
2596 def test_function_length_check_definition_severity2(self):
2597 self.assert_function_length_check_at_error_level(2)
2599 def test_function_length_check_definition_above_severity2(self):
2600 self.assert_function_length_check_above_error_level(2)
2602 def test_function_length_check_definition_below_severity3(self):
2603 self.assert_function_length_check_below_error_level(3)
2605 def test_function_length_check_definition_severity3(self):
2606 self.assert_function_length_check_at_error_level(3)
2608 def test_function_length_check_definition_above_severity3(self):
2609 self.assert_function_length_check_above_error_level(3)
2611 def test_function_length_check_definition_below_severity4(self):
2612 self.assert_function_length_check_below_error_level(4)
2614 def test_function_length_check_definition_severity4(self):
2615 self.assert_function_length_check_at_error_level(4)
2617 def test_function_length_check_definition_above_severity4(self):
2618 self.assert_function_length_check_above_error_level(4)
2620 def test_function_length_check_definition_below_severity5(self):
2621 self.assert_function_length_check_below_error_level(5)
2623 def test_function_length_check_definition_at_severity5(self):
2624 self.assert_function_length_check_at_error_level(5)
2626 def test_function_length_check_definition_above_severity5(self):
2627 self.assert_function_length_check_above_error_level(5)
2629 def test_function_length_check_definition_huge_lines(self):
2631 self.assert_function_length_check_definition(self.trigger_lines(10), 5)
2633 def test_function_length_not_determinable(self):
2634 # Macro invocation without terminating semicolon.
2635 self.assert_function_lengths_check(
2639 # Macro with underscores
2640 self.assert_function_lengths_check(
2641 'MACRO_WITH_UNDERSCORES(arg1, arg2, arg3)',
2644 self.assert_function_lengths_check(
2646 'Lint failed to find start of function body.'
2647 ' [readability/fn_size] [5]')
2650 class NoNonVirtualDestructorsTest(CppStyleTestBase):
2652 def test_no_error(self):
2653 self.assert_multi_line_lint(
2660 self.assert_multi_line_lint(
2662 virtual inline ~Foo();
2667 self.assert_multi_line_lint(
2669 inline virtual ~Foo();
2674 self.assert_multi_line_lint(
2680 self.assert_multi_line_lint(
2681 'class Foo { void foo(); };',
2682 'More than one command on the same line [whitespace/newline] [4]')
2684 self.assert_multi_line_lint(
2685 '''class Qualified::Goo : public Foo {
2690 self.assert_multi_line_lint(
2696 'Labels should always be indented at least one space. If this is a '
2697 'member-initializer list in a constructor, the colon should be on the '
2698 'line after the definition header. [whitespace/labels] [4]')
2700 def test_no_destructor_when_virtual_needed(self):
2701 self.assert_multi_line_lint_re(
2705 'The class Foo probably needs a virtual destructor')
2707 def test_destructor_non_virtual_when_virtual_needed(self):
2708 self.assert_multi_line_lint_re(
2713 'The class Foo probably needs a virtual destructor')
2715 def test_no_warn_when_derived(self):
2716 self.assert_multi_line_lint(
2717 '''class Foo : public Goo {
2722 def test_internal_braces(self):
2723 self.assert_multi_line_lint_re(
2730 'The class Foo probably needs a virtual destructor')
2732 def test_inner_class_needs_virtual_destructor(self):
2733 self.assert_multi_line_lint_re(
2739 'The class Goo probably needs a virtual destructor')
2741 def test_outer_class_needs_virtual_destructor(self):
2742 self.assert_multi_line_lint_re(
2748 'The class Foo probably needs a virtual destructor')
2750 def test_qualified_class_needs_virtual_destructor(self):
2751 self.assert_multi_line_lint_re(
2752 '''class Qualified::Foo {
2755 'The class Qualified::Foo probably needs a virtual destructor')
2757 def test_multi_line_declaration_no_error(self):
2758 self.assert_multi_line_lint_re(
2765 def test_multi_line_declaration_with_error(self):
2766 self.assert_multi_line_lint(
2771 ['This { should be at the end of the previous line '
2772 '[whitespace/braces] [4]',
2773 'The class Foo probably needs a virtual destructor due to having '
2774 'virtual method(s), one declared at line 2. [runtime/virtual] [4]'])
2777 class CppStyleStateTest(unittest.TestCase):
2778 def test_error_count(self):
2779 self.assertEquals(0, cpp_style.error_count())
2780 cpp_style._cpp_style_state.increment_error_count()
2781 cpp_style._cpp_style_state.increment_error_count()
2782 self.assertEquals(2, cpp_style.error_count())
2783 cpp_style._cpp_style_state.reset_error_count()
2784 self.assertEquals(0, cpp_style.error_count())
2787 class WebKitStyleTest(CppStyleTestBase):
2789 # for http://webkit.org/coding/coding-style.html
2790 def test_indentation(self):
2791 # 1. Use spaces, not tabs. Tabs should only appear in files that
2792 # require them for semantic meaning, like Makefiles.
2793 self.assert_multi_line_lint(
2798 self.assert_multi_line_lint(
2802 'Tab found; better to use spaces [whitespace/tab] [1]')
2804 # 2. The indent size is 4 spaces.
2805 self.assert_multi_line_lint(
2810 self.assert_multi_line_lint(
2814 'Weird number of spaces at line-start. Are you using a 4-space indent? [whitespace/indent] [3]')
2815 # FIXME: No tests for 8-spaces.
2817 # 3. In a header, code inside a namespace should not be indented.
2818 self.assert_multi_line_lint(
2819 'namespace WebCore {\n\n'
2820 'class Document {\n'
2821 ' int myVariable;\n'
2826 self.assert_multi_line_lint(
2827 'namespace OuterNamespace {\n'
2828 ' namespace InnerNamespace {\n'
2829 ' class Document {\n'
2833 ['Code inside a namespace should not be indented. [whitespace/indent] [4]', 'namespace should never be indented. [whitespace/indent] [4]'],
2835 self.assert_multi_line_lint(
2836 'namespace WebCore {\n'
2838 ' class Document {\n'
2842 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
2844 self.assert_multi_line_lint(
2845 'namespace WebCore {\n'
2846 'class Document {\n'
2852 # 4. In an implementation file (files with the extension .cpp, .c
2853 # or .mm), code inside a namespace should not be indented.
2854 self.assert_multi_line_lint(
2855 'namespace WebCore {\n\n'
2864 self.assert_multi_line_lint(
2865 'namespace OuterNamespace {\n'
2866 'namespace InnerNamespace {\n'
2867 'Document::Foo() { }\n'
2871 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
2873 self.assert_multi_line_lint(
2874 'namespace OuterNamespace {\n'
2875 'namespace InnerNamespace {\n'
2876 'Document::Foo() { }\n'
2880 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
2882 self.assert_multi_line_lint(
2883 'namespace WebCore {\n\n'
2884 ' const char* foo = "start:;"\n'
2887 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
2889 self.assert_multi_line_lint(
2890 'namespace WebCore {\n\n'
2891 'const char* foo(void* a = ";", // ;\n'
2895 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
2897 self.assert_multi_line_lint(
2898 'namespace WebCore {\n\n'
2899 'const char* foo[] = {\n'
2900 ' "void* b);", // ;\n'