mirror of
https://github.com/tiennm99/styleguide.git
synced 2026-08-23 20:26:48 +00:00
Update cpplint.py to #122:
- Don't check quoted filenames with irrelevant tests.
- Make cpplint accept 'for (foo; bar; ) {}'.
- Work with temporary files generated by Emacs flymake-mode.
- Don't warn on "/// Doxygen comments."
- Check the use of DCHECK in the same way we check the use of CHECK.
- Properly handle relative file paths with IncludeWhatYouUse checking.
- Start checking for IncludeWhatYouUse in a limited way in .cc files.
This commit is contained in:
+142
-2
@@ -13,6 +13,9 @@
|
||||
|
||||
"""Unit test for cpplint.py."""
|
||||
|
||||
# TODO(unknown): Add a good test that tests UpdateIncludeState.
|
||||
|
||||
import codecs
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
@@ -72,6 +75,18 @@ class ErrorCollector:
|
||||
self._errors = self._errors[0:index] + self._errors[(index + 1):]
|
||||
break
|
||||
|
||||
|
||||
# This class is a lame mock of codecs. We do not verify filename, mode, or
|
||||
# encoding, but for the current use case it is not needed.
|
||||
class MockIo:
|
||||
def __init__(self, mock_file):
|
||||
self.mock_file = mock_file
|
||||
|
||||
def open(self, unused_filename, unused_mode, unused_encoding, _): # NOLINT
|
||||
# (lint doesn't like open as a method name)
|
||||
return self.mock_file
|
||||
|
||||
|
||||
class CpplintTestBase(unittest.TestCase):
|
||||
"""Provides some useful helper functions for cpplint tests."""
|
||||
|
||||
@@ -147,7 +162,7 @@ class CpplintTestBase(unittest.TestCase):
|
||||
function_state, error_collector)
|
||||
return error_collector.Results()
|
||||
|
||||
def PerformIncludeWhatYouUse(self, code, filename='foo.h'):
|
||||
def PerformIncludeWhatYouUse(self, code, filename='foo.h', io=codecs):
|
||||
# First, build up the include state.
|
||||
error_collector = ErrorCollector(self.assert_)
|
||||
include_state = cpplint._IncludeState()
|
||||
@@ -163,7 +178,7 @@ class CpplintTestBase(unittest.TestCase):
|
||||
|
||||
# Second, look for missing includes.
|
||||
cpplint.CheckForIncludeWhatYouUse(filename, lines, include_state,
|
||||
error_collector)
|
||||
error_collector, io)
|
||||
return error_collector.Results()
|
||||
|
||||
# Perform lint and compare the error message with "expected_message".
|
||||
@@ -430,6 +445,15 @@ class CpplintTest(CpplintTestBase):
|
||||
'Using sizeof(type). Use sizeof(varname) instead if possible'
|
||||
' [runtime/sizeof] [1]')
|
||||
|
||||
# Test false errors that happened with some include file names
|
||||
def testIncludeFilenameFalseError(self):
|
||||
self.TestLint(
|
||||
'#include "foo/long-foo.h"',
|
||||
'')
|
||||
self.TestLint(
|
||||
'#include "foo/sprintf.h"',
|
||||
'')
|
||||
|
||||
# Test typedef cases. There was a bug that cpplint misidentified
|
||||
# typedef for pointer to function as C-style cast and produced
|
||||
# false-positive error messages.
|
||||
@@ -581,6 +605,75 @@ class CpplintTest(CpplintTestBase):
|
||||
''',
|
||||
'')
|
||||
|
||||
# Test the UpdateIncludeState code path.
|
||||
mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"']
|
||||
message = self.PerformIncludeWhatYouUse(
|
||||
'#include "blah/a.h"',
|
||||
filename='blah/a.cc',
|
||||
io=MockIo(mock_header_contents))
|
||||
self.assertEquals(message, '')
|
||||
|
||||
mock_header_contents = ['#include <set>']
|
||||
message = self.PerformIncludeWhatYouUse(
|
||||
'''#include "blah/a.h"
|
||||
std::set<int> foo;''',
|
||||
filename='blah/a.cc',
|
||||
io=MockIo(mock_header_contents))
|
||||
self.assertEquals(message, '')
|
||||
|
||||
# Make sure we can find the correct header file if the cc file seems to be
|
||||
# a temporary file generated by Emacs's flymake.
|
||||
mock_header_contents = ['']
|
||||
message = self.PerformIncludeWhatYouUse(
|
||||
'''#include "blah/a.h"
|
||||
std::set<int> foo;''',
|
||||
filename='blah/a_flymake.cc',
|
||||
io=MockIo(mock_header_contents))
|
||||
self.assertEquals(message, 'Add #include <set> for set<> '
|
||||
'[build/include_what_you_use] [4]')
|
||||
|
||||
# If there's just a cc and the header can't be found then it's ok.
|
||||
message = self.PerformIncludeWhatYouUse(
|
||||
'''#include "blah/a.h"
|
||||
std::set<int> foo;''',
|
||||
filename='blah/a.cc')
|
||||
self.assertEquals(message, '')
|
||||
|
||||
# Make sure we find the headers with relative paths.
|
||||
mock_header_contents = ['']
|
||||
message = self.PerformIncludeWhatYouUse(
|
||||
'''#include "%s/a.h"
|
||||
std::set<int> foo;''' % os.path.basename(os.getcwd()),
|
||||
filename='a.cc',
|
||||
io=MockIo(mock_header_contents))
|
||||
self.assertEquals(message, 'Add #include <set> for set<> '
|
||||
'[build/include_what_you_use] [4]')
|
||||
|
||||
def testFilesBelongToSameModule(self):
|
||||
f = cpplint.FilesBelongToSameModule
|
||||
self.assertEquals((True, ''), f('a.cc', 'a.h'))
|
||||
self.assertEquals((True, ''), f('base/google.cc', 'base/google.h'))
|
||||
self.assertEquals((True, ''), f('base/google_test.cc', 'base/google.h'))
|
||||
self.assertEquals((True, ''),
|
||||
f('base/google_unittest.cc', 'base/google.h'))
|
||||
self.assertEquals((True, ''),
|
||||
f('base/internal/google_unittest.cc',
|
||||
'base/public/google.h'))
|
||||
self.assertEquals((True, 'xxx/yyy/'),
|
||||
f('xxx/yyy/base/internal/google_unittest.cc',
|
||||
'base/public/google.h'))
|
||||
self.assertEquals((True, 'xxx/yyy/'),
|
||||
f('xxx/yyy/base/google_unittest.cc',
|
||||
'base/public/google.h'))
|
||||
self.assertEquals((True, ''),
|
||||
f('base/google_unittest.cc', 'base/google-inl.h'))
|
||||
self.assertEquals((True, '/home/build/google3/'),
|
||||
f('/home/build/google3/base/google.cc', 'base/google.h'))
|
||||
|
||||
self.assertEquals((False, ''),
|
||||
f('/home/build/google3/base/google.cc', 'basu/google.h'))
|
||||
self.assertEquals((False, ''), f('a.cc', 'b.h'))
|
||||
|
||||
def testCleanseLine(self):
|
||||
self.assertEquals('int foo = 0; ',
|
||||
cpplint.CleanseComments('int foo = 0; // danger!'))
|
||||
@@ -962,6 +1055,25 @@ class CpplintTest(CpplintTestBase):
|
||||
'Consider using CHECK_LT instead of CHECK(a < b)'
|
||||
' [readability/check] [2]')
|
||||
|
||||
self.TestLint('DCHECK(x == 42)',
|
||||
'Consider using DCHECK_EQ instead of DCHECK(a == b)'
|
||||
' [readability/check] [2]')
|
||||
self.TestLint('DCHECK(x != 42)',
|
||||
'Consider using DCHECK_NE instead of DCHECK(a != b)'
|
||||
' [readability/check] [2]')
|
||||
self.TestLint('DCHECK(x >= 42)',
|
||||
'Consider using DCHECK_GE instead of DCHECK(a >= b)'
|
||||
' [readability/check] [2]')
|
||||
self.TestLint('DCHECK(x > 42)',
|
||||
'Consider using DCHECK_GT instead of DCHECK(a > b)'
|
||||
' [readability/check] [2]')
|
||||
self.TestLint('DCHECK(x <= 42)',
|
||||
'Consider using DCHECK_LE instead of DCHECK(a <= b)'
|
||||
' [readability/check] [2]')
|
||||
self.TestLint('DCHECK(x < 42)',
|
||||
'Consider using DCHECK_LT instead of DCHECK(a < b)'
|
||||
' [readability/check] [2]')
|
||||
|
||||
self.TestLint(
|
||||
'EXPECT_TRUE("42" == x)',
|
||||
'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)'
|
||||
@@ -1088,9 +1200,12 @@ class CpplintTest(CpplintTestBase):
|
||||
' [whitespace/parens] [5]')
|
||||
self.TestLint('switch ( foo) {', 'Mismatching spaces inside () in switch'
|
||||
' [whitespace/parens] [5]')
|
||||
self.TestLint('for (foo; ba; bar ) {', 'Mismatching spaces inside () in for'
|
||||
' [whitespace/parens] [5]')
|
||||
self.TestLint('for (; foo; bar) {', '')
|
||||
self.TestLint('for ( ; foo; bar) {', '')
|
||||
self.TestLint('for ( ; foo; bar ) {', '')
|
||||
self.TestLint('for (foo; bar; ) {', '')
|
||||
self.TestLint('while ( foo ) {', 'Should have zero or one spaces inside'
|
||||
' ( and ) in while [whitespace/parens] [5]')
|
||||
|
||||
@@ -1285,6 +1400,13 @@ class CpplintTest(CpplintTestBase):
|
||||
self.TestLint('//x', 'Should have a space between // and comment'
|
||||
' [whitespace/comments] [4]')
|
||||
self.TestLint('// x', '')
|
||||
self.TestLint('//----', '')
|
||||
self.TestLint('//====', '')
|
||||
self.TestLint('//////', '')
|
||||
self.TestLint('////// x', '')
|
||||
self.TestLint('/// x', '')
|
||||
self.TestLint('////x', 'Should have a space between // and comment'
|
||||
' [whitespace/comments] [4]')
|
||||
|
||||
# Test a line preceded by empty or comment lines. There was a bug
|
||||
# that caused it to print the same warning N times if the erroneous
|
||||
@@ -1529,6 +1651,24 @@ class CpplintTest(CpplintTestBase):
|
||||
finally:
|
||||
cpplint._cpplint_state.filters = old_filters
|
||||
|
||||
def testDefaultFilter(self):
|
||||
default_filters = cpplint._DEFAULT_FILTERS
|
||||
old_filters = cpplint._cpplint_state.filters
|
||||
cpplint._DEFAULT_FILTERS = [ '-whitespace' ]
|
||||
try:
|
||||
# Reset filters
|
||||
cpplint._cpplint_state.SetFilters('')
|
||||
self.TestLint('// Hello there ', '')
|
||||
cpplint._cpplint_state.SetFilters('+whitespace/end_of_line')
|
||||
self.TestLint(
|
||||
'// Hello there ',
|
||||
'Line ends in whitespace. Consider deleting these extra spaces.'
|
||||
' [whitespace/end_of_line] [4]')
|
||||
self.TestLint(' weird opening space', '')
|
||||
finally:
|
||||
cpplint._cpplint_state.filters = old_filters
|
||||
cpplint._DEFAULT_FILTERS = default_filters
|
||||
|
||||
def testUnnamedNamespacesInHeaders(self):
|
||||
self.TestLanguageRulesCheck(
|
||||
'foo.h', 'namespace {',
|
||||
|
||||
Reference in New Issue
Block a user