PageRenderTime 69ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 1ms

/hooks/webkitpy/style/checkers/cpp_unittest.py

https://github.com/hwti/LunaSysMgr
Python | 4632 lines | 4547 code | 24 blank | 61 comment | 115 complexity | 7b51637e6df01dfbae05da2e913ffe63 MD5 | raw file
  1. #!/usr/bin/python
  2. # -*- coding: utf-8; -*-
  3. #
  4. # Copyright (C) 2011 Google Inc. All rights reserved.
  5. # Copyright (C) 2009 Torch Mobile Inc.
  6. # Copyright (C) 2009 Apple Inc. All rights reserved.
  7. # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
  8. #
  9. # Redistribution and use in source and binary forms, with or without
  10. # modification, are permitted provided that the following conditions are
  11. # met:
  12. #
  13. # * Redistributions of source code must retain the above copyright
  14. # notice, this list of conditions and the following disclaimer.
  15. # * Redistributions in binary form must reproduce the above
  16. # copyright notice, this list of conditions and the following disclaimer
  17. # in the documentation and/or other materials provided with the
  18. # distribution.
  19. # * Neither the name of Google Inc. nor the names of its
  20. # contributors may be used to endorse or promote products derived from
  21. # this software without specific prior written permission.
  22. #
  23. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  24. # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  25. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  26. # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  27. # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  28. # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  29. # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  30. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  31. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  32. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  33. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34. """Unit test for cpp_style.py."""
  35. # FIXME: Add a good test that tests UpdateIncludeState.
  36. import codecs
  37. import os
  38. import random
  39. import re
  40. import unittest
  41. import cpp as cpp_style
  42. from cpp import CppChecker
  43. from ..filter import FilterConfiguration
  44. # This class works as an error collector and replaces cpp_style.Error
  45. # function for the unit tests. We also verify each category we see
  46. # is in STYLE_CATEGORIES, to help keep that list up to date.
  47. class ErrorCollector:
  48. _all_style_categories = CppChecker.categories
  49. # This is a list including all categories seen in any unit test.
  50. _seen_style_categories = {}
  51. def __init__(self, assert_fn, filter=None):
  52. """assert_fn: a function to call when we notice a problem.
  53. filter: filters the errors that we are concerned about."""
  54. self._assert_fn = assert_fn
  55. self._errors = []
  56. if not filter:
  57. filter = FilterConfiguration()
  58. self._filter = filter
  59. def __call__(self, unused_linenum, category, confidence, message):
  60. self._assert_fn(category in self._all_style_categories,
  61. 'Message "%s" has category "%s",'
  62. ' which is not in STYLE_CATEGORIES' % (message, category))
  63. if self._filter.should_check(category, ""):
  64. self._seen_style_categories[category] = 1
  65. self._errors.append('%s [%s] [%d]' % (message, category, confidence))
  66. def results(self):
  67. if len(self._errors) < 2:
  68. return ''.join(self._errors) # Most tests expect to have a string.
  69. else:
  70. return self._errors # Let's give a list if there is more than one.
  71. def result_list(self):
  72. return self._errors
  73. def verify_all_categories_are_seen(self):
  74. """Fails if there's a category in _all_style_categories - _seen_style_categories.
  75. This should only be called after all tests are run, so
  76. _seen_style_categories has had a chance to fully populate. Since
  77. this isn't called from within the normal unittest framework, we
  78. can't use the normal unittest assert macros. Instead we just exit
  79. when we see an error. Good thing this test is always run last!
  80. """
  81. for category in self._all_style_categories:
  82. if category not in self._seen_style_categories:
  83. import sys
  84. sys.exit('FATAL ERROR: There are no tests for category "%s"' % category)
  85. # This class is a lame mock of codecs. We do not verify filename, mode, or
  86. # encoding, but for the current use case it is not needed.
  87. class MockIo:
  88. def __init__(self, mock_file):
  89. self.mock_file = mock_file
  90. def open(self, unused_filename, unused_mode, unused_encoding, _): # NOLINT
  91. # (lint doesn't like open as a method name)
  92. return self.mock_file
  93. class CppFunctionsTest(unittest.TestCase):
  94. """Supports testing functions that do not need CppStyleTestBase."""
  95. def test_convert_to_lower_with_underscores(self):
  96. self.assertEquals(cpp_style._convert_to_lower_with_underscores('ABC'), 'abc')
  97. self.assertEquals(cpp_style._convert_to_lower_with_underscores('aB'), 'a_b')
  98. self.assertEquals(cpp_style._convert_to_lower_with_underscores('isAName'), 'is_a_name')
  99. self.assertEquals(cpp_style._convert_to_lower_with_underscores('AnotherTest'), 'another_test')
  100. self.assertEquals(cpp_style._convert_to_lower_with_underscores('PassRefPtr<MyClass>'), 'pass_ref_ptr<my_class>')
  101. self.assertEquals(cpp_style._convert_to_lower_with_underscores('_ABC'), '_abc')
  102. def test_create_acronym(self):
  103. self.assertEquals(cpp_style._create_acronym('ABC'), 'ABC')
  104. self.assertEquals(cpp_style._create_acronym('IsAName'), 'IAN')
  105. self.assertEquals(cpp_style._create_acronym('PassRefPtr<MyClass>'), 'PRP<MC>')
  106. def test_is_c_or_objective_c(self):
  107. clean_lines = cpp_style.CleansedLines([''])
  108. clean_objc_lines = cpp_style.CleansedLines(['#import "header.h"'])
  109. self.assertTrue(cpp_style._FileState(clean_lines, 'c').is_c_or_objective_c())
  110. self.assertTrue(cpp_style._FileState(clean_lines, 'm').is_c_or_objective_c())
  111. self.assertFalse(cpp_style._FileState(clean_lines, 'cpp').is_c_or_objective_c())
  112. self.assertFalse(cpp_style._FileState(clean_lines, 'cc').is_c_or_objective_c())
  113. self.assertFalse(cpp_style._FileState(clean_lines, 'h').is_c_or_objective_c())
  114. self.assertTrue(cpp_style._FileState(clean_objc_lines, 'h').is_c_or_objective_c())
  115. def test_parameter(self):
  116. # Test type.
  117. parameter = cpp_style.Parameter('ExceptionCode', 13, 1)
  118. self.assertEquals(parameter.type, 'ExceptionCode')
  119. self.assertEquals(parameter.name, '')
  120. self.assertEquals(parameter.row, 1)
  121. # Test type and name.
  122. parameter = cpp_style.Parameter('PassRefPtr<MyClass> parent', 19, 1)
  123. self.assertEquals(parameter.type, 'PassRefPtr<MyClass>')
  124. self.assertEquals(parameter.name, 'parent')
  125. self.assertEquals(parameter.row, 1)
  126. # Test type, no name, with default value.
  127. parameter = cpp_style.Parameter('MyClass = 0', 7, 0)
  128. self.assertEquals(parameter.type, 'MyClass')
  129. self.assertEquals(parameter.name, '')
  130. self.assertEquals(parameter.row, 0)
  131. # Test type, name, and default value.
  132. parameter = cpp_style.Parameter('MyClass a = 0', 7, 0)
  133. self.assertEquals(parameter.type, 'MyClass')
  134. self.assertEquals(parameter.name, 'a')
  135. self.assertEquals(parameter.row, 0)
  136. def test_single_line_view(self):
  137. start_position = cpp_style.Position(row=1, column=1)
  138. end_position = cpp_style.Position(row=3, column=1)
  139. single_line_view = cpp_style.SingleLineView(['0', 'abcde', 'fgh', 'i'], start_position, end_position)
  140. self.assertEquals(single_line_view.single_line, 'bcde fgh i')
  141. self.assertEquals(single_line_view.convert_column_to_row(0), 1)
  142. self.assertEquals(single_line_view.convert_column_to_row(4), 1)
  143. self.assertEquals(single_line_view.convert_column_to_row(5), 2)
  144. self.assertEquals(single_line_view.convert_column_to_row(8), 2)
  145. self.assertEquals(single_line_view.convert_column_to_row(9), 3)
  146. self.assertEquals(single_line_view.convert_column_to_row(100), 3)
  147. start_position = cpp_style.Position(row=0, column=3)
  148. end_position = cpp_style.Position(row=0, column=4)
  149. single_line_view = cpp_style.SingleLineView(['abcdef'], start_position, end_position)
  150. self.assertEquals(single_line_view.single_line, 'd')
  151. def test_create_skeleton_parameters(self):
  152. self.assertEquals(cpp_style.create_skeleton_parameters(''), '')
  153. self.assertEquals(cpp_style.create_skeleton_parameters(' '), ' ')
  154. self.assertEquals(cpp_style.create_skeleton_parameters('long'), 'long,')
  155. self.assertEquals(cpp_style.create_skeleton_parameters('const unsigned long int'), ' int,')
  156. self.assertEquals(cpp_style.create_skeleton_parameters('long int*'), ' int ,')
  157. self.assertEquals(cpp_style.create_skeleton_parameters('PassRefPtr<Foo> a'), 'PassRefPtr a,')
  158. self.assertEquals(cpp_style.create_skeleton_parameters(
  159. 'ComplexTemplate<NestedTemplate1<MyClass1, MyClass2>, NestedTemplate1<MyClass1, MyClass2> > param, int second'),
  160. 'ComplexTemplate param, int second,')
  161. self.assertEquals(cpp_style.create_skeleton_parameters('int = 0, Namespace::Type& a'), 'int , Type a,')
  162. # Create skeleton parameters is a bit too aggressive with function variables, but
  163. # it allows for parsing other parameters and declarations like this are rare.
  164. self.assertEquals(cpp_style.create_skeleton_parameters('void (*fn)(int a, int b), Namespace::Type& a'),
  165. 'void , Type a,')
  166. # This doesn't look like functions declarations but the simplifications help to eliminate false positives.
  167. self.assertEquals(cpp_style.create_skeleton_parameters('b{d}'), 'b ,')
  168. def test_find_parameter_name_index(self):
  169. self.assertEquals(cpp_style.find_parameter_name_index(' int a '), 5)
  170. self.assertEquals(cpp_style.find_parameter_name_index(' PassRefPtr '), 16)
  171. self.assertEquals(cpp_style.find_parameter_name_index('double'), 6)
  172. def test_parameter_list(self):
  173. elided_lines = ['int blah(PassRefPtr<MyClass> paramName,',
  174. 'const Other1Class& foo,',
  175. 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const * param = new ComplexTemplate<Class1, NestedTemplate<P1, P2> >(34, 42),',
  176. 'int* myCount = 0);']
  177. start_position = cpp_style.Position(row=0, column=8)
  178. end_position = cpp_style.Position(row=3, column=16)
  179. expected_parameters = ({'type': 'PassRefPtr<MyClass>', 'name': 'paramName', 'row': 0},
  180. {'type': 'const Other1Class&', 'name': 'foo', 'row': 1},
  181. {'type': 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const *', 'name': 'param', 'row': 2},
  182. {'type': 'int*', 'name': 'myCount', 'row': 3})
  183. index = 0
  184. for parameter in cpp_style.parameter_list(elided_lines, start_position, end_position):
  185. expected_parameter = expected_parameters[index]
  186. self.assertEquals(parameter.type, expected_parameter['type'])
  187. self.assertEquals(parameter.name, expected_parameter['name'])
  188. self.assertEquals(parameter.row, expected_parameter['row'])
  189. index += 1
  190. self.assertEquals(index, len(expected_parameters))
  191. def test_check_parameter_against_text(self):
  192. error_collector = ErrorCollector(self.assert_)
  193. parameter = cpp_style.Parameter('FooF ooF', 4, 1)
  194. self.assertFalse(cpp_style._check_parameter_name_against_text(parameter, 'FooF', error_collector))
  195. self.assertEquals(error_collector.results(),
  196. 'The parameter name "ooF" adds no information, so it should be removed. [readability/parameter_name] [5]')
  197. class CppStyleTestBase(unittest.TestCase):
  198. """Provides some useful helper functions for cpp_style tests.
  199. Attributes:
  200. min_confidence: An integer that is the current minimum confidence
  201. level for the tests.
  202. """
  203. # FIXME: Refactor the unit tests so the confidence level is passed
  204. # explicitly, just like it is in the real code.
  205. min_confidence = 1;
  206. # Helper function to avoid needing to explicitly pass confidence
  207. # in all the unit test calls to cpp_style.process_file_data().
  208. def process_file_data(self, filename, file_extension, lines, error, unit_test_config={}):
  209. """Call cpp_style.process_file_data() with the min_confidence."""
  210. return cpp_style.process_file_data(filename, file_extension, lines,
  211. error, self.min_confidence, unit_test_config)
  212. def perform_lint(self, code, filename, basic_error_rules, unit_test_config={}):
  213. error_collector = ErrorCollector(self.assert_, FilterConfiguration(basic_error_rules))
  214. lines = code.split('\n')
  215. extension = filename.split('.')[1]
  216. self.process_file_data(filename, extension, lines, error_collector, unit_test_config)
  217. return error_collector.results()
  218. # Perform lint on single line of input and return the error message.
  219. def perform_single_line_lint(self, code, filename):
  220. basic_error_rules = ('-build/header_guard',
  221. '-legal/copyright',
  222. '-readability/fn_size',
  223. '-readability/parameter_name',
  224. '-readability/pass_ptr',
  225. '-whitespace/ending_newline')
  226. return self.perform_lint(code, filename, basic_error_rules)
  227. # Perform lint over multiple lines and return the error message.
  228. def perform_multi_line_lint(self, code, file_extension):
  229. basic_error_rules = ('-build/header_guard',
  230. '-legal/copyright',
  231. '-readability/parameter_name',
  232. '-whitespace/ending_newline')
  233. return self.perform_lint(code, 'test.' + file_extension, basic_error_rules)
  234. # Only keep some errors related to includes, namespaces and rtti.
  235. def perform_language_rules_check(self, filename, code):
  236. basic_error_rules = ('-',
  237. '+build/include',
  238. '+build/include_order',
  239. '+build/namespaces',
  240. '+runtime/rtti')
  241. return self.perform_lint(code, filename, basic_error_rules)
  242. # Only keep function length errors.
  243. def perform_function_lengths_check(self, code):
  244. basic_error_rules = ('-',
  245. '+readability/fn_size')
  246. return self.perform_lint(code, 'test.cpp', basic_error_rules)
  247. # Only keep pass ptr errors.
  248. def perform_pass_ptr_check(self, code):
  249. basic_error_rules = ('-',
  250. '+readability/pass_ptr')
  251. return self.perform_lint(code, 'test.cpp', basic_error_rules)
  252. # Only include what you use errors.
  253. def perform_include_what_you_use(self, code, filename='foo.h', io=codecs):
  254. basic_error_rules = ('-',
  255. '+build/include_what_you_use')
  256. unit_test_config = {cpp_style.INCLUDE_IO_INJECTION_KEY: io}
  257. return self.perform_lint(code, filename, basic_error_rules, unit_test_config)
  258. # Perform lint and compare the error message with "expected_message".
  259. def assert_lint(self, code, expected_message, file_name='foo.cpp'):
  260. self.assertEquals(expected_message, self.perform_single_line_lint(code, file_name))
  261. def assert_lint_one_of_many_errors_re(self, code, expected_message_re, file_name='foo.cpp'):
  262. messages = self.perform_single_line_lint(code, file_name)
  263. for message in messages:
  264. if re.search(expected_message_re, message):
  265. return
  266. self.assertEquals(expected_message_re, messages)
  267. def assert_multi_line_lint(self, code, expected_message, file_name='foo.h'):
  268. file_extension = file_name[file_name.rfind('.') + 1:]
  269. self.assertEquals(expected_message, self.perform_multi_line_lint(code, file_extension))
  270. def assert_multi_line_lint_re(self, code, expected_message_re, file_name='foo.h'):
  271. file_extension = file_name[file_name.rfind('.') + 1:]
  272. message = self.perform_multi_line_lint(code, file_extension)
  273. if not re.search(expected_message_re, message):
  274. self.fail('Message was:\n' + message + 'Expected match to "' + expected_message_re + '"')
  275. def assert_language_rules_check(self, file_name, code, expected_message):
  276. self.assertEquals(expected_message,
  277. self.perform_language_rules_check(file_name, code))
  278. def assert_include_what_you_use(self, code, expected_message):
  279. self.assertEquals(expected_message,
  280. self.perform_include_what_you_use(code))
  281. def assert_blank_lines_check(self, lines, start_errors, end_errors):
  282. error_collector = ErrorCollector(self.assert_)
  283. self.process_file_data('foo.cpp', 'cpp', lines, error_collector)
  284. self.assertEquals(
  285. start_errors,
  286. error_collector.results().count(
  287. 'Blank line at the start of a code block. Is this needed?'
  288. ' [whitespace/blank_line] [2]'))
  289. self.assertEquals(
  290. end_errors,
  291. error_collector.results().count(
  292. 'Blank line at the end of a code block. Is this needed?'
  293. ' [whitespace/blank_line] [3]'))
  294. def assert_positions_equal(self, position, tuple_position):
  295. """Checks if the two positions are equal.
  296. position: a cpp_style.Position object.
  297. tuple_position: a tuple (row, column) to compare against."""
  298. self.assertEquals(position, cpp_style.Position(tuple_position[0], tuple_position[1]),
  299. 'position %s, tuple_position %s' % (position, tuple_position))
  300. class FunctionDetectionTest(CppStyleTestBase):
  301. def perform_function_detection(self, lines, function_information, detection_line=0):
  302. clean_lines = cpp_style.CleansedLines(lines)
  303. function_state = cpp_style._FunctionState(5)
  304. error_collector = ErrorCollector(self.assert_)
  305. cpp_style.detect_functions(clean_lines, detection_line, function_state, error_collector)
  306. if not function_information:
  307. self.assertEquals(function_state.in_a_function, False)
  308. return
  309. self.assertEquals(function_state.in_a_function, True)
  310. self.assertEquals(function_state.current_function, function_information['name'] + '()')
  311. self.assertEquals(function_state.modifiers_and_return_type(), function_information['modifiers_and_return_type'])
  312. self.assertEquals(function_state.is_pure, function_information['is_pure'])
  313. self.assertEquals(function_state.is_declaration, function_information['is_declaration'])
  314. self.assert_positions_equal(function_state.function_name_start_position, function_information['function_name_start_position'])
  315. self.assert_positions_equal(function_state.parameter_start_position, function_information['parameter_start_position'])
  316. self.assert_positions_equal(function_state.parameter_end_position, function_information['parameter_end_position'])
  317. self.assert_positions_equal(function_state.body_start_position, function_information['body_start_position'])
  318. self.assert_positions_equal(function_state.end_position, function_information['end_position'])
  319. expected_parameters = function_information.get('parameter_list')
  320. if expected_parameters:
  321. actual_parameters = function_state.parameter_list()
  322. self.assertEquals(len(actual_parameters), len(expected_parameters))
  323. for index in range(len(expected_parameters)):
  324. actual_parameter = actual_parameters[index]
  325. expected_parameter = expected_parameters[index]
  326. self.assertEquals(actual_parameter.type, expected_parameter['type'])
  327. self.assertEquals(actual_parameter.name, expected_parameter['name'])
  328. self.assertEquals(actual_parameter.row, expected_parameter['row'])
  329. def test_basic_function_detection(self):
  330. self.perform_function_detection(
  331. ['void theTestFunctionName(int) {',
  332. '}'],
  333. {'name': 'theTestFunctionName',
  334. 'modifiers_and_return_type': 'void',
  335. 'function_name_start_position': (0, 5),
  336. 'parameter_start_position': (0, 24),
  337. 'parameter_end_position': (0, 29),
  338. 'body_start_position': (0, 30),
  339. 'end_position': (1, 1),
  340. 'is_pure': False,
  341. 'is_declaration': False})
  342. def test_function_declaration_detection(self):
  343. self.perform_function_detection(
  344. ['void aFunctionName(int);'],
  345. {'name': 'aFunctionName',
  346. 'modifiers_and_return_type': 'void',
  347. 'function_name_start_position': (0, 5),
  348. 'parameter_start_position': (0, 18),
  349. 'parameter_end_position': (0, 23),
  350. 'body_start_position': (0, 23),
  351. 'end_position': (0, 24),
  352. 'is_pure': False,
  353. 'is_declaration': True})
  354. self.perform_function_detection(
  355. ['CheckedInt<T> operator /(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
  356. {'name': 'operator /',
  357. 'modifiers_and_return_type': 'CheckedInt<T>',
  358. 'function_name_start_position': (0, 14),
  359. 'parameter_start_position': (0, 24),
  360. 'parameter_end_position': (0, 76),
  361. 'body_start_position': (0, 76),
  362. 'end_position': (0, 77),
  363. 'is_pure': False,
  364. 'is_declaration': True})
  365. self.perform_function_detection(
  366. ['CheckedInt<T> operator -(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
  367. {'name': 'operator -',
  368. 'modifiers_and_return_type': 'CheckedInt<T>',
  369. 'function_name_start_position': (0, 14),
  370. 'parameter_start_position': (0, 24),
  371. 'parameter_end_position': (0, 76),
  372. 'body_start_position': (0, 76),
  373. 'end_position': (0, 77),
  374. 'is_pure': False,
  375. 'is_declaration': True})
  376. self.perform_function_detection(
  377. ['CheckedInt<T> operator !=(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
  378. {'name': 'operator !=',
  379. 'modifiers_and_return_type': 'CheckedInt<T>',
  380. 'function_name_start_position': (0, 14),
  381. 'parameter_start_position': (0, 25),
  382. 'parameter_end_position': (0, 77),
  383. 'body_start_position': (0, 77),
  384. 'end_position': (0, 78),
  385. 'is_pure': False,
  386. 'is_declaration': True})
  387. self.perform_function_detection(
  388. ['CheckedInt<T> operator +(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
  389. {'name': 'operator +',
  390. 'modifiers_and_return_type': 'CheckedInt<T>',
  391. 'function_name_start_position': (0, 14),
  392. 'parameter_start_position': (0, 24),
  393. 'parameter_end_position': (0, 76),
  394. 'body_start_position': (0, 76),
  395. 'end_position': (0, 77),
  396. 'is_pure': False,
  397. 'is_declaration': True})
  398. def test_pure_function_detection(self):
  399. self.perform_function_detection(
  400. ['virtual void theTestFunctionName(int = 0);'],
  401. {'name': 'theTestFunctionName',
  402. 'modifiers_and_return_type': 'virtual void',
  403. 'function_name_start_position': (0, 13),
  404. 'parameter_start_position': (0, 32),
  405. 'parameter_end_position': (0, 41),
  406. 'body_start_position': (0, 41),
  407. 'end_position': (0, 42),
  408. 'is_pure': False,
  409. 'is_declaration': True})
  410. self.perform_function_detection(
  411. ['virtual void theTestFunctionName(int) = 0;'],
  412. {'name': 'theTestFunctionName',
  413. 'modifiers_and_return_type': 'virtual void',
  414. 'function_name_start_position': (0, 13),
  415. 'parameter_start_position': (0, 32),
  416. 'parameter_end_position': (0, 37),
  417. 'body_start_position': (0, 41),
  418. 'end_position': (0, 42),
  419. 'is_pure': True,
  420. 'is_declaration': True})
  421. # Hopefully, no one writes code like this but it is a tricky case.
  422. self.perform_function_detection(
  423. ['virtual void theTestFunctionName(int)',
  424. ' = ',
  425. ' 0 ;'],
  426. {'name': 'theTestFunctionName',
  427. 'modifiers_and_return_type': 'virtual void',
  428. 'function_name_start_position': (0, 13),
  429. 'parameter_start_position': (0, 32),
  430. 'parameter_end_position': (0, 37),
  431. 'body_start_position': (2, 3),
  432. 'end_position': (2, 4),
  433. 'is_pure': True,
  434. 'is_declaration': True})
  435. def test_ignore_macros(self):
  436. self.perform_function_detection(['void aFunctionName(int); \\'], None)
  437. def test_non_functions(self):
  438. # This case exposed an error because the open brace was in quotes.
  439. self.perform_function_detection(
  440. ['asm(',
  441. ' "stmdb sp!, {r1-r3}" "\n"',
  442. ');'],
  443. # This isn't a function but it looks like one to our simple
  444. # algorithm and that is ok.
  445. {'name': 'asm',
  446. 'modifiers_and_return_type': '',
  447. 'function_name_start_position': (0, 0),
  448. 'parameter_start_position': (0, 3),
  449. 'parameter_end_position': (2, 1),
  450. 'body_start_position': (2, 1),
  451. 'end_position': (2, 2),
  452. 'is_pure': False,
  453. 'is_declaration': True})
  454. # Simple test case with something that is not a function.
  455. self.perform_function_detection(['class Stuff;'], None)
  456. def test_parameter_list(self):
  457. # A function with no arguments.
  458. function_state = self.perform_function_detection(
  459. ['void functionName();'],
  460. {'name': 'functionName',
  461. 'modifiers_and_return_type': 'void',
  462. 'function_name_start_position': (0, 5),
  463. 'parameter_start_position': (0, 17),
  464. 'parameter_end_position': (0, 19),
  465. 'body_start_position': (0, 19),
  466. 'end_position': (0, 20),
  467. 'is_pure': False,
  468. 'is_declaration': True,
  469. 'parameter_list': ()})
  470. # A function with one argument.
  471. function_state = self.perform_function_detection(
  472. ['void functionName(int);'],
  473. {'name': 'functionName',
  474. 'modifiers_and_return_type': 'void',
  475. 'function_name_start_position': (0, 5),
  476. 'parameter_start_position': (0, 17),
  477. 'parameter_end_position': (0, 22),
  478. 'body_start_position': (0, 22),
  479. 'end_position': (0, 23),
  480. 'is_pure': False,
  481. 'is_declaration': True,
  482. 'parameter_list':
  483. ({'type': 'int', 'name': '', 'row': 0},)})
  484. # A function with unsigned and short arguments
  485. function_state = self.perform_function_detection(
  486. ['void functionName(unsigned a, short b, long c, long long short unsigned int);'],
  487. {'name': 'functionName',
  488. 'modifiers_and_return_type': 'void',
  489. 'function_name_start_position': (0, 5),
  490. 'parameter_start_position': (0, 17),
  491. 'parameter_end_position': (0, 76),
  492. 'body_start_position': (0, 76),
  493. 'end_position': (0, 77),
  494. 'is_pure': False,
  495. 'is_declaration': True,
  496. 'parameter_list':
  497. ({'type': 'unsigned', 'name': 'a', 'row': 0},
  498. {'type': 'short', 'name': 'b', 'row': 0},
  499. {'type': 'long', 'name': 'c', 'row': 0},
  500. {'type': 'long long short unsigned int', 'name': '', 'row': 0})})
  501. # Some parameter type with modifiers and no parameter names.
  502. function_state = self.perform_function_detection(
  503. ['virtual void determineARIADropEffects(Vector<String>*&, const unsigned long int*&, const MediaPlayer::Preload, Other<Other2, Other3<P1, P2> >, int);'],
  504. {'name': 'determineARIADropEffects',
  505. 'modifiers_and_return_type': 'virtual void',
  506. 'parameter_start_position': (0, 37),
  507. 'function_name_start_position': (0, 13),
  508. 'parameter_end_position': (0, 147),
  509. 'body_start_position': (0, 147),
  510. 'end_position': (0, 148),
  511. 'is_pure': False,
  512. 'is_declaration': True,
  513. 'parameter_list':
  514. ({'type': 'Vector<String>*&', 'name': '', 'row': 0},
  515. {'type': 'const unsigned long int*&', 'name': '', 'row': 0},
  516. {'type': 'const MediaPlayer::Preload', 'name': '', 'row': 0},
  517. {'type': 'Other<Other2, Other3<P1, P2> >', 'name': '', 'row': 0},
  518. {'type': 'int', 'name': '', 'row': 0})})
  519. # Try parsing a function with a very complex definition.
  520. function_state = self.perform_function_detection(
  521. ['#define MyMacro(a) a',
  522. 'virtual',
  523. 'AnotherTemplate<Class1, Class2> aFunctionName(PassRefPtr<MyClass> paramName,',
  524. 'const Other1Class& foo,',
  525. 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const * param = new ComplexTemplate<Class1, NestedTemplate<P1, P2> >(34, 42),',
  526. 'int* myCount = 0);'],
  527. {'name': 'aFunctionName',
  528. 'modifiers_and_return_type': 'virtual AnotherTemplate<Class1, Class2>',
  529. 'function_name_start_position': (2, 32),
  530. 'parameter_start_position': (2, 45),
  531. 'parameter_end_position': (5, 17),
  532. 'body_start_position': (5, 17),
  533. 'end_position': (5, 18),
  534. 'is_pure': False,
  535. 'is_declaration': True,
  536. 'parameter_list':
  537. ({'type': 'PassRefPtr<MyClass>', 'name': 'paramName', 'row': 2},
  538. {'type': 'const Other1Class&', 'name': 'foo', 'row': 3},
  539. {'type': 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const *', 'name': 'param', 'row': 4},
  540. {'type': 'int*', 'name': 'myCount', 'row': 5})},
  541. detection_line=2)
  542. class CppStyleTest(CppStyleTestBase):
  543. def test_asm_lines_ignored(self):
  544. self.assert_lint(
  545. '__asm mov [registration], eax',
  546. '')
  547. # Test get line width.
  548. def test_get_line_width(self):
  549. self.assertEquals(0, cpp_style.get_line_width(''))
  550. self.assertEquals(10, cpp_style.get_line_width(u'x' * 10))
  551. self.assertEquals(16, cpp_style.get_line_width(u'都|道|府|県|支庁'))
  552. def test_find_next_multi_line_comment_start(self):
  553. self.assertEquals(1, cpp_style.find_next_multi_line_comment_start([''], 0))
  554. lines = ['a', 'b', '/* c']
  555. self.assertEquals(2, cpp_style.find_next_multi_line_comment_start(lines, 0))
  556. lines = ['char a[] = "/*";'] # not recognized as comment.
  557. self.assertEquals(1, cpp_style.find_next_multi_line_comment_start(lines, 0))
  558. def test_find_next_multi_line_comment_end(self):
  559. self.assertEquals(1, cpp_style.find_next_multi_line_comment_end([''], 0))
  560. lines = ['a', 'b', ' c */']
  561. self.assertEquals(2, cpp_style.find_next_multi_line_comment_end(lines, 0))
  562. def test_remove_multi_line_comments_from_range(self):
  563. lines = ['a', ' /* comment ', ' * still comment', ' comment */ ', 'b']
  564. cpp_style.remove_multi_line_comments_from_range(lines, 1, 4)
  565. self.assertEquals(['a', '// dummy', '// dummy', '// dummy', 'b'], lines)
  566. def test_position(self):
  567. position = cpp_style.Position(3, 4)
  568. self.assert_positions_equal(position, (3, 4))
  569. self.assertEquals(position.row, 3)
  570. self.assertTrue(position > cpp_style.Position(position.row - 1, position.column + 1))
  571. self.assertTrue(position > cpp_style.Position(position.row, position.column - 1))
  572. self.assertTrue(position < cpp_style.Position(position.row, position.column + 1))
  573. self.assertTrue(position < cpp_style.Position(position.row + 1, position.column - 1))
  574. self.assertEquals(position.__str__(), '(3, 4)')
  575. def test_rfind_in_lines(self):
  576. not_found_position = cpp_style.Position(10, 11)
  577. start_position = cpp_style.Position(2, 2)
  578. lines = ['ab', 'ace', 'test']
  579. self.assertEquals(not_found_position, cpp_style._rfind_in_lines('st', lines, start_position, not_found_position))
  580. self.assertTrue(cpp_style.Position(1, 1) == cpp_style._rfind_in_lines('a', lines, start_position, not_found_position))
  581. self.assertEquals(cpp_style.Position(2, 2), cpp_style._rfind_in_lines('(te|a)', lines, start_position, not_found_position))
  582. def test_close_expression(self):
  583. self.assertEquals(cpp_style.Position(1, -1), cpp_style.close_expression([')('], cpp_style.Position(0, 1)))
  584. self.assertEquals(cpp_style.Position(1, -1), cpp_style.close_expression([') ()'], cpp_style.Position(0, 1)))
  585. self.assertEquals(cpp_style.Position(0, 4), cpp_style.close_expression([')[)]'], cpp_style.Position(0, 1)))
  586. self.assertEquals(cpp_style.Position(0, 5), cpp_style.close_expression(['}{}{}'], cpp_style.Position(0, 3)))
  587. self.assertEquals(cpp_style.Position(1, 1), cpp_style.close_expression(['}{}{', '}'], cpp_style.Position(0, 3)))
  588. self.assertEquals(cpp_style.Position(2, -1), cpp_style.close_expression(['][][', ' '], cpp_style.Position(0, 3)))
  589. def test_spaces_at_end_of_line(self):
  590. self.assert_lint(
  591. '// Hello there ',
  592. 'Line ends in whitespace. Consider deleting these extra spaces.'
  593. ' [whitespace/end_of_line] [4]')
  594. # Test C-style cast cases.
  595. def test_cstyle_cast(self):
  596. self.assert_lint(
  597. 'int a = (int)1.0;',
  598. 'Using C-style cast. Use static_cast<int>(...) instead'
  599. ' [readability/casting] [4]')
  600. self.assert_lint(
  601. 'int *a = (int *)DEFINED_VALUE;',
  602. 'Using C-style cast. Use reinterpret_cast<int *>(...) instead'
  603. ' [readability/casting] [4]', 'foo.c')
  604. self.assert_lint(
  605. 'uint16 a = (uint16)1.0;',
  606. 'Using C-style cast. Use static_cast<uint16>(...) instead'
  607. ' [readability/casting] [4]')
  608. self.assert_lint(
  609. 'int32 a = (int32)1.0;',
  610. 'Using C-style cast. Use static_cast<int32>(...) instead'
  611. ' [readability/casting] [4]')
  612. self.assert_lint(
  613. 'uint64 a = (uint64)1.0;',
  614. 'Using C-style cast. Use static_cast<uint64>(...) instead'
  615. ' [readability/casting] [4]')
  616. # Test taking address of casts (runtime/casting)
  617. def test_runtime_casting(self):
  618. self.assert_lint(
  619. 'int* x = &static_cast<int*>(foo);',
  620. 'Are you taking an address of a cast? '
  621. 'This is dangerous: could be a temp var. '
  622. 'Take the address before doing the cast, rather than after'
  623. ' [runtime/casting] [4]')
  624. self.assert_lint(
  625. 'int* x = &dynamic_cast<int *>(foo);',
  626. ['Are you taking an address of a cast? '
  627. 'This is dangerous: could be a temp var. '
  628. 'Take the address before doing the cast, rather than after'
  629. ' [runtime/casting] [4]',
  630. 'Do not use dynamic_cast<>. If you need to cast within a class '
  631. 'hierarchy, use static_cast<> to upcast. Google doesn\'t support '
  632. 'RTTI. [runtime/rtti] [5]'])
  633. self.assert_lint(
  634. 'int* x = &reinterpret_cast<int *>(foo);',
  635. 'Are you taking an address of a cast? '
  636. 'This is dangerous: could be a temp var. '
  637. 'Take the address before doing the cast, rather than after'
  638. ' [runtime/casting] [4]')
  639. # It's OK to cast an address.
  640. self.assert_lint(
  641. 'int* x = reinterpret_cast<int *>(&foo);',
  642. '')
  643. def test_runtime_selfinit(self):
  644. self.assert_lint(
  645. 'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }',
  646. 'You seem to be initializing a member variable with itself.'
  647. ' [runtime/init] [4]')
  648. self.assert_lint(
  649. 'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }',
  650. '')
  651. self.assert_lint(
  652. 'Foo::Foo(Bar r) : r_(r), l_(r_), ll_(l_) { }',
  653. '')
  654. def test_runtime_rtti(self):
  655. statement = 'int* x = dynamic_cast<int*>(&foo);'
  656. error_message = (
  657. 'Do not use dynamic_cast<>. If you need to cast within a class '
  658. 'hierarchy, use static_cast<> to upcast. Google doesn\'t support '
  659. 'RTTI. [runtime/rtti] [5]')
  660. # dynamic_cast is disallowed in most files.
  661. self.assert_language_rules_check('foo.cpp', statement, error_message)
  662. self.assert_language_rules_check('foo.h', statement, error_message)
  663. # We cannot test this functionality because of difference of
  664. # function definitions. Anyway, we may never enable this.
  665. #
  666. # # Test for unnamed arguments in a method.
  667. # def test_check_for_unnamed_params(self):
  668. # message = ('All parameters should be named in a function'
  669. # ' [readability/function] [3]')
  670. # self.assert_lint('virtual void A(int*) const;', message)
  671. # self.assert_lint('virtual void B(void (*fn)(int*));', message)
  672. # self.assert_lint('virtual void C(int*);', message)
  673. # self.assert_lint('void *(*f)(void *) = x;', message)
  674. # self.assert_lint('void Method(char*) {', message)
  675. # self.assert_lint('void Method(char*);', message)
  676. # self.assert_lint('void Method(char* /*x*/);', message)
  677. # self.assert_lint('typedef void (*Method)(int32);', message)
  678. # self.assert_lint('static void operator delete[](void*) throw();', message)
  679. #
  680. # self.assert_lint('virtual void D(int* p);', '')
  681. # self.assert_lint('void operator delete(void* x) throw();', '')
  682. # self.assert_lint('void Method(char* x)\n{', '')
  683. # self.assert_lint('void Method(char* /*x*/)\n{', '')
  684. # self.assert_lint('void Method(char* x);', '')
  685. # self.assert_lint('typedef void (*Method)(int32 x);', '')
  686. # self.assert_lint('static void operator delete[](void* x) throw();', '')
  687. # self.assert_lint('static void operator delete[](void* /*x*/) throw();', '')
  688. #
  689. # # This one should technically warn, but doesn't because the function
  690. # # pointer is confusing.
  691. # self.assert_lint('virtual void E(void (*fn)(int* p));', '')
  692. # Test deprecated casts such as int(d)
  693. def test_deprecated_cast(self):
  694. self.assert_lint(
  695. 'int a = int(2.2);',
  696. 'Using deprecated casting style. '
  697. 'Use static_cast<int>(...) instead'
  698. ' [readability/casting] [4]')
  699. # Checks for false positives...
  700. self.assert_lint(
  701. 'int a = int(); // Constructor, o.k.',
  702. '')
  703. self.assert_lint(
  704. 'X::X() : a(int()) { } // default Constructor, o.k.',
  705. '')
  706. self.assert_lint(
  707. 'operator bool(); // Conversion operator, o.k.',
  708. '')
  709. # The second parameter to a gMock method definition is a function signature
  710. # that often looks like a bad cast but should not picked up by lint.
  711. def test_mock_method(self):
  712. self.assert_lint(
  713. 'MOCK_METHOD0(method, int());',
  714. '')
  715. self.assert_lint(
  716. 'MOCK_CONST_METHOD1(method, float(string));',
  717. '')
  718. self.assert_lint(
  719. 'MOCK_CONST_METHOD2_T(method, double(float, float));',
  720. '')
  721. # Test sizeof(type) cases.
  722. def test_sizeof_type(self):
  723. self.assert_lint(
  724. 'sizeof(int);',
  725. 'Using sizeof(type). Use sizeof(varname) instead if possible'
  726. ' [runtime/sizeof] [1]')
  727. self.assert_lint(
  728. 'sizeof(int *);',
  729. 'Using sizeof(type). Use sizeof(varname) instead if possible'
  730. ' [runtime/sizeof] [1]')
  731. # Test typedef cases. There was a bug that cpp_style misidentified
  732. # typedef for pointer to function as C-style cast and produced
  733. # false-positive error messages.
  734. def test_typedef_for_pointer_to_function(self):
  735. self.assert_lint(
  736. 'typedef void (*Func)(int x);',
  737. '')
  738. self.assert_lint(
  739. 'typedef void (*Func)(int *x);',
  740. '')
  741. self.assert_lint(
  742. 'typedef void Func(int x);',
  743. '')
  744. self.assert_lint(
  745. 'typedef void Func(int *x);',
  746. '')
  747. def test_include_what_you_use_no_implementation_files(self):
  748. code = 'std::vector<int> foo;'
  749. self.assertEquals('Add #include <vector> for vector<>'
  750. ' [build/include_what_you_use] [4]',
  751. self.perform_include_what_you_use(code, 'foo.h'))
  752. self.assertEquals('',
  753. self.perform_include_what_you_use(code, 'foo.cpp'))
  754. def test_include_what_you_use(self):
  755. self.assert_include_what_you_use(
  756. '''#include <vector>
  757. std::vector<int> foo;
  758. ''',
  759. '')
  760. self.assert_include_what_you_use(
  761. '''#include <map>
  762. std::pair<int,int> foo;
  763. ''',
  764. '')
  765. self.assert_include_what_you_use(
  766. '''#include <multimap>
  767. std::pair<int,int> foo;
  768. ''',
  769. '')
  770. self.assert_include_what_you_use(
  771. '''#include <hash_map>
  772. std::pair<int,int> foo;
  773. ''',
  774. '')
  775. self.assert_include_what_you_use(
  776. '''#include <utility>
  777. std::pair<int,int> foo;
  778. ''',
  779. '')
  780. self.assert_include_what_you_use(
  781. '''#include <vector>
  782. DECLARE_string(foobar);
  783. ''',
  784. '')
  785. self.assert_include_what_you_use(
  786. '''#include <vector>
  787. DEFINE_string(foobar, "", "");
  788. ''',
  789. '')
  790. self.assert_include_what_you_use(
  791. '''#include <vector>
  792. std::pair<int,int> foo;
  793. ''',
  794. 'Add #include <utility> for pair<>'
  795. ' [build/include_what_you_use] [4]')
  796. self.assert_include_what_you_use(
  797. '''#include "base/foobar.h"
  798. std::vector<int> foo;
  799. ''',
  800. 'Add #include <vector> for vector<>'
  801. ' [build/include_what_you_use] [4]')
  802. self.assert_include_what_you_use(
  803. '''#include <vector>
  804. std::set<int> foo;
  805. ''',
  806. 'Add #include <set> for set<>'
  807. ' [build/include_what_you_use] [4]')
  808. self.assert_include_what_you_use(
  809. '''#include "base/foobar.h"
  810. hash_map<int, int> foobar;
  811. ''',
  812. 'Add #include <hash_map> for hash_map<>'
  813. ' [build/include_what_you_use] [4]')
  814. self.assert_include_what_you_use(
  815. '''#include "base/foobar.h"
  816. bool foobar = std::less<int>(0,1);
  817. ''',
  818. 'Add #include <functional> for less<>'
  819. ' [build/include_what_you_use] [4]')
  820. self.assert_include_what_you_use(
  821. '''#include "base/foobar.h"
  822. bool foobar = min<int>(0,1);
  823. ''',
  824. 'Add #include <algorithm> for min [build/include_what_you_use] [4]')
  825. self.assert_include_what_you_use(
  826. 'void a(const string &foobar);',
  827. 'Add #include <string> for string [build/include_what_you_use] [4]')
  828. self.assert_include_what_you_use(
  829. '''#include "base/foobar.h"
  830. bool foobar = swap(0,1);
  831. ''',
  832. 'Add #include <algorithm> for swap [build/include_what_you_use] [4]')
  833. self.assert_include_what_you_use(
  834. '''#include "base/foobar.h"
  835. bool foobar = transform(a.begin(), a.end(), b.start(), Foo);
  836. ''',
  837. 'Add #include <algorithm> for transform '
  838. '[build/include_what_you_use] [4]')
  839. self.assert_include_what_you_use(
  840. '''#include "base/foobar.h"
  841. bool foobar = min_element(a.begin(), a.end());
  842. ''',
  843. 'Add #include <algorithm> for min_element '
  844. '[build/include_what_you_use] [4]')
  845. self.assert_include_what_you_use(
  846. '''foo->swap(0,1);
  847. foo.swap(0,1);
  848. ''',
  849. '')
  850. self.assert_include_what_you_use(
  851. '''#include <string>
  852. void a(const std::multimap<int,string> &foobar);
  853. ''',
  854. 'Add #include <map> for multimap<>'
  855. ' [build/include_what_you_use] [4]')
  856. self.assert_include_what_you_use(
  857. '''#include <queue>
  858. void a(const std::priority_queue<int> &foobar);
  859. ''',
  860. '')
  861. self.assert_include_what_you_use(
  862. '''#include "base/basictypes.h"
  863. #include "base/port.h"
  864. #include <assert.h>
  865. #include <string>
  866. #include <vector>
  867. vector<string> hajoa;''', '')
  868. self.assert_include_what_you_use(
  869. '''#include <string>
  870. int i = numeric_limits<int>::max()
  871. ''',
  872. 'Add #include <limits> for numeric_limits<>'
  873. ' [build/include_what_you_use] [4]')
  874. self.assert_include_what_you_use(
  875. '''#include <limits>
  876. int i = numeric_limits<int>::max()
  877. ''',
  878. '')
  879. # Test the UpdateIncludeState code path.
  880. mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"']
  881. message = self.perform_include_what_you_use(
  882. '#include "config.h"\n'
  883. '#include "blah/a.h"\n',
  884. filename='blah/a.cpp',
  885. io=MockIo(mock_header_contents))
  886. self.assertEquals(message, '')
  887. mock_header_contents = ['#include <set>']
  888. message = self.perform_include_what_you_use(
  889. '''#include "config.h"
  890. #include "blah/a.h"
  891. std::set<int> foo;''',
  892. filename='blah/a.cpp',
  893. io=MockIo(mock_header_contents))
  894. self.assertEquals(message, '')
  895. # If there's just a .cpp and the header can't be found then it's ok.
  896. message = self.perform_include_what_you_use(
  897. '''#include "config.h"
  898. #include "blah/a.h"
  899. std::set<int> foo;''',
  900. filename='blah/a.cpp')
  901. self.assertEquals(message, '')
  902. # Make sure we find the headers with relative paths.
  903. mock_header_contents = ['']
  904. message = self.perform_include_what_you_use(
  905. '''#include "config.h"
  906. #include "%s%sa.h"
  907. std::set<int> foo;''' % (os.path.basename(os.getcwd()), os.path.sep),
  908. filename='a.cpp',
  909. io=MockIo(mock_header_contents))
  910. self.assertEquals(message, 'Add #include <set> for set<> '
  911. '[build/include_what_you_use] [4]')
  912. def test_files_belong_to_same_module(self):
  913. f = cpp_style.files_belong_to_same_module
  914. self.assertEquals((True, ''), f('a.cpp', 'a.h'))
  915. self.assertEquals((True, ''), f('base/google.cpp', 'base/google.h'))
  916. self.assertEquals((True, ''), f('base/google_test.cpp', 'base/google.h'))
  917. self.assertEquals((True, ''),
  918. f('base/google_unittest.cpp', 'base/google.h'))
  919. self.assertEquals((True, ''),
  920. f('base/internal/google_unittest.cpp',
  921. 'base/public/google.h'))
  922. self.assertEquals((True, 'xxx/yyy/'),
  923. f('xxx/yyy/base/internal/google_unittest.cpp',
  924. 'base/public/google.h'))
  925. self.assertEquals((True, 'xxx/yyy/'),
  926. f('xxx/yyy/base/google_unittest.cpp',
  927. 'base/public/google.h'))
  928. self.assertEquals((True, ''),
  929. f('base/google_unittest.cpp', 'base/google-inl.h'))
  930. self.assertEquals((True, '/home/build/google3/'),
  931. f('/home/build/google3/base/google.cpp', 'base/google.h'))
  932. self.assertEquals((False, ''),
  933. f('/home/build/google3/base/google.cpp', 'basu/google.h'))
  934. self.assertEquals((False, ''), f('a.cpp', 'b.h'))
  935. def test_cleanse_line(self):
  936. self.assertEquals('int foo = 0; ',
  937. cpp_style.cleanse_comments('int foo = 0; // danger!'))
  938. self.assertEquals('int o = 0;',
  939. cpp_style.cleanse_comments('int /* foo */ o = 0;'))
  940. self.assertEquals('foo(int a, int b);',
  941. cpp_style.cleanse_comments('foo(int a /* abc */, int b);'))
  942. self.assertEqual('f(a, b);',
  943. cpp_style.cleanse_comments('f(a, /* name */ b);'))
  944. self.assertEqual('f(a, b);',
  945. cpp_style.cleanse_comments('f(a /* name */, b);'))
  946. self.assertEqual('f(a, b);',
  947. cpp_style.cleanse_comments('f(a, /* name */b);'))
  948. def test_multi_line_comments(self):
  949. # missing explicit is bad
  950. self.assert_multi_line_lint(
  951. r'''int a = 0;
  952. /* multi-liner
  953. class Foo {
  954. Foo(int f); // should cause a lint warning in code
  955. }
  956. */ ''',
  957. '')
  958. self.assert_multi_line_lint(
  959. r'''/* int a = 0; multi-liner
  960. static const int b = 0;''',
  961. ['Could not find end of multi-line comment'
  962. ' [readability/multiline_comment] [5]',
  963. 'Complex multi-line /*...*/-style comment found. '
  964. 'Lint may give bogus warnings. Consider replacing these with '
  965. '//-style comments, with #if 0...#endif, or with more clearly '
  966. 'structured multi-line comments. [readability/multiline_comment] [5]'])
  967. self.assert_multi_line_lint(r''' /* multi-line comment''',
  968. ['Could not find end of multi-line comment'
  969. ' [readability/multiline_comment] [5]',
  970. 'Complex multi-line /*...*/-style comment found. '
  971. 'Lint may give bogus warnings. Consider replacing these with '
  972. '//-style comments, with #if 0...#endif, or with more clearly '
  973. 'structured multi-line comments. [readability/multiline_comment] [5]'])
  974. self.assert_multi_line_lint(r''' // /* comment, but not multi-line''', '')
  975. def test_multiline_strings(self):
  976. multiline_string_error_message = (
  977. 'Multi-line string ("...") found. This lint script doesn\'t '
  978. 'do well with such strings, and may give bogus warnings. They\'re '
  979. 'ugly and unnecessary, and you should use concatenation instead".'
  980. ' [readability/multiline_string] [5]')
  981. file_path = 'mydir/foo.cpp'
  982. error_collector = ErrorCollector(self.assert_)
  983. self.process_file_data(file_path, 'cpp',
  984. ['const char* str = "This is a\\',
  985. ' multiline string.";'],
  986. error_collector)
  987. self.assertEquals(
  988. 2, # One per line.
  989. error_collector.result_list().count(multiline_string_error_message))
  990. # Test non-explicit single-argument constructors
  991. def test_explicit_single_argument_constructors(self):
  992. # missing explicit is bad
  993. self.assert_multi_line_lint(
  994. '''class Foo {
  995. Foo(int f);
  996. };''',
  997. 'Single-argument constructors should be marked explicit.'
  998. ' [runtime/explicit] [5]')
  999. # missing explicit is bad, even with whitespace
  1000. self.assert_multi_line_lint(
  1001. '''class Foo {
  1002. Foo (int f);
  1003. };''',
  1004. ['Extra space before ( in function call [whitespace/parens] [4]',
  1005. 'Single-argument constructors should be marked explicit.'
  1006. ' [runtime/explicit] [5]'])
  1007. # missing explicit, with distracting comment, is still bad
  1008. self.assert_multi_line_lint(
  1009. '''class Foo {
  1010. Foo(int f); // simpler than Foo(blargh, blarg)
  1011. };''',
  1012. 'Single-argument constructors should be marked explicit.'
  1013. ' [runtime/explicit] [5]')
  1014. # missing explicit, with qualified classname
  1015. self.assert_multi_line_lint(
  1016. '''class Qualifier::AnotherOne::Foo {
  1017. Foo(int f);
  1018. };''',
  1019. 'Single-argument constructors should be marked explicit.'
  1020. ' [runtime/explicit] [5]')
  1021. # structs are caught as well.
  1022. self.assert_multi_line_lint(
  1023. '''struct Foo {
  1024. Foo(int f);
  1025. };''',
  1026. 'Single-argument constructors should be marked explicit.'
  1027. ' [runtime/explicit] [5]')
  1028. # Templatized classes are caught as well.
  1029. self.assert_multi_line_lint(
  1030. '''template<typename T> class Foo {
  1031. Foo(int f);
  1032. };''',
  1033. 'Single-argument constructors should be marked explicit.'
  1034. ' [runtime/explicit] [5]')
  1035. # proper style is okay
  1036. self.assert_multi_line_lint(
  1037. '''class Foo {
  1038. explicit Foo(int f);
  1039. };''',
  1040. '')
  1041. # two argument constructor is okay
  1042. self.assert_multi_line_lint(
  1043. '''class Foo {
  1044. Foo(int f, int b);
  1045. };''',
  1046. '')
  1047. # two argument constructor, across two lines, is okay
  1048. self.assert_multi_line_lint(
  1049. '''class Foo {
  1050. Foo(int f,
  1051. int b);
  1052. };''',
  1053. '')
  1054. # non-constructor (but similar name), is okay
  1055. self.assert_multi_line_lint(
  1056. '''class Foo {
  1057. aFoo(int f);
  1058. };''',
  1059. '')
  1060. # constructor with void argument is okay
  1061. self.assert_multi_line_lint(
  1062. '''class Foo {
  1063. Foo(void);
  1064. };''',
  1065. '')
  1066. # single argument method is okay
  1067. self.assert_multi_line_lint(
  1068. '''class Foo {
  1069. Bar(int b);
  1070. };''',
  1071. '')
  1072. # comments should be ignored
  1073. self.assert_multi_line_lint(
  1074. '''class Foo {
  1075. // Foo(int f);
  1076. };''',
  1077. '')
  1078. # single argument function following class definition is okay
  1079. # (okay, it's not actually valid, but we don't want a false positive)
  1080. self.assert_multi_line_lint(
  1081. '''class Foo {
  1082. Foo(int f, int b);
  1083. };
  1084. Foo(int f);''',
  1085. '')
  1086. # single argument function is okay
  1087. self.assert_multi_line_lint(
  1088. '''static Foo(int f);''',
  1089. '')
  1090. # single argument copy constructor is okay.
  1091. self.assert_multi_line_lint(
  1092. '''class Foo {
  1093. Foo(const Foo&);
  1094. };''',
  1095. '')
  1096. self.assert_multi_line_lint(
  1097. '''class Foo {
  1098. Foo(Foo&);
  1099. };''',
  1100. '')
  1101. def test_slash_star_comment_on_single_line(self):
  1102. self.assert_multi_line_lint(
  1103. '''/* static */ Foo(int f);''',
  1104. '')
  1105. self.assert_multi_line_lint(
  1106. '''/*/ static */ Foo(int f);''',
  1107. '')
  1108. self.assert_multi_line_lint(
  1109. '''/*/ static Foo(int f);''',
  1110. 'Could not find end of multi-line comment'
  1111. ' [readability/multiline_comment] [5]')
  1112. self.assert_multi_line_lint(
  1113. ''' /*/ static Foo(int f);''',
  1114. 'Could not find end of multi-line comment'
  1115. ' [readability/multiline_comment] [5]')
  1116. self.assert_multi_line_lint(
  1117. ''' /**/ static Foo(int f);''',
  1118. '')
  1119. # Test suspicious usage of "if" like this:
  1120. # if (a == b) {
  1121. # DoSomething();
  1122. # } if (a == c) { // Should be "else if".
  1123. # DoSomething(); // This gets called twice if a == b && a == c.
  1124. # }
  1125. def test_suspicious_usage_of_if(self):
  1126. self.assert_lint(
  1127. ' if (a == b) {',
  1128. '')
  1129. self.assert_lint(
  1130. ' } if (a == b) {',
  1131. 'Did you mean "else if"? If not, start a new line for "if".'
  1132. ' [readability/braces] [4]')
  1133. # Test suspicious usage of memset. Specifically, a 0
  1134. # as the final argument is almost certainly an error.
  1135. def test_suspicious_usage_of_memset(self):
  1136. # Normal use is okay.
  1137. self.assert_lint(
  1138. ' memset(buf, 0, sizeof(buf))',
  1139. '')
  1140. # A 0 as the final argument is almost certainly an error.
  1141. self.assert_lint(
  1142. ' memset(buf, sizeof(buf), 0)',
  1143. 'Did you mean "memset(buf, 0, sizeof(buf))"?'
  1144. ' [runtime/memset] [4]')
  1145. self.assert_lint(
  1146. ' memset(buf, xsize * ysize, 0)',
  1147. 'Did you mean "memset(buf, 0, xsize * ysize)"?'
  1148. ' [runtime/memset] [4]')
  1149. # There is legitimate test code that uses this form.
  1150. # This is okay since the second argument is a literal.
  1151. self.assert_lint(
  1152. " memset(buf, 'y', 0)",
  1153. '')
  1154. self.assert_lint(
  1155. ' memset(buf, 4, 0)',
  1156. '')
  1157. self.assert_lint(
  1158. ' memset(buf, -1, 0)',
  1159. '')
  1160. self.assert_lint(
  1161. ' memset(buf, 0xF1, 0)',
  1162. '')
  1163. self.assert_lint(
  1164. ' memset(buf, 0xcd, 0)',
  1165. '')
  1166. def test_check_posix_threading(self):
  1167. self.assert_lint('sctime_r()', '')
  1168. self.assert_lint('strtok_r()', '')
  1169. self.assert_lint(' strtok_r(foo, ba, r)', '')
  1170. self.assert_lint('brand()', '')
  1171. self.assert_lint('_rand()', '')
  1172. self.assert_lint('.rand()', '')
  1173. self.assert_lint('>rand()', '')
  1174. self.assert_lint('rand()',
  1175. 'Consider using rand_r(...) instead of rand(...)'
  1176. ' for improved thread safety.'
  1177. ' [runtime/threadsafe_fn] [2]')
  1178. self.assert_lint('strtok()',
  1179. 'Consider using strtok_r(...) '
  1180. 'instead of strtok(...)'
  1181. ' for improved thread safety.'
  1182. ' [runtime/threadsafe_fn] [2]')
  1183. # Test potential format string bugs like printf(foo).
  1184. def test_format_strings(self):
  1185. self.assert_lint('printf("foo")', '')
  1186. self.assert_lint('printf("foo: %s", foo)', '')
  1187. self.assert_lint('DocidForPrintf(docid)', '') # Should not trigger.
  1188. self.assert_lint(
  1189. 'printf(foo)',
  1190. 'Potential format string bug. Do printf("%s", foo) instead.'
  1191. ' [runtime/printf] [4]')
  1192. self.assert_lint(
  1193. 'printf(foo.c_str())',
  1194. 'Potential format string bug. '
  1195. 'Do printf("%s", foo.c_str()) instead.'
  1196. ' [runtime/printf] [4]')
  1197. self.assert_lint(
  1198. 'printf(foo->c_str())',
  1199. 'Potential format string bug. '
  1200. 'Do printf("%s", foo->c_str()) instead.'
  1201. ' [runtime/printf] [4]')
  1202. self.assert_lint(
  1203. 'StringPrintf(foo)',
  1204. 'Potential format string bug. Do StringPrintf("%s", foo) instead.'
  1205. ''
  1206. ' [runtime/printf] [4]')
  1207. # Variable-length arrays are not permitted.
  1208. def test_variable_length_array_detection(self):
  1209. errmsg = ('Do not use variable-length arrays. Use an appropriately named '
  1210. "('k' followed by CamelCase) compile-time constant for the size."
  1211. ' [runtime/arrays] [1]')
  1212. self.assert_lint('int a[any_old_variable];', errmsg)
  1213. self.assert_lint('int doublesize[some_var * 2];', errmsg)
  1214. self.assert_lint('int a[afunction()];', errmsg)
  1215. self.assert_lint('int a[function(kMaxFooBars)];', errmsg)
  1216. self.assert_lint('bool aList[items_->size()];', errmsg)
  1217. self.assert_lint('namespace::Type buffer[len+1];', errmsg)
  1218. self.assert_lint('int a[64];', '')
  1219. self.assert_lint('int a[0xFF];', '')
  1220. self.assert_lint('int first[256], second[256];', '')
  1221. self.assert_lint('int arrayName[kCompileTimeConstant];', '')
  1222. self.assert_lint('char buf[somenamespace::kBufSize];', '')
  1223. self.assert_lint('int arrayName[ALL_CAPS];', '')
  1224. self.assert_lint('AClass array1[foo::bar::ALL_CAPS];', '')
  1225. self.assert_lint('int a[kMaxStrLen + 1];', '')
  1226. self.assert_lint('int a[sizeof(foo)];', '')
  1227. self.assert_lint('int a[sizeof(*foo)];', '')
  1228. self.assert_lint('int a[sizeof foo];', '')
  1229. self.assert_lint('int a[sizeof(struct Foo)];', '')
  1230. self.assert_lint('int a[128 - sizeof(const bar)];', '')
  1231. self.assert_lint('int a[(sizeof(foo) * 4)];', '')
  1232. self.assert_lint('int a[(arraysize(fixed_size_array)/2) << 1];', 'Missing spaces around / [whitespace/operators] [3]')
  1233. self.assert_lint('delete a[some_var];', '')
  1234. self.assert_lint('return a[some_var];', '')
  1235. # Brace usage
  1236. def test_braces(self):
  1237. # Braces shouldn't be followed by a ; unless they're defining a struct
  1238. # or initializing an array
  1239. self.assert_lint('int a[3] = { 1, 2, 3 };', '')
  1240. self.assert_lint(
  1241. '''const int foo[] =
  1242. {1, 2, 3 };''',
  1243. '')
  1244. # For single line, unmatched '}' with a ';' is ignored (not enough context)
  1245. self.assert_multi_line_lint(
  1246. '''int a[3] = { 1,
  1247. 2,
  1248. 3 };''',
  1249. '')
  1250. self.assert_multi_line_lint(
  1251. '''int a[2][3] = { { 1, 2 },
  1252. { 3, 4 } };''',
  1253. '')
  1254. self.assert_multi_line_lint(
  1255. '''int a[2][3] =
  1256. { { 1, 2 },
  1257. { 3, 4 } };''',
  1258. '')
  1259. # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements
  1260. def test_check_check(self):
  1261. self.assert_lint('CHECK(x == 42)',
  1262. 'Consider using CHECK_EQ instead of CHECK(a == b)'
  1263. ' [readability/check] [2]')
  1264. self.assert_lint('CHECK(x != 42)',
  1265. 'Consider using CHECK_NE instead of CHECK(a != b)'
  1266. ' [readability/check] [2]')
  1267. self.assert_lint('CHECK(x >= 42)',
  1268. 'Consider using CHECK_GE instead of CHECK(a >= b)'
  1269. ' [readability/check] [2]')
  1270. self.assert_lint('CHECK(x > 42)',
  1271. 'Consider using CHECK_GT instead of CHECK(a > b)'
  1272. ' [readability/check] [2]')
  1273. self.assert_lint('CHECK(x <= 42)',
  1274. 'Consider using CHECK_LE instead of CHECK(a <= b)'
  1275. ' [readability/check] [2]')
  1276. self.assert_lint('CHECK(x < 42)',
  1277. 'Consider using CHECK_LT instead of CHECK(a < b)'
  1278. ' [readability/check] [2]')
  1279. self.assert_lint('DCHECK(x == 42)',
  1280. 'Consider using DCHECK_EQ instead of DCHECK(a == b)'
  1281. ' [readability/check] [2]')
  1282. self.assert_lint('DCHECK(x != 42)',
  1283. 'Consider using DCHECK_NE instead of DCHECK(a != b)'
  1284. ' [readability/check] [2]')
  1285. self.assert_lint('DCHECK(x >= 42)',
  1286. 'Consider using DCHECK_GE instead of DCHECK(a >= b)'
  1287. ' [readability/check] [2]')
  1288. self.assert_lint('DCHECK(x > 42)',
  1289. 'Consider using DCHECK_GT instead of DCHECK(a > b)'
  1290. ' [readability/check] [2]')
  1291. self.assert_lint('DCHECK(x <= 42)',
  1292. 'Consider using DCHECK_LE instead of DCHECK(a <= b)'
  1293. ' [readability/check] [2]')
  1294. self.assert_lint('DCHECK(x < 42)',
  1295. 'Consider using DCHECK_LT instead of DCHECK(a < b)'
  1296. ' [readability/check] [2]')
  1297. self.assert_lint(
  1298. 'EXPECT_TRUE("42" == x)',
  1299. 'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)'
  1300. ' [readability/check] [2]')
  1301. self.assert_lint(
  1302. 'EXPECT_TRUE("42" != x)',
  1303. 'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)'
  1304. ' [readability/check] [2]')
  1305. self.assert_lint(
  1306. 'EXPECT_TRUE(+42 >= x)',
  1307. 'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)'
  1308. ' [readability/check] [2]')
  1309. self.assert_lint(
  1310. 'EXPECT_TRUE_M(-42 > x)',
  1311. 'Consider using EXPECT_GT_M instead of EXPECT_TRUE_M(a > b)'
  1312. ' [readability/check] [2]')
  1313. self.assert_lint(
  1314. 'EXPECT_TRUE_M(42U <= x)',
  1315. 'Consider using EXPECT_LE_M instead of EXPECT_TRUE_M(a <= b)'
  1316. ' [readability/check] [2]')
  1317. self.assert_lint(
  1318. 'EXPECT_TRUE_M(42L < x)',
  1319. 'Consider using EXPECT_LT_M instead of EXPECT_TRUE_M(a < b)'
  1320. ' [readability/check] [2]')
  1321. self.assert_lint(
  1322. 'EXPECT_FALSE(x == 42)',
  1323. 'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)'
  1324. ' [readability/check] [2]')
  1325. self.assert_lint(
  1326. 'EXPECT_FALSE(x != 42)',
  1327. 'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)'
  1328. ' [readability/check] [2]')
  1329. self.assert_lint(
  1330. 'EXPECT_FALSE(x >= 42)',
  1331. 'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)'
  1332. ' [readability/check] [2]')
  1333. self.assert_lint(
  1334. 'ASSERT_FALSE(x > 42)',
  1335. 'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)'
  1336. ' [readability/check] [2]')
  1337. self.assert_lint(
  1338. 'ASSERT_FALSE(x <= 42)',
  1339. 'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)'
  1340. ' [readability/check] [2]')
  1341. self.assert_lint(
  1342. 'ASSERT_FALSE_M(x < 42)',
  1343. 'Consider using ASSERT_GE_M instead of ASSERT_FALSE_M(a < b)'
  1344. ' [readability/check] [2]')
  1345. self.assert_lint('CHECK(some_iterator == obj.end())', '')
  1346. self.assert_lint('EXPECT_TRUE(some_iterator == obj.end())', '')
  1347. self.assert_lint('EXPECT_FALSE(some_iterator == obj.end())', '')
  1348. self.assert_lint('CHECK(CreateTestFile(dir, (1 << 20)));', '')
  1349. self.assert_lint('CHECK(CreateTestFile(dir, (1 >> 20)));', '')
  1350. self.assert_lint('CHECK(x<42)',
  1351. ['Missing spaces around <'
  1352. ' [whitespace/operators] [3]',
  1353. 'Consider using CHECK_LT instead of CHECK(a < b)'
  1354. ' [readability/check] [2]'])
  1355. self.assert_lint('CHECK(x>42)',
  1356. 'Consider using CHECK_GT instead of CHECK(a > b)'
  1357. ' [readability/check] [2]')
  1358. self.assert_lint(
  1359. ' EXPECT_TRUE(42 < x) // Random comment.',
  1360. 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
  1361. ' [readability/check] [2]')
  1362. self.assert_lint(
  1363. 'EXPECT_TRUE( 42 < x )',
  1364. ['Extra space after ( in function call'
  1365. ' [whitespace/parens] [4]',
  1366. 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
  1367. ' [readability/check] [2]'])
  1368. self.assert_lint(
  1369. 'CHECK("foo" == "foo")',
  1370. 'Consider using CHECK_EQ instead of CHECK(a == b)'
  1371. ' [readability/check] [2]')
  1372. self.assert_lint('CHECK_EQ("foo", "foo")', '')
  1373. def test_brace_at_begin_of_line(self):
  1374. self.assert_lint('{',
  1375. 'This { should be at the end of the previous line'
  1376. ' [whitespace/braces] [4]')
  1377. self.assert_multi_line_lint(
  1378. '#endif\n'
  1379. '{\n'
  1380. '}\n',
  1381. '')
  1382. self.assert_multi_line_lint(
  1383. 'if (condition) {',
  1384. '')
  1385. self.assert_multi_line_lint(
  1386. ' MACRO1(macroArg) {',
  1387. '')
  1388. self.assert_multi_line_lint(
  1389. 'ACCESSOR_GETTER(MessageEventPorts) {',
  1390. 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
  1391. self.assert_multi_line_lint(
  1392. 'int foo() {',
  1393. 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
  1394. self.assert_multi_line_lint(
  1395. 'int foo() const {',
  1396. 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
  1397. self.assert_multi_line_lint(
  1398. 'int foo() const\n'
  1399. '{\n'
  1400. '}\n',
  1401. '')
  1402. self.assert_multi_line_lint(
  1403. 'if (condition\n'
  1404. ' && condition2\n'
  1405. ' && condition3) {\n'
  1406. '}\n',
  1407. '')
  1408. def test_mismatching_spaces_in_parens(self):
  1409. self.assert_lint('if (foo ) {', 'Extra space before ) in if'
  1410. ' [whitespace/parens] [5]')
  1411. self.assert_lint('switch ( foo) {', 'Extra space after ( in switch'
  1412. ' [whitespace/parens] [5]')
  1413. self.assert_lint('for (foo; ba; bar ) {', 'Extra space before ) in for'
  1414. ' [whitespace/parens] [5]')
  1415. self.assert_lint('for ((foo); (ba); (bar) ) {', 'Extra space before ) in for'
  1416. ' [whitespace/parens] [5]')
  1417. self.assert_lint('for (; foo; bar) {', '')
  1418. self.assert_lint('for (; (foo); (bar)) {', '')
  1419. self.assert_lint('for ( ; foo; bar) {', '')
  1420. self.assert_lint('for ( ; (foo); (bar)) {', '')
  1421. self.assert_lint('for ( ; foo; bar ) {', 'Extra space before ) in for'
  1422. ' [whitespace/parens] [5]')
  1423. self.assert_lint('for ( ; (foo); (bar) ) {', 'Extra space before ) in for'
  1424. ' [whitespace/parens] [5]')
  1425. self.assert_lint('for (foo; bar; ) {', '')
  1426. self.assert_lint('for ((foo); (bar); ) {', '')
  1427. self.assert_lint('foreach (foo, foos ) {', 'Extra space before ) in foreach'
  1428. ' [whitespace/parens] [5]')
  1429. self.assert_lint('foreach ( foo, foos) {', 'Extra space after ( in foreach'
  1430. ' [whitespace/parens] [5]')
  1431. self.assert_lint('while ( foo) {', 'Extra space after ( in while'
  1432. ' [whitespace/parens] [5]')
  1433. def test_spacing_for_fncall(self):
  1434. self.assert_lint('if (foo) {', '')
  1435. self.assert_lint('for (foo;bar;baz) {', '')
  1436. self.assert_lint('foreach (foo, foos) {', '')
  1437. self.assert_lint('while (foo) {', '')
  1438. self.assert_lint('switch (foo) {', '')
  1439. self.assert_lint('new (RenderArena()) RenderInline(document())', '')
  1440. self.assert_lint('foo( bar)', 'Extra space after ( in function call'
  1441. ' [whitespace/parens] [4]')
  1442. self.assert_lint('foobar( \\', '')
  1443. self.assert_lint('foobar( \\', '')
  1444. self.assert_lint('( a + b)', 'Extra space after ('
  1445. ' [whitespace/parens] [2]')
  1446. self.assert_lint('((a+b))', '')
  1447. self.assert_lint('foo (foo)', 'Extra space before ( in function call'
  1448. ' [whitespace/parens] [4]')
  1449. self.assert_lint('#elif (foo(bar))', '')
  1450. self.assert_lint('#elif (foo(bar) && foo(baz))', '')
  1451. self.assert_lint('typedef foo (*foo)(foo)', '')
  1452. self.assert_lint('typedef foo (*foo12bar_)(foo)', '')
  1453. self.assert_lint('typedef foo (Foo::*bar)(foo)', '')
  1454. self.assert_lint('foo (Foo::*bar)(',
  1455. 'Extra space before ( in function call'
  1456. ' [whitespace/parens] [4]')
  1457. self.assert_lint('typedef foo (Foo::*bar)(', '')
  1458. self.assert_lint('(foo)(bar)', '')
  1459. self.assert_lint('Foo (*foo)(bar)', '')
  1460. self.assert_lint('Foo (*foo)(Bar bar,', '')
  1461. self.assert_lint('char (*p)[sizeof(foo)] = &foo', '')
  1462. self.assert_lint('char (&ref)[sizeof(foo)] = &foo', '')
  1463. self.assert_lint('const char32 (*table[])[6];', '')
  1464. def test_spacing_before_braces(self):
  1465. self.assert_lint('if (foo){', 'Missing space before {'
  1466. ' [whitespace/braces] [5]')
  1467. self.assert_lint('for{', 'Missing space before {'
  1468. ' [whitespace/braces] [5]')
  1469. self.assert_lint('for {', '')
  1470. self.assert_lint('EXPECT_DEBUG_DEATH({', '')
  1471. def test_spacing_between_braces(self):
  1472. self.assert_lint(' { }', '')
  1473. self.assert_lint(' {}', 'Missing space inside { }. [whitespace/braces] [5]')
  1474. self.assert_lint(' { }', 'Too many spaces inside { }. [whitespace/braces] [5]')
  1475. def test_spacing_around_else(self):
  1476. self.assert_lint('}else {', 'Missing space before else'
  1477. ' [whitespace/braces] [5]')
  1478. self.assert_lint('} else{', 'Missing space before {'
  1479. ' [whitespace/braces] [5]')
  1480. self.assert_lint('} else {', '')
  1481. self.assert_lint('} else if', '')
  1482. def test_spacing_for_binary_ops(self):
  1483. self.assert_lint('if (foo<=bar) {', 'Missing spaces around <='
  1484. ' [whitespace/operators] [3]')
  1485. self.assert_lint('if (foo<bar) {', 'Missing spaces around <'
  1486. ' [whitespace/operators] [3]')
  1487. self.assert_lint('if (foo<bar->baz) {', 'Missing spaces around <'
  1488. ' [whitespace/operators] [3]')
  1489. self.assert_lint('if (foo<bar->bar) {', 'Missing spaces around <'
  1490. ' [whitespace/operators] [3]')
  1491. self.assert_lint('typedef hash_map<Foo, Bar', 'Missing spaces around <'
  1492. ' [whitespace/operators] [3]')
  1493. self.assert_lint('typedef hash_map<FoooooType, BaaaaarType,', '')
  1494. self.assert_lint('a<Foo> t+=b;', 'Missing spaces around +='
  1495. ' [whitespace/operators] [3]')
  1496. self.assert_lint('a<Foo> t-=b;', 'Missing spaces around -='
  1497. ' [whitespace/operators] [3]')
  1498. self.assert_lint('a<Foo*> t*=b;', 'Missing spaces around *='
  1499. ' [whitespace/operators] [3]')
  1500. self.assert_lint('a<Foo*> t/=b;', 'Missing spaces around /='
  1501. ' [whitespace/operators] [3]')
  1502. self.assert_lint('a<Foo*> t|=b;', 'Missing spaces around |='
  1503. ' [whitespace/operators] [3]')
  1504. self.assert_lint('a<Foo*> t&=b;', 'Missing spaces around &='
  1505. ' [whitespace/operators] [3]')
  1506. self.assert_lint('a<Foo*> t<<=b;', 'Missing spaces around <<='
  1507. ' [whitespace/operators] [3]')
  1508. self.assert_lint('a<Foo*> t>>=b;', 'Missing spaces around >>='
  1509. ' [whitespace/operators] [3]')
  1510. self.assert_lint('a<Foo*> t>>=&b|c;', 'Missing spaces around >>='
  1511. ' [whitespace/operators] [3]')
  1512. self.assert_lint('a<Foo*> t<<=*b/c;', 'Missing spaces around <<='
  1513. ' [whitespace/operators] [3]')
  1514. self.assert_lint('a<Foo> t -= b;', '')
  1515. self.assert_lint('a<Foo> t += b;', '')
  1516. self.assert_lint('a<Foo*> t *= b;', '')
  1517. self.assert_lint('a<Foo*> t /= b;', '')
  1518. self.assert_lint('a<Foo*> t |= b;', '')
  1519. self.assert_lint('a<Foo*> t &= b;', '')
  1520. self.assert_lint('a<Foo*> t <<= b;', '')
  1521. self.assert_lint('a<Foo*> t >>= b;', '')
  1522. self.assert_lint('a<Foo*> t >>= &b|c;', 'Missing spaces around |'
  1523. ' [whitespace/operators] [3]')
  1524. self.assert_lint('a<Foo*> t <<= *b/c;', 'Missing spaces around /'
  1525. ' [whitespace/operators] [3]')
  1526. self.assert_lint('a<Foo*> t <<= b/c; //Test', [
  1527. 'Should have a space between // and comment '
  1528. '[whitespace/comments] [4]', 'Missing'
  1529. ' spaces around / [whitespace/operators] [3]'])
  1530. self.assert_lint('a<Foo*> t <<= b||c; //Test', ['One space before end'
  1531. ' of line comments [whitespace/comments] [5]',
  1532. 'Should have a space between // and comment '
  1533. '[whitespace/comments] [4]',
  1534. 'Missing spaces around || [whitespace/operators] [3]'])
  1535. self.assert_lint('a<Foo*> t <<= b&&c; // Test', 'Missing spaces around'
  1536. ' && [whitespace/operators] [3]')
  1537. self.assert_lint('a<Foo*> t <<= b&&&c; // Test', 'Missing spaces around'
  1538. ' && [whitespace/operators] [3]')
  1539. self.assert_lint('a<Foo*> t <<= b&&*c; // Test', 'Missing spaces around'
  1540. ' && [whitespace/operators] [3]')
  1541. self.assert_lint('a<Foo*> t <<= b && *c; // Test', '')
  1542. self.assert_lint('a<Foo*> t <<= b && &c; // Test', '')
  1543. self.assert_lint('a<Foo*> t <<= b || &c; /*Test', 'Complex multi-line '
  1544. '/*...*/-style comment found. Lint may give bogus '
  1545. 'warnings. Consider replacing these with //-style'
  1546. ' comments, with #if 0...#endif, or with more clearly'
  1547. ' structured multi-line comments. [readability/multiline_comment] [5]')
  1548. self.assert_lint('a<Foo&> t <<= &b | &c;', '')
  1549. self.assert_lint('a<Foo*> t <<= &b & &c; // Test', '')
  1550. self.assert_lint('a<Foo*> t <<= *b / &c; // Test', '')
  1551. self.assert_lint('if (a=b == 1)', 'Missing spaces around = [whitespace/operators] [4]')
  1552. self.assert_lint('a = 1<<20', 'Missing spaces around << [whitespace/operators] [3]')
  1553. self.assert_lint('if (a = b == 1)', '')
  1554. self.assert_lint('a = 1 << 20', '')
  1555. self.assert_multi_line_lint('#include <sys/io.h>\n', '')
  1556. self.assert_multi_line_lint('#import <foo/bar.h>\n', '')
  1557. def test_operator_methods(self):
  1558. self.assert_lint('String operator+(const String&, const String&);', '')
  1559. self.assert_lint('bool operator==(const String&, const String&);', '')
  1560. self.assert_lint('String& operator-=(const String&, const String&);', '')
  1561. self.assert_lint('String& operator+=(const String&, const String&);', '')
  1562. self.assert_lint('String& operator*=(const String&, const String&);', '')
  1563. self.assert_lint('String& operator%=(const String&, const String&);', '')
  1564. self.assert_lint('String& operator&=(const String&, const String&);', '')
  1565. self.assert_lint('String& operator<<=(const String&, const String&);', '')
  1566. self.assert_lint('String& operator>>=(const String&, const String&);', '')
  1567. self.assert_lint('String& operator|=(const String&, const String&);', '')
  1568. self.assert_lint('String& operator^=(const String&, const String&);', '')
  1569. def test_spacing_before_last_semicolon(self):
  1570. self.assert_lint('call_function() ;',
  1571. 'Extra space before last semicolon. If this should be an '
  1572. 'empty statement, use { } instead.'
  1573. ' [whitespace/semicolon] [5]')
  1574. self.assert_lint('while (true) ;',
  1575. 'Extra space before last semicolon. If this should be an '
  1576. 'empty statement, use { } instead.'
  1577. ' [whitespace/semicolon] [5]')
  1578. self.assert_lint('default:;',
  1579. 'Semicolon defining empty statement. Use { } instead.'
  1580. ' [whitespace/semicolon] [5]')
  1581. self.assert_lint(' ;',
  1582. 'Line contains only semicolon. If this should be an empty '
  1583. 'statement, use { } instead.'
  1584. ' [whitespace/semicolon] [5]')
  1585. self.assert_lint('for (int i = 0; ;', '')
  1586. # Static or global STL strings.
  1587. def test_static_or_global_stlstrings(self):
  1588. self.assert_lint('string foo;',
  1589. 'For a static/global string constant, use a C style '
  1590. 'string instead: "char foo[]".'
  1591. ' [runtime/string] [4]')
  1592. self.assert_lint('string kFoo = "hello"; // English',
  1593. 'For a static/global string constant, use a C style '
  1594. 'string instead: "char kFoo[]".'
  1595. ' [runtime/string] [4]')
  1596. self.assert_lint('static string foo;',
  1597. 'For a static/global string constant, use a C style '
  1598. 'string instead: "static char foo[]".'
  1599. ' [runtime/string] [4]')
  1600. self.assert_lint('static const string foo;',
  1601. 'For a static/global string constant, use a C style '
  1602. 'string instead: "static const char foo[]".'
  1603. ' [runtime/string] [4]')
  1604. self.assert_lint('string Foo::bar;',
  1605. 'For a static/global string constant, use a C style '
  1606. 'string instead: "char Foo::bar[]".'
  1607. ' [runtime/string] [4]')
  1608. # Rare case.
  1609. self.assert_lint('string foo("foobar");',
  1610. 'For a static/global string constant, use a C style '
  1611. 'string instead: "char foo[]".'
  1612. ' [runtime/string] [4]')
  1613. # Should not catch local or member variables.
  1614. self.assert_lint(' string foo', '')
  1615. # Should not catch functions.
  1616. self.assert_lint('string EmptyString() { return ""; }', '')
  1617. self.assert_lint('string EmptyString () { return ""; }', '')
  1618. self.assert_lint('string VeryLongNameFunctionSometimesEndsWith(\n'
  1619. ' VeryLongNameType veryLongNameVariable) { }', '')
  1620. self.assert_lint('template<>\n'
  1621. 'string FunctionTemplateSpecialization<SomeType>(\n'
  1622. ' int x) { return ""; }', '')
  1623. self.assert_lint('template<>\n'
  1624. 'string FunctionTemplateSpecialization<vector<A::B>* >(\n'
  1625. ' int x) { return ""; }', '')
  1626. # should not catch methods of template classes.
  1627. self.assert_lint('string Class<Type>::Method() const\n'
  1628. '{\n'
  1629. ' return "";\n'
  1630. '}\n', '')
  1631. self.assert_lint('string Class<Type>::Method(\n'
  1632. ' int arg) const\n'
  1633. '{\n'
  1634. ' return "";\n'
  1635. '}\n', '')
  1636. def test_no_spaces_in_function_calls(self):
  1637. self.assert_lint('TellStory(1, 3);',
  1638. '')
  1639. self.assert_lint('TellStory(1, 3 );',
  1640. 'Extra space before )'
  1641. ' [whitespace/parens] [2]')
  1642. self.assert_lint('TellStory(1 /* wolf */, 3 /* pigs */);',
  1643. '')
  1644. self.assert_multi_line_lint('#endif\n );',
  1645. '')
  1646. def test_one_spaces_between_code_and_comments(self):
  1647. self.assert_lint('} // namespace foo',
  1648. '')
  1649. self.assert_lint('}// namespace foo',
  1650. 'One space before end of line comments'
  1651. ' [whitespace/comments] [5]')
  1652. self.assert_lint('printf("foo"); // Outside quotes.',
  1653. '')
  1654. self.assert_lint('int i = 0; // Having one space is fine.','')
  1655. self.assert_lint('int i = 0; // Having two spaces is bad.',
  1656. 'One space before end of line comments'
  1657. ' [whitespace/comments] [5]')
  1658. self.assert_lint('int i = 0; // Having three spaces is bad.',
  1659. 'One space before end of line comments'
  1660. ' [whitespace/comments] [5]')
  1661. self.assert_lint('// Top level comment', '')
  1662. self.assert_lint(' // Line starts with four spaces.', '')
  1663. self.assert_lint('foo();\n'
  1664. '{ // A scope is opening.', '')
  1665. self.assert_lint(' foo();\n'
  1666. ' { // An indented scope is opening.', '')
  1667. self.assert_lint('if (foo) { // not a pure scope',
  1668. '')
  1669. self.assert_lint('printf("// In quotes.")', '')
  1670. self.assert_lint('printf("\\"%s // In quotes.")', '')
  1671. self.assert_lint('printf("%s", "// In quotes.")', '')
  1672. def test_one_spaces_after_punctuation_in_comments(self):
  1673. self.assert_lint('int a; // This is a sentence.',
  1674. '')
  1675. self.assert_lint('int a; // This is a sentence. ',
  1676. 'Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4]')
  1677. self.assert_lint('int a; // This is a sentence. This is a another sentence.',
  1678. '')
  1679. self.assert_lint('int a; // This is a sentence. This is a another sentence.',
  1680. 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
  1681. self.assert_lint('int a; // This is a sentence! This is a another sentence.',
  1682. 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
  1683. self.assert_lint('int a; // Why did I write this? This is a another sentence.',
  1684. 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
  1685. self.assert_lint('int a; // Elementary, my dear.',
  1686. 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
  1687. self.assert_lint('int a; // The following should be clear: Is it?',
  1688. 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
  1689. self.assert_lint('int a; // Look at the follow semicolon; I hope this gives an error.',
  1690. 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
  1691. def test_space_after_comment_marker(self):
  1692. self.assert_lint('//', '')
  1693. self.assert_lint('//x', 'Should have a space between // and comment'
  1694. ' [whitespace/comments] [4]')
  1695. self.assert_lint('// x', '')
  1696. self.assert_lint('//----', '')
  1697. self.assert_lint('//====', '')
  1698. self.assert_lint('//////', '')
  1699. self.assert_lint('////// x', '')
  1700. self.assert_lint('/// x', '')
  1701. self.assert_lint('////x', 'Should have a space between // and comment'
  1702. ' [whitespace/comments] [4]')
  1703. def test_newline_at_eof(self):
  1704. def do_test(self, data, is_missing_eof):
  1705. error_collector = ErrorCollector(self.assert_)
  1706. self.process_file_data('foo.cpp', 'cpp', data.split('\n'),
  1707. error_collector)
  1708. # The warning appears only once.
  1709. self.assertEquals(
  1710. int(is_missing_eof),
  1711. error_collector.results().count(
  1712. 'Could not find a newline character at the end of the file.'
  1713. ' [whitespace/ending_newline] [5]'))
  1714. do_test(self, '// Newline\n// at EOF\n', False)
  1715. do_test(self, '// No newline\n// at EOF', True)
  1716. def test_invalid_utf8(self):
  1717. def do_test(self, raw_bytes, has_invalid_utf8):
  1718. error_collector = ErrorCollector(self.assert_)
  1719. self.process_file_data('foo.cpp', 'cpp',
  1720. unicode(raw_bytes, 'utf8', 'replace').split('\n'),
  1721. error_collector)
  1722. # The warning appears only once.
  1723. self.assertEquals(
  1724. int(has_invalid_utf8),
  1725. error_collector.results().count(
  1726. 'Line contains invalid UTF-8'
  1727. ' (or Unicode replacement character).'
  1728. ' [readability/utf8] [5]'))
  1729. do_test(self, 'Hello world\n', False)
  1730. do_test(self, '\xe9\x8e\xbd\n', False)
  1731. do_test(self, '\xe9x\x8e\xbd\n', True)
  1732. # This is the encoding of the replacement character itself (which
  1733. # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')).
  1734. do_test(self, '\xef\xbf\xbd\n', True)
  1735. def test_is_blank_line(self):
  1736. self.assert_(cpp_style.is_blank_line(''))
  1737. self.assert_(cpp_style.is_blank_line(' '))
  1738. self.assert_(cpp_style.is_blank_line(' \t\r\n'))
  1739. self.assert_(not cpp_style.is_blank_line('int a;'))
  1740. self.assert_(not cpp_style.is_blank_line('{'))
  1741. def test_blank_lines_check(self):
  1742. self.assert_blank_lines_check(['{\n', '\n', '\n', '}\n'], 1, 1)
  1743. self.assert_blank_lines_check([' if (foo) {\n', '\n', ' }\n'], 1, 1)
  1744. self.assert_blank_lines_check(
  1745. ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0)
  1746. self.assert_blank_lines_check(['\n', 'run("{");\n', '\n'], 0, 0)
  1747. self.assert_blank_lines_check(['\n', ' if (foo) { return 0; }\n', '\n'], 0, 0)
  1748. def test_allow_blank_line_before_closing_namespace(self):
  1749. error_collector = ErrorCollector(self.assert_)
  1750. self.process_file_data('foo.cpp', 'cpp',
  1751. ['namespace {', '', '} // namespace'],
  1752. error_collector)
  1753. self.assertEquals(0, error_collector.results().count(
  1754. 'Blank line at the end of a code block. Is this needed?'
  1755. ' [whitespace/blank_line] [3]'))
  1756. def test_allow_blank_line_before_if_else_chain(self):
  1757. error_collector = ErrorCollector(self.assert_)
  1758. self.process_file_data('foo.cpp', 'cpp',
  1759. ['if (hoge) {',
  1760. '', # No warning
  1761. '} else if (piyo) {',
  1762. '', # No warning
  1763. '} else if (piyopiyo) {',
  1764. ' hoge = true;', # No warning
  1765. '} else {',
  1766. '', # Warning on this line
  1767. '}'],
  1768. error_collector)
  1769. self.assertEquals(1, error_collector.results().count(
  1770. 'Blank line at the end of a code block. Is this needed?'
  1771. ' [whitespace/blank_line] [3]'))
  1772. def test_else_on_same_line_as_closing_braces(self):
  1773. error_collector = ErrorCollector(self.assert_)
  1774. self.process_file_data('foo.cpp', 'cpp',
  1775. ['if (hoge) {',
  1776. '',
  1777. '}',
  1778. ' else {' # Warning on this line
  1779. '',
  1780. '}'],
  1781. error_collector)
  1782. self.assertEquals(1, error_collector.results().count(
  1783. 'An else should appear on the same line as the preceding }'
  1784. ' [whitespace/newline] [4]'))
  1785. def test_else_clause_not_on_same_line_as_else(self):
  1786. self.assert_lint(' else DoSomethingElse();',
  1787. 'Else clause should never be on same line as else '
  1788. '(use 2 lines) [whitespace/newline] [4]')
  1789. self.assert_lint(' else ifDoSomethingElse();',
  1790. 'Else clause should never be on same line as else '
  1791. '(use 2 lines) [whitespace/newline] [4]')
  1792. self.assert_lint(' else if (blah) {', '')
  1793. self.assert_lint(' variable_ends_in_else = true;', '')
  1794. def test_comma(self):
  1795. self.assert_lint('a = f(1,2);',
  1796. 'Missing space after , [whitespace/comma] [3]')
  1797. self.assert_lint('int tmp=a,a=b,b=tmp;',
  1798. ['Missing spaces around = [whitespace/operators] [4]',
  1799. 'Missing space after , [whitespace/comma] [3]'])
  1800. self.assert_lint('f(a, /* name */ b);', '')
  1801. self.assert_lint('f(a, /* name */b);', '')
  1802. def test_declaration(self):
  1803. self.assert_lint('int a;', '')
  1804. self.assert_lint('int a;', 'Extra space between int and a [whitespace/declaration] [3]')
  1805. self.assert_lint('int* a;', 'Extra space between int* and a [whitespace/declaration] [3]')
  1806. self.assert_lint('else if { }', '')
  1807. self.assert_lint('else if { }', 'Extra space between else and if [whitespace/declaration] [3]')
  1808. def test_pointer_reference_marker_location(self):
  1809. self.assert_lint('int* b;', '', 'foo.cpp')
  1810. self.assert_lint('int *b;',
  1811. 'Declaration has space between type name and * in int *b [whitespace/declaration] [3]',
  1812. 'foo.cpp')
  1813. self.assert_lint('return *b;', '', 'foo.cpp')
  1814. self.assert_lint('delete *b;', '', 'foo.cpp')
  1815. self.assert_lint('int *b;', '', 'foo.c')
  1816. self.assert_lint('int* b;',
  1817. 'Declaration has space between * and variable name in int* b [whitespace/declaration] [3]',
  1818. 'foo.c')
  1819. self.assert_lint('int& b;', '', 'foo.cpp')
  1820. self.assert_lint('int &b;',
  1821. 'Declaration has space between type name and & in int &b [whitespace/declaration] [3]',
  1822. 'foo.cpp')
  1823. self.assert_lint('return &b;', '', 'foo.cpp')
  1824. def test_indent(self):
  1825. self.assert_lint('static int noindent;', '')
  1826. self.assert_lint(' int fourSpaceIndent;', '')
  1827. self.assert_lint(' int oneSpaceIndent;',
  1828. 'Weird number of spaces at line-start. '
  1829. 'Are you using a 4-space indent? [whitespace/indent] [3]')
  1830. self.assert_lint(' int threeSpaceIndent;',
  1831. 'Weird number of spaces at line-start. '
  1832. 'Are you using a 4-space indent? [whitespace/indent] [3]')
  1833. self.assert_lint(' char* oneSpaceIndent = "public:";',
  1834. 'Weird number of spaces at line-start. '
  1835. 'Are you using a 4-space indent? [whitespace/indent] [3]')
  1836. self.assert_lint(' public:', '')
  1837. self.assert_lint(' public:', '')
  1838. self.assert_lint(' public:', '')
  1839. def test_label(self):
  1840. self.assert_lint('public:',
  1841. 'Labels should always be indented at least one space. '
  1842. 'If this is a member-initializer list in a constructor, '
  1843. 'the colon should be on the line after the definition '
  1844. 'header. [whitespace/labels] [4]')
  1845. self.assert_lint(' public:', '')
  1846. self.assert_lint(' public:', '')
  1847. self.assert_lint(' public:', '')
  1848. self.assert_lint(' public:', '')
  1849. self.assert_lint(' public:', '')
  1850. def test_not_alabel(self):
  1851. self.assert_lint('MyVeryLongNamespace::MyVeryLongClassName::', '')
  1852. def test_tab(self):
  1853. self.assert_lint('\tint a;',
  1854. 'Tab found; better to use spaces [whitespace/tab] [1]')
  1855. self.assert_lint('int a = 5;\t// set a to 5',
  1856. 'Tab found; better to use spaces [whitespace/tab] [1]')
  1857. def test_unnamed_namespaces_in_headers(self):
  1858. self.assert_language_rules_check(
  1859. 'foo.h', 'namespace {',
  1860. 'Do not use unnamed namespaces in header files. See'
  1861. ' http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
  1862. ' for more information. [build/namespaces] [4]')
  1863. # namespace registration macros are OK.
  1864. self.assert_language_rules_check('foo.h', 'namespace { \\', '')
  1865. # named namespaces are OK.
  1866. self.assert_language_rules_check('foo.h', 'namespace foo {', '')
  1867. self.assert_language_rules_check('foo.h', 'namespace foonamespace {', '')
  1868. self.assert_language_rules_check('foo.cpp', 'namespace {', '')
  1869. self.assert_language_rules_check('foo.cpp', 'namespace foo {', '')
  1870. def test_build_class(self):
  1871. # Test that the linter can parse to the end of class definitions,
  1872. # and that it will report when it can't.
  1873. # Use multi-line linter because it performs the ClassState check.
  1874. self.assert_multi_line_lint(
  1875. 'class Foo {',
  1876. 'Failed to find complete declaration of class Foo'
  1877. ' [build/class] [5]')
  1878. # Don't warn on forward declarations of various types.
  1879. self.assert_multi_line_lint(
  1880. 'class Foo;',
  1881. '')
  1882. self.assert_multi_line_lint(
  1883. '''struct Foo*
  1884. foo = NewFoo();''',
  1885. '')
  1886. # Here is an example where the linter gets confused, even though
  1887. # the code doesn't violate the style guide.
  1888. self.assert_multi_line_lint(
  1889. '''class Foo
  1890. #ifdef DERIVE_FROM_GOO
  1891. : public Goo {
  1892. #else
  1893. : public Hoo {
  1894. #endif
  1895. };''',
  1896. 'Failed to find complete declaration of class Foo'
  1897. ' [build/class] [5]')
  1898. def test_build_end_comment(self):
  1899. # The crosstool compiler we currently use will fail to compile the
  1900. # code in this test, so we might consider removing the lint check.
  1901. self.assert_lint('#endif Not a comment',
  1902. 'Uncommented text after #endif is non-standard.'
  1903. ' Use a comment.'
  1904. ' [build/endif_comment] [5]')
  1905. def test_build_forward_decl(self):
  1906. # The crosstool compiler we currently use will fail to compile the
  1907. # code in this test, so we might consider removing the lint check.
  1908. self.assert_lint('class Foo::Goo;',
  1909. 'Inner-style forward declarations are invalid.'
  1910. ' Remove this line.'
  1911. ' [build/forward_decl] [5]')
  1912. def test_build_header_guard(self):
  1913. file_path = 'mydir/Foo.h'
  1914. # We can't rely on our internal stuff to get a sane path on the open source
  1915. # side of things, so just parse out the suggested header guard. This
  1916. # doesn't allow us to test the suggested header guard, but it does let us
  1917. # test all the other header tests.
  1918. error_collector = ErrorCollector(self.assert_)
  1919. self.process_file_data(file_path, 'h', [], error_collector)
  1920. expected_guard = ''
  1921. matcher = re.compile(
  1922. 'No \#ifndef header guard found\, suggested CPP variable is\: ([A-Za-z_0-9]+) ')
  1923. for error in error_collector.result_list():
  1924. matches = matcher.match(error)
  1925. if matches:
  1926. expected_guard = matches.group(1)
  1927. break
  1928. # Make sure we extracted something for our header guard.
  1929. self.assertNotEqual(expected_guard, '')
  1930. # Wrong guard
  1931. error_collector = ErrorCollector(self.assert_)
  1932. self.process_file_data(file_path, 'h',
  1933. ['#ifndef FOO_H', '#define FOO_H'], error_collector)
  1934. self.assertEquals(
  1935. 1,
  1936. error_collector.result_list().count(
  1937. '#ifndef header guard has wrong style, please use: %s'
  1938. ' [build/header_guard] [5]' % expected_guard),
  1939. error_collector.result_list())
  1940. # No define
  1941. error_collector = ErrorCollector(self.assert_)
  1942. self.process_file_data(file_path, 'h',
  1943. ['#ifndef %s' % expected_guard], error_collector)
  1944. self.assertEquals(
  1945. 1,
  1946. error_collector.result_list().count(
  1947. 'No #ifndef header guard found, suggested CPP variable is: %s'
  1948. ' [build/header_guard] [5]' % expected_guard),
  1949. error_collector.result_list())
  1950. # Mismatched define
  1951. error_collector = ErrorCollector(self.assert_)
  1952. self.process_file_data(file_path, 'h',
  1953. ['#ifndef %s' % expected_guard,
  1954. '#define FOO_H'],
  1955. error_collector)
  1956. self.assertEquals(
  1957. 1,
  1958. error_collector.result_list().count(
  1959. 'No #ifndef header guard found, suggested CPP variable is: %s'
  1960. ' [build/header_guard] [5]' % expected_guard),
  1961. error_collector.result_list())
  1962. # No header guard errors
  1963. error_collector = ErrorCollector(self.assert_)
  1964. self.process_file_data(file_path, 'h',
  1965. ['#ifndef %s' % expected_guard,
  1966. '#define %s' % expected_guard,
  1967. '#endif // %s' % expected_guard],
  1968. error_collector)
  1969. for line in error_collector.result_list():
  1970. if line.find('build/header_guard') != -1:
  1971. self.fail('Unexpected error: %s' % line)
  1972. # Completely incorrect header guard
  1973. error_collector = ErrorCollector(self.assert_)
  1974. self.process_file_data(file_path, 'h',
  1975. ['#ifndef FOO',
  1976. '#define FOO',
  1977. '#endif // FOO'],
  1978. error_collector)
  1979. self.assertEquals(
  1980. 1,
  1981. error_collector.result_list().count(
  1982. '#ifndef header guard has wrong style, please use: %s'
  1983. ' [build/header_guard] [5]' % expected_guard),
  1984. error_collector.result_list())
  1985. # Special case for flymake
  1986. error_collector = ErrorCollector(self.assert_)
  1987. self.process_file_data('mydir/Foo_flymake.h', 'h',
  1988. ['#ifndef %s' % expected_guard,
  1989. '#define %s' % expected_guard,
  1990. '#endif // %s' % expected_guard],
  1991. error_collector)
  1992. for line in error_collector.result_list():
  1993. if line.find('build/header_guard') != -1:
  1994. self.fail('Unexpected error: %s' % line)
  1995. error_collector = ErrorCollector(self.assert_)
  1996. self.process_file_data('mydir/Foo_flymake.h', 'h', [], error_collector)
  1997. self.assertEquals(
  1998. 1,
  1999. error_collector.result_list().count(
  2000. 'No #ifndef header guard found, suggested CPP variable is: %s'
  2001. ' [build/header_guard] [5]' % expected_guard),
  2002. error_collector.result_list())
  2003. # Verify that we don't blindly suggest the WTF prefix for all headers.
  2004. self.assertFalse(expected_guard.startswith('WTF_'))
  2005. # Allow the WTF_ prefix for files in that directory.
  2006. header_guard_filter = FilterConfiguration(('-', '+build/header_guard'))
  2007. error_collector = ErrorCollector(self.assert_, header_guard_filter)
  2008. self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h',
  2009. ['#ifndef WTF_TestName_h', '#define WTF_TestName_h'],
  2010. error_collector)
  2011. self.assertEquals(0, len(error_collector.result_list()),
  2012. error_collector.result_list())
  2013. # Also allow the non WTF_ prefix for files in that directory.
  2014. error_collector = ErrorCollector(self.assert_, header_guard_filter)
  2015. self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h',
  2016. ['#ifndef TestName_h', '#define TestName_h'],
  2017. error_collector)
  2018. self.assertEquals(0, len(error_collector.result_list()),
  2019. error_collector.result_list())
  2020. # Verify that we suggest the WTF prefix version.
  2021. error_collector = ErrorCollector(self.assert_, header_guard_filter)
  2022. self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h',
  2023. ['#ifndef BAD_TestName_h', '#define BAD_TestName_h'],
  2024. error_collector)
  2025. self.assertEquals(
  2026. 1,
  2027. error_collector.result_list().count(
  2028. '#ifndef header guard has wrong style, please use: WTF_TestName_h'
  2029. ' [build/header_guard] [5]'),
  2030. error_collector.result_list())
  2031. def test_build_printf_format(self):
  2032. self.assert_lint(
  2033. r'printf("\%%d", value);',
  2034. '%, [, (, and { are undefined character escapes. Unescape them.'
  2035. ' [build/printf_format] [3]')
  2036. self.assert_lint(
  2037. r'snprintf(buffer, sizeof(buffer), "\[%d", value);',
  2038. '%, [, (, and { are undefined character escapes. Unescape them.'
  2039. ' [build/printf_format] [3]')
  2040. self.assert_lint(
  2041. r'fprintf(file, "\(%d", value);',
  2042. '%, [, (, and { are undefined character escapes. Unescape them.'
  2043. ' [build/printf_format] [3]')
  2044. self.assert_lint(
  2045. r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);',
  2046. '%, [, (, and { are undefined character escapes. Unescape them.'
  2047. ' [build/printf_format] [3]')
  2048. # Don't warn if double-slash precedes the symbol
  2049. self.assert_lint(r'printf("\\%%%d", value);',
  2050. '')
  2051. def test_runtime_printf_format(self):
  2052. self.assert_lint(
  2053. r'fprintf(file, "%q", value);',
  2054. '%q in format strings is deprecated. Use %ll instead.'
  2055. ' [runtime/printf_format] [3]')
  2056. self.assert_lint(
  2057. r'aprintf(file, "The number is %12q", value);',
  2058. '%q in format strings is deprecated. Use %ll instead.'
  2059. ' [runtime/printf_format] [3]')
  2060. self.assert_lint(
  2061. r'printf(file, "The number is" "%-12q", value);',
  2062. '%q in format strings is deprecated. Use %ll instead.'
  2063. ' [runtime/printf_format] [3]')
  2064. self.assert_lint(
  2065. r'printf(file, "The number is" "%+12q", value);',
  2066. '%q in format strings is deprecated. Use %ll instead.'
  2067. ' [runtime/printf_format] [3]')
  2068. self.assert_lint(
  2069. r'printf(file, "The number is" "% 12q", value);',
  2070. '%q in format strings is deprecated. Use %ll instead.'
  2071. ' [runtime/printf_format] [3]')
  2072. self.assert_lint(
  2073. r'snprintf(file, "Never mix %d and %1$d parmaeters!", value);',
  2074. '%N$ formats are unconventional. Try rewriting to avoid them.'
  2075. ' [runtime/printf_format] [2]')
  2076. def assert_lintLogCodeOnError(self, code, expected_message):
  2077. # Special assert_lint which logs the input code on error.
  2078. result = self.perform_single_line_lint(code, 'foo.cpp')
  2079. if result != expected_message:
  2080. self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"'
  2081. % (code, result, expected_message))
  2082. def test_build_storage_class(self):
  2083. qualifiers = [None, 'const', 'volatile']
  2084. signs = [None, 'signed', 'unsigned']
  2085. types = ['void', 'char', 'int', 'float', 'double',
  2086. 'schar', 'int8', 'uint8', 'int16', 'uint16',
  2087. 'int32', 'uint32', 'int64', 'uint64']
  2088. storage_classes = ['auto', 'extern', 'register', 'static', 'typedef']
  2089. build_storage_class_error_message = (
  2090. 'Storage class (static, extern, typedef, etc) should be first.'
  2091. ' [build/storage_class] [5]')
  2092. # Some explicit cases. Legal in C++, deprecated in C99.
  2093. self.assert_lint('const int static foo = 5;',
  2094. build_storage_class_error_message)
  2095. self.assert_lint('char static foo;',
  2096. build_storage_class_error_message)
  2097. self.assert_lint('double const static foo = 2.0;',
  2098. build_storage_class_error_message)
  2099. self.assert_lint('uint64 typedef unsignedLongLong;',
  2100. build_storage_class_error_message)
  2101. self.assert_lint('int register foo = 0;',
  2102. build_storage_class_error_message)
  2103. # Since there are a very large number of possibilities, randomly
  2104. # construct declarations.
  2105. # Make sure that the declaration is logged if there's an error.
  2106. # Seed generator with an integer for absolute reproducibility.
  2107. random.seed(25)
  2108. for unused_i in range(10):
  2109. # Build up random list of non-storage-class declaration specs.
  2110. other_decl_specs = [random.choice(qualifiers), random.choice(signs),
  2111. random.choice(types)]
  2112. # remove None
  2113. other_decl_specs = filter(lambda x: x is not None, other_decl_specs)
  2114. # shuffle
  2115. random.shuffle(other_decl_specs)
  2116. # insert storage class after the first
  2117. storage_class = random.choice(storage_classes)
  2118. insertion_point = random.randint(1, len(other_decl_specs))
  2119. decl_specs = (other_decl_specs[0:insertion_point]
  2120. + [storage_class]
  2121. + other_decl_specs[insertion_point:])
  2122. self.assert_lintLogCodeOnError(
  2123. ' '.join(decl_specs) + ';',
  2124. build_storage_class_error_message)
  2125. # but no error if storage class is first
  2126. self.assert_lintLogCodeOnError(
  2127. storage_class + ' ' + ' '.join(other_decl_specs),
  2128. '')
  2129. def test_legal_copyright(self):
  2130. legal_copyright_message = (
  2131. 'No copyright message found. '
  2132. 'You should have a line: "Copyright [year] <Copyright Owner>"'
  2133. ' [legal/copyright] [5]')
  2134. copyright_line = '// Copyright 2008 Google Inc. All Rights Reserved.'
  2135. file_path = 'mydir/googleclient/foo.cpp'
  2136. # There should be a copyright message in the first 10 lines
  2137. error_collector = ErrorCollector(self.assert_)
  2138. self.process_file_data(file_path, 'cpp', [], error_collector)
  2139. self.assertEquals(
  2140. 1,
  2141. error_collector.result_list().count(legal_copyright_message))
  2142. error_collector = ErrorCollector(self.assert_)
  2143. self.process_file_data(
  2144. file_path, 'cpp',
  2145. ['' for unused_i in range(10)] + [copyright_line],
  2146. error_collector)
  2147. self.assertEquals(
  2148. 1,
  2149. error_collector.result_list().count(legal_copyright_message))
  2150. # Test that warning isn't issued if Copyright line appears early enough.
  2151. error_collector = ErrorCollector(self.assert_)
  2152. self.process_file_data(file_path, 'cpp', [copyright_line], error_collector)
  2153. for message in error_collector.result_list():
  2154. if message.find('legal/copyright') != -1:
  2155. self.fail('Unexpected error: %s' % message)
  2156. error_collector = ErrorCollector(self.assert_)
  2157. self.process_file_data(
  2158. file_path, 'cpp',
  2159. ['' for unused_i in range(9)] + [copyright_line],
  2160. error_collector)
  2161. for message in error_collector.result_list():
  2162. if message.find('legal/copyright') != -1:
  2163. self.fail('Unexpected error: %s' % message)
  2164. def test_invalid_increment(self):
  2165. self.assert_lint('*count++;',
  2166. 'Changing pointer instead of value (or unused value of '
  2167. 'operator*). [runtime/invalid_increment] [5]')
  2168. # Integral bitfields must be declared with either signed or unsigned keyword.
  2169. def test_plain_integral_bitfields(self):
  2170. errmsg = ('Please declare integral type bitfields with either signed or unsigned. [runtime/bitfields] [5]')
  2171. self.assert_lint('int a : 30;', errmsg)
  2172. self.assert_lint('mutable short a : 14;', errmsg)
  2173. self.assert_lint('const char a : 6;', errmsg)
  2174. self.assert_lint('long int a : 30;', errmsg)
  2175. self.assert_lint('int a = 1 ? 0 : 30;', '')
  2176. class CleansedLinesTest(unittest.TestCase):
  2177. def test_init(self):
  2178. lines = ['Line 1',
  2179. 'Line 2',
  2180. 'Line 3 // Comment test',
  2181. 'Line 4 "foo"']
  2182. clean_lines = cpp_style.CleansedLines(lines)
  2183. self.assertEquals(lines, clean_lines.raw_lines)
  2184. self.assertEquals(4, clean_lines.num_lines())
  2185. self.assertEquals(['Line 1',
  2186. 'Line 2',
  2187. 'Line 3 ',
  2188. 'Line 4 "foo"'],
  2189. clean_lines.lines)
  2190. self.assertEquals(['Line 1',
  2191. 'Line 2',
  2192. 'Line 3 ',
  2193. 'Line 4 ""'],
  2194. clean_lines.elided)
  2195. def test_init_empty(self):
  2196. clean_lines = cpp_style.CleansedLines([])
  2197. self.assertEquals([], clean_lines.raw_lines)
  2198. self.assertEquals(0, clean_lines.num_lines())
  2199. def test_collapse_strings(self):
  2200. collapse = cpp_style.CleansedLines.collapse_strings
  2201. self.assertEquals('""', collapse('""')) # "" (empty)
  2202. self.assertEquals('"""', collapse('"""')) # """ (bad)
  2203. self.assertEquals('""', collapse('"xyz"')) # "xyz" (string)
  2204. self.assertEquals('""', collapse('"\\\""')) # "\"" (string)
  2205. self.assertEquals('""', collapse('"\'"')) # "'" (string)
  2206. self.assertEquals('"\"', collapse('"\"')) # "\" (bad)
  2207. self.assertEquals('""', collapse('"\\\\"')) # "\\" (string)
  2208. self.assertEquals('"', collapse('"\\\\\\"')) # "\\\" (bad)
  2209. self.assertEquals('""', collapse('"\\\\\\\\"')) # "\\\\" (string)
  2210. self.assertEquals('\'\'', collapse('\'\'')) # '' (empty)
  2211. self.assertEquals('\'\'', collapse('\'a\'')) # 'a' (char)
  2212. self.assertEquals('\'\'', collapse('\'\\\'\'')) # '\'' (char)
  2213. self.assertEquals('\'', collapse('\'\\\'')) # '\' (bad)
  2214. self.assertEquals('', collapse('\\012')) # '\012' (char)
  2215. self.assertEquals('', collapse('\\xfF0')) # '\xfF0' (char)
  2216. self.assertEquals('', collapse('\\n')) # '\n' (char)
  2217. self.assertEquals('\#', collapse('\\#')) # '\#' (bad)
  2218. self.assertEquals('StringReplace(body, "", "");',
  2219. collapse('StringReplace(body, "\\\\", "\\\\\\\\");'))
  2220. self.assertEquals('\'\' ""',
  2221. collapse('\'"\' "foo"'))
  2222. class OrderOfIncludesTest(CppStyleTestBase):
  2223. def setUp(self):
  2224. self.include_state = cpp_style._IncludeState()
  2225. # Cheat os.path.abspath called in FileInfo class.
  2226. self.os_path_abspath_orig = os.path.abspath
  2227. os.path.abspath = lambda value: value
  2228. def tearDown(self):
  2229. os.path.abspath = self.os_path_abspath_orig
  2230. def test_try_drop_common_suffixes(self):
  2231. self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h'))
  2232. self.assertEqual('foo/bar/foo',
  2233. cpp_style._drop_common_suffixes('foo/bar/foo_inl.h'))
  2234. self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp'))
  2235. self.assertEqual('foo/foo_unusualinternal',
  2236. cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h'))
  2237. self.assertEqual('',
  2238. cpp_style._drop_common_suffixes('_test.cpp'))
  2239. self.assertEqual('test',
  2240. cpp_style._drop_common_suffixes('test.cpp'))
  2241. class OrderOfIncludesTest(CppStyleTestBase):
  2242. def setUp(self):
  2243. self.include_state = cpp_style._IncludeState()
  2244. # Cheat os.path.abspath called in FileInfo class.
  2245. self.os_path_abspath_orig = os.path.abspath
  2246. self.os_path_isfile_orig = os.path.isfile
  2247. os.path.abspath = lambda value: value
  2248. def tearDown(self):
  2249. os.path.abspath = self.os_path_abspath_orig
  2250. os.path.isfile = self.os_path_isfile_orig
  2251. def test_check_next_include_order__no_config(self):
  2252. self.assertEqual('Header file should not contain WebCore config.h.',
  2253. self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, True, True))
  2254. def test_check_next_include_order__no_self(self):
  2255. self.assertEqual('Header file should not contain itself.',
  2256. self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, True, True))
  2257. # Test actual code to make sure that header types are correctly assigned.
  2258. self.assert_language_rules_check('Foo.h',
  2259. '#include "Foo.h"\n',
  2260. 'Header file should not contain itself. Should be: alphabetically sorted.'
  2261. ' [build/include_order] [4]')
  2262. self.assert_language_rules_check('FooBar.h',
  2263. '#include "Foo.h"\n',
  2264. '')
  2265. def test_check_next_include_order__likely_then_config(self):
  2266. self.assertEqual('Found header this file implements before WebCore config.h.',
  2267. self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False, True))
  2268. self.assertEqual('Found WebCore config.h after a header this file implements.',
  2269. self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
  2270. def test_check_next_include_order__other_then_config(self):
  2271. self.assertEqual('Found other header before WebCore config.h.',
  2272. self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False, True))
  2273. self.assertEqual('Found WebCore config.h after other header.',
  2274. self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
  2275. def test_check_next_include_order__config_then_other_then_likely(self):
  2276. self.assertEqual('', self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
  2277. self.assertEqual('Found other header before a header this file implements.',
  2278. self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False, True))
  2279. self.assertEqual('Found header this file implements after other header.',
  2280. self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False, True))
  2281. def test_check_alphabetical_include_order(self):
  2282. self.assert_language_rules_check('foo.h',
  2283. '#include "a.h"\n'
  2284. '#include "c.h"\n'
  2285. '#include "b.h"\n',
  2286. 'Alphabetical sorting problem. [build/include_order] [4]')
  2287. self.assert_language_rules_check('foo.h',
  2288. '#include "a.h"\n'
  2289. '#include "b.h"\n'
  2290. '#include "c.h"\n',
  2291. '')
  2292. self.assert_language_rules_check('foo.h',
  2293. '#include <assert.h>\n'
  2294. '#include "bar.h"\n',
  2295. 'Alphabetical sorting problem. [build/include_order] [4]')
  2296. self.assert_language_rules_check('foo.h',
  2297. '#include "bar.h"\n'
  2298. '#include <assert.h>\n',
  2299. '')
  2300. def test_check_line_break_after_own_header(self):
  2301. self.assert_language_rules_check('foo.cpp',
  2302. '#include "config.h"\n'
  2303. '#include "foo.h"\n'
  2304. '#include "bar.h"\n',
  2305. 'You should add a blank line after implementation file\'s own header. [build/include_order] [4]')
  2306. self.assert_language_rules_check('foo.cpp',
  2307. '#include "config.h"\n'
  2308. '#include "foo.h"\n'
  2309. '\n'
  2310. '#include "bar.h"\n',
  2311. '')
  2312. def test_check_preprocessor_in_include_section(self):
  2313. self.assert_language_rules_check('foo.cpp',
  2314. '#include "config.h"\n'
  2315. '#include "foo.h"\n'
  2316. '\n'
  2317. '#ifdef BAZ\n'
  2318. '#include "baz.h"\n'
  2319. '#else\n'
  2320. '#include "foobar.h"\n'
  2321. '#endif"\n'
  2322. '#include "bar.h"\n', # No flag because previous is in preprocessor section
  2323. '')
  2324. self.assert_language_rules_check('foo.cpp',
  2325. '#include "config.h"\n'
  2326. '#include "foo.h"\n'
  2327. '\n'
  2328. '#ifdef BAZ\n'
  2329. '#include "baz.h"\n'
  2330. '#endif"\n'
  2331. '#include "bar.h"\n'
  2332. '#include "a.h"\n', # Should still flag this.
  2333. 'Alphabetical sorting problem. [build/include_order] [4]')
  2334. self.assert_language_rules_check('foo.cpp',
  2335. '#include "config.h"\n'
  2336. '#include "foo.h"\n'
  2337. '\n'
  2338. '#ifdef BAZ\n'
  2339. '#include "baz.h"\n'
  2340. '#include "bar.h"\n' #Should still flag this
  2341. '#endif"\n',
  2342. 'Alphabetical sorting problem. [build/include_order] [4]')
  2343. self.assert_language_rules_check('foo.cpp',
  2344. '#include "config.h"\n'
  2345. '#include "foo.h"\n'
  2346. '\n'
  2347. '#ifdef BAZ\n'
  2348. '#include "baz.h"\n'
  2349. '#endif"\n'
  2350. '#ifdef FOOBAR\n'
  2351. '#include "foobar.h"\n'
  2352. '#endif"\n'
  2353. '#include "bar.h"\n'
  2354. '#include "a.h"\n', # Should still flag this.
  2355. 'Alphabetical sorting problem. [build/include_order] [4]')
  2356. # Check that after an already included error, the sorting rules still work.
  2357. self.assert_language_rules_check('foo.cpp',
  2358. '#include "config.h"\n'
  2359. '#include "foo.h"\n'
  2360. '\n'
  2361. '#include "foo.h"\n'
  2362. '#include "g.h"\n',
  2363. '"foo.h" already included at foo.cpp:2 [build/include] [4]')
  2364. def test_primary_header(self):
  2365. # File with non-existing primary header should not produce errors.
  2366. self.assert_language_rules_check('foo.cpp',
  2367. '#include "config.h"\n'
  2368. '\n'
  2369. '#include "bar.h"\n',
  2370. '')
  2371. # Pretend that header files exist.
  2372. os.path.isfile = lambda filename: True
  2373. # Missing include for existing primary header -> error.
  2374. self.assert_language_rules_check('foo.cpp',
  2375. '#include "config.h"\n'
  2376. '\n'
  2377. '#include "bar.h"\n',
  2378. 'Found other header before a header this file implements. '
  2379. 'Should be: config.h, primary header, blank line, and then '
  2380. 'alphabetically sorted. [build/include_order] [4]')
  2381. # Having include for existing primary header -> no error.
  2382. self.assert_language_rules_check('foo.cpp',
  2383. '#include "config.h"\n'
  2384. '#include "foo.h"\n'
  2385. '\n'
  2386. '#include "bar.h"\n',
  2387. '')
  2388. os.path.isfile = self.os_path_isfile_orig
  2389. def test_check_wtf_includes(self):
  2390. self.assert_language_rules_check('foo.cpp',
  2391. '#include "config.h"\n'
  2392. '#include "foo.h"\n'
  2393. '\n'
  2394. '#include <wtf/Assertions.h>\n',
  2395. '')
  2396. self.assert_language_rules_check('foo.cpp',
  2397. '#include "config.h"\n'
  2398. '#include "foo.h"\n'
  2399. '\n'
  2400. '#include "wtf/Assertions.h"\n',
  2401. 'wtf includes should be <wtf/file.h> instead of "wtf/file.h".'
  2402. ' [build/include] [4]')
  2403. def test_classify_include(self):
  2404. classify_include = cpp_style._classify_include
  2405. include_state = cpp_style._IncludeState()
  2406. self.assertEqual(cpp_style._CONFIG_HEADER,
  2407. classify_include('foo/foo.cpp',
  2408. 'config.h',
  2409. False, include_state))
  2410. self.assertEqual(cpp_style._PRIMARY_HEADER,
  2411. classify_include('foo/internal/foo.cpp',
  2412. 'foo/public/foo.h',
  2413. False, include_state))
  2414. self.assertEqual(cpp_style._PRIMARY_HEADER,
  2415. classify_include('foo/internal/foo.cpp',
  2416. 'foo/other/public/foo.h',
  2417. False, include_state))
  2418. self.assertEqual(cpp_style._OTHER_HEADER,
  2419. classify_include('foo/internal/foo.cpp',
  2420. 'foo/other/public/foop.h',
  2421. False, include_state))
  2422. self.assertEqual(cpp_style._OTHER_HEADER,
  2423. classify_include('foo/foo.cpp',
  2424. 'string',
  2425. True, include_state))
  2426. self.assertEqual(cpp_style._PRIMARY_HEADER,
  2427. classify_include('fooCustom.cpp',
  2428. 'foo.h',
  2429. False, include_state))
  2430. self.assertEqual(cpp_style._PRIMARY_HEADER,
  2431. classify_include('PrefixFooCustom.cpp',
  2432. 'Foo.h',
  2433. False, include_state))
  2434. self.assertEqual(cpp_style._MOC_HEADER,
  2435. classify_include('foo.cpp',
  2436. 'foo.moc',
  2437. False, include_state))
  2438. self.assertEqual(cpp_style._MOC_HEADER,
  2439. classify_include('foo.cpp',
  2440. 'moc_foo.cpp',
  2441. False, include_state))
  2442. # Tricky example where both includes might be classified as primary.
  2443. self.assert_language_rules_check('ScrollbarThemeWince.cpp',
  2444. '#include "config.h"\n'
  2445. '#include "ScrollbarThemeWince.h"\n'
  2446. '\n'
  2447. '#include "Scrollbar.h"\n',
  2448. '')
  2449. self.assert_language_rules_check('ScrollbarThemeWince.cpp',
  2450. '#include "config.h"\n'
  2451. '#include "Scrollbar.h"\n'
  2452. '\n'
  2453. '#include "ScrollbarThemeWince.h"\n',
  2454. 'Found header this file implements after a header this file implements.'
  2455. ' Should be: config.h, primary header, blank line, and then alphabetically sorted.'
  2456. ' [build/include_order] [4]')
  2457. self.assert_language_rules_check('ResourceHandleWin.cpp',
  2458. '#include "config.h"\n'
  2459. '#include "ResourceHandle.h"\n'
  2460. '\n'
  2461. '#include "ResourceHandleWin.h"\n',
  2462. '')
  2463. def test_try_drop_common_suffixes(self):
  2464. self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h'))
  2465. self.assertEqual('foo/bar/foo',
  2466. cpp_style._drop_common_suffixes('foo/bar/foo_inl.h'))
  2467. self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp'))
  2468. self.assertEqual('foo/foo_unusualinternal',
  2469. cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h'))
  2470. self.assertEqual('',
  2471. cpp_style._drop_common_suffixes('_test.cpp'))
  2472. self.assertEqual('test',
  2473. cpp_style._drop_common_suffixes('test.cpp'))
  2474. self.assertEqual('test',
  2475. cpp_style._drop_common_suffixes('test.cpp'))
  2476. class CheckForFunctionLengthsTest(CppStyleTestBase):
  2477. def setUp(self):
  2478. # Reducing these thresholds for the tests speeds up tests significantly.
  2479. self.old_normal_trigger = cpp_style._FunctionState._NORMAL_TRIGGER
  2480. self.old_test_trigger = cpp_style._FunctionState._TEST_TRIGGER
  2481. cpp_style._FunctionState._NORMAL_TRIGGER = 10
  2482. cpp_style._FunctionState._TEST_TRIGGER = 25
  2483. def tearDown(self):
  2484. cpp_style._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger
  2485. cpp_style._FunctionState._TEST_TRIGGER = self.old_test_trigger
  2486. # FIXME: Eliminate the need for this function.
  2487. def set_min_confidence(self, min_confidence):
  2488. """Set new test confidence and return old test confidence."""
  2489. old_min_confidence = self.min_confidence
  2490. self.min_confidence = min_confidence
  2491. return old_min_confidence
  2492. def assert_function_lengths_check(self, code, expected_message):
  2493. """Check warnings for long function bodies are as expected.
  2494. Args:
  2495. code: C++ source code expected to generate a warning message.
  2496. expected_message: Message expected to be generated by the C++ code.
  2497. """
  2498. self.assertEquals(expected_message,
  2499. self.perform_function_lengths_check(code))
  2500. def trigger_lines(self, error_level):
  2501. """Return number of lines needed to trigger a function length warning.
  2502. Args:
  2503. error_level: --v setting for cpp_style.
  2504. Returns:
  2505. Number of lines needed to trigger a function length warning.
  2506. """
  2507. return cpp_style._FunctionState._NORMAL_TRIGGER * 2 ** error_level
  2508. def trigger_test_lines(self, error_level):
  2509. """Return number of lines needed to trigger a test function length warning.
  2510. Args:
  2511. error_level: --v setting for cpp_style.
  2512. Returns:
  2513. Number of lines needed to trigger a test function length warning.
  2514. """
  2515. return cpp_style._FunctionState._TEST_TRIGGER * 2 ** error_level
  2516. def assert_function_length_check_definition(self, lines, error_level):
  2517. """Generate long function definition and check warnings are as expected.
  2518. Args:
  2519. lines: Number of lines to generate.
  2520. error_level: --v setting for cpp_style.
  2521. """
  2522. trigger_level = self.trigger_lines(self.min_confidence)
  2523. self.assert_function_lengths_check(
  2524. 'void test(int x)' + self.function_body(lines),
  2525. ('Small and focused functions are preferred: '
  2526. 'test() has %d non-comment lines '
  2527. '(error triggered by exceeding %d lines).'
  2528. ' [readability/fn_size] [%d]'
  2529. % (lines, trigger_level, error_level)))
  2530. def assert_function_length_check_definition_ok(self, lines):
  2531. """Generate shorter function definition and check no warning is produced.
  2532. Args:
  2533. lines: Number of lines to generate.
  2534. """
  2535. self.assert_function_lengths_check(
  2536. 'void test(int x)' + self.function_body(lines),
  2537. '')
  2538. def assert_function_length_check_at_error_level(self, error_level):
  2539. """Generate and check function at the trigger level for --v setting.
  2540. Args:
  2541. error_level: --v setting for cpp_style.
  2542. """
  2543. self.assert_function_length_check_definition(self.trigger_lines(error_level),
  2544. error_level)
  2545. def assert_function_length_check_below_error_level(self, error_level):
  2546. """Generate and check function just below the trigger level for --v setting.
  2547. Args:
  2548. error_level: --v setting for cpp_style.
  2549. """
  2550. self.assert_function_length_check_definition(self.trigger_lines(error_level) - 1,
  2551. error_level - 1)
  2552. def assert_function_length_check_above_error_level(self, error_level):
  2553. """Generate and check function just above the trigger level for --v setting.
  2554. Args:
  2555. error_level: --v setting for cpp_style.
  2556. """
  2557. self.assert_function_length_check_definition(self.trigger_lines(error_level) + 1,
  2558. error_level)
  2559. def function_body(self, number_of_lines):
  2560. return ' {\n' + ' this_is_just_a_test();\n' * number_of_lines + '}'
  2561. def function_body_with_blank_lines(self, number_of_lines):
  2562. return ' {\n' + ' this_is_just_a_test();\n\n' * number_of_lines + '}'
  2563. def function_body_with_no_lints(self, number_of_lines):
  2564. return ' {\n' + ' this_is_just_a_test(); // NOLINT\n' * number_of_lines + '}'
  2565. # Test line length checks.
  2566. def test_function_length_check_declaration(self):
  2567. self.assert_function_lengths_check(
  2568. 'void test();', # Not a function definition
  2569. '')
  2570. def test_function_length_check_declaration_with_block_following(self):
  2571. self.assert_function_lengths_check(
  2572. ('void test();\n'
  2573. + self.function_body(66)), # Not a function definition
  2574. '')
  2575. def test_function_length_check_class_definition(self):
  2576. self.assert_function_lengths_check( # Not a function definition
  2577. 'class Test' + self.function_body(66) + ';',
  2578. '')
  2579. def test_function_length_check_trivial(self):
  2580. self.assert_function_lengths_check(
  2581. 'void test() {}', # Not counted
  2582. '')
  2583. def test_function_length_check_empty(self):
  2584. self.assert_function_lengths_check(
  2585. 'void test() {\n}',
  2586. '')
  2587. def test_function_length_check_definition_below_severity0(self):
  2588. old_min_confidence = self.set_min_confidence(0)
  2589. self.assert_function_length_check_definition_ok(self.trigger_lines(0) - 1)
  2590. self.set_min_confidence(old_min_confidence)
  2591. def test_function_length_check_definition_at_severity0(self):
  2592. old_min_confidence = self.set_min_confidence(0)
  2593. self.assert_function_length_check_definition_ok(self.trigger_lines(0))
  2594. self.set_min_confidence(old_min_confidence)
  2595. def test_function_length_check_definition_above_severity0(self):
  2596. old_min_confidence = self.set_min_confidence(0)
  2597. self.assert_function_length_check_above_error_level(0)
  2598. self.set_min_confidence(old_min_confidence)
  2599. def test_function_length_check_definition_below_severity1v0(self):
  2600. old_min_confidence = self.set_min_confidence(0)
  2601. self.assert_function_length_check_below_error_level(1)
  2602. self.set_min_confidence(old_min_confidence)
  2603. def test_function_length_check_definition_at_severity1v0(self):
  2604. old_min_confidence = self.set_min_confidence(0)
  2605. self.assert_function_length_check_at_error_level(1)
  2606. self.set_min_confidence(old_min_confidence)
  2607. def test_function_length_check_definition_below_severity1(self):
  2608. self.assert_function_length_check_definition_ok(self.trigger_lines(1) - 1)
  2609. def test_function_length_check_definition_at_severity1(self):
  2610. self.assert_function_length_check_definition_ok(self.trigger_lines(1))
  2611. def test_function_length_check_definition_above_severity1(self):
  2612. self.assert_function_length_check_above_error_level(1)
  2613. def test_function_length_check_definition_severity1_plus_indented(self):
  2614. error_level = 1
  2615. error_lines = self.trigger_lines(error_level) + 1
  2616. trigger_level = self.trigger_lines(self.min_confidence)
  2617. indent_spaces = ' '
  2618. self.assert_function_lengths_check(
  2619. re.sub(r'(?m)^(.)', indent_spaces + r'\1',
  2620. 'void test_indent(int x)\n' + self.function_body(error_lines)),
  2621. ('Small and focused functions are preferred: '
  2622. 'test_indent() has %d non-comment lines '
  2623. '(error triggered by exceeding %d lines).'
  2624. ' [readability/fn_size] [%d]')
  2625. % (error_lines, trigger_level, error_level))
  2626. def test_function_length_check_definition_severity1_plus_blanks(self):
  2627. error_level = 1
  2628. error_lines = self.trigger_lines(error_level) + 1
  2629. trigger_level = self.trigger_lines(self.min_confidence)
  2630. self.assert_function_lengths_check(
  2631. 'void test_blanks(int x)' + self.function_body(error_lines),
  2632. ('Small and focused functions are preferred: '
  2633. 'test_blanks() has %d non-comment lines '
  2634. '(error triggered by exceeding %d lines).'
  2635. ' [readability/fn_size] [%d]')
  2636. % (error_lines, trigger_level, error_level))
  2637. def test_function_length_check_complex_definition_severity1(self):
  2638. error_level = 1
  2639. error_lines = self.trigger_lines(error_level) + 1
  2640. trigger_level = self.trigger_lines(self.min_confidence)
  2641. self.assert_function_lengths_check(
  2642. ('my_namespace::my_other_namespace::MyVeryLongTypeName<Type1, bool func(const Element*)>*\n'
  2643. 'my_namespace::my_other_namespace<Type3, Type4>::~MyFunction<Type5<Type6, Type7> >(int arg1, char* arg2)'
  2644. + self.function_body(error_lines)),
  2645. ('Small and focused functions are preferred: '
  2646. 'my_namespace::my_other_namespace<Type3, Type4>::~MyFunction<Type5<Type6, Type7> >()'
  2647. ' has %d non-comment lines '
  2648. '(error triggered by exceeding %d lines).'
  2649. ' [readability/fn_size] [%d]')
  2650. % (error_lines, trigger_level, error_level))
  2651. def test_function_length_check_definition_severity1_for_test(self):
  2652. error_level = 1
  2653. error_lines = self.trigger_test_lines(error_level) + 1
  2654. trigger_level = self.trigger_test_lines(self.min_confidence)
  2655. self.assert_function_lengths_check(
  2656. 'TEST_F(Test, Mutator)' + self.function_body(error_lines),
  2657. ('Small and focused functions are preferred: '
  2658. 'TEST_F(Test, Mutator) has %d non-comment lines '
  2659. '(error triggered by exceeding %d lines).'
  2660. ' [readability/fn_size] [%d]')
  2661. % (error_lines, trigger_level, error_level))
  2662. def test_function_length_check_definition_severity1_for_split_line_test(self):
  2663. error_level = 1
  2664. error_lines = self.trigger_test_lines(error_level) + 1
  2665. trigger_level = self.trigger_test_lines(self.min_confidence)
  2666. self.assert_function_lengths_check(
  2667. ('TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,\n'
  2668. ' FixGoogleUpdate_AllValues_MachineApp)' # note: 4 spaces
  2669. + self.function_body(error_lines)),
  2670. ('Small and focused functions are preferred: '
  2671. 'TEST_F(GoogleUpdateRecoveryRegistryProtectedTest, ' # 1 space
  2672. 'FixGoogleUpdate_AllValues_MachineApp) has %d non-comment lines '
  2673. '(error triggered by exceeding %d lines).'
  2674. ' [readability/fn_size] [%d]')
  2675. % (error_lines, trigger_level, error_level))
  2676. def test_function_length_check_definition_severity1_for_bad_test_doesnt_break(self):
  2677. error_level = 1
  2678. error_lines = self.trigger_test_lines(error_level) + 1
  2679. trigger_level = self.trigger_test_lines(self.min_confidence)
  2680. # Since the function name isn't valid, the function detection algorithm
  2681. # will skip it, so no error is produced.
  2682. self.assert_function_lengths_check(
  2683. ('TEST_F('
  2684. + self.function_body(error_lines)),
  2685. '')
  2686. def test_function_length_check_definition_severity1_with_embedded_no_lints(self):
  2687. error_level = 1
  2688. error_lines = self.trigger_lines(error_level) + 1
  2689. trigger_level = self.trigger_lines(self.min_confidence)
  2690. self.assert_function_lengths_check(
  2691. 'void test(int x)' + self.function_body_with_no_lints(error_lines),
  2692. ('Small and focused functions are preferred: '
  2693. 'test() has %d non-comment lines '
  2694. '(error triggered by exceeding %d lines).'
  2695. ' [readability/fn_size] [%d]')
  2696. % (error_lines, trigger_level, error_level))
  2697. def test_function_length_check_definition_severity1_with_no_lint(self):
  2698. self.assert_function_lengths_check(
  2699. ('void test(int x)' + self.function_body(self.trigger_lines(1))
  2700. + ' // NOLINT -- long function'),
  2701. '')
  2702. def test_function_length_check_definition_below_severity2(self):
  2703. self.assert_function_length_check_below_error_level(2)
  2704. def test_function_length_check_definition_severity2(self):
  2705. self.assert_function_length_check_at_error_level(2)
  2706. def test_function_length_check_definition_above_severity2(self):
  2707. self.assert_function_length_check_above_error_level(2)
  2708. def test_function_length_check_definition_below_severity3(self):
  2709. self.assert_function_length_check_below_error_level(3)
  2710. def test_function_length_check_definition_severity3(self):
  2711. self.assert_function_length_check_at_error_level(3)
  2712. def test_function_length_check_definition_above_severity3(self):
  2713. self.assert_function_length_check_above_error_level(3)
  2714. def test_function_length_check_definition_below_severity4(self):
  2715. self.assert_function_length_check_below_error_level(4)
  2716. def test_function_length_check_definition_severity4(self):
  2717. self.assert_function_length_check_at_error_level(4)
  2718. def test_function_length_check_definition_above_severity4(self):
  2719. self.assert_function_length_check_above_error_level(4)
  2720. def test_function_length_check_definition_below_severity5(self):
  2721. self.assert_function_length_check_below_error_level(5)
  2722. def test_function_length_check_definition_at_severity5(self):
  2723. self.assert_function_length_check_at_error_level(5)
  2724. def test_function_length_check_definition_above_severity5(self):
  2725. self.assert_function_length_check_above_error_level(5)
  2726. def test_function_length_check_definition_huge_lines(self):
  2727. # 5 is the limit
  2728. self.assert_function_length_check_definition(self.trigger_lines(10), 5)
  2729. def test_function_length_not_determinable(self):
  2730. # Macro invocation without terminating semicolon.
  2731. self.assert_function_lengths_check(
  2732. 'MACRO(arg)',
  2733. '')
  2734. # Macro with underscores
  2735. self.assert_function_lengths_check(
  2736. 'MACRO_WITH_UNDERSCORES(arg1, arg2, arg3)',
  2737. '')
  2738. self.assert_function_lengths_check(
  2739. 'NonMacro(arg)',
  2740. 'Lint failed to find start of function body.'
  2741. ' [readability/fn_size] [5]')
  2742. class NoNonVirtualDestructorsTest(CppStyleTestBase):
  2743. def test_no_error(self):
  2744. self.assert_multi_line_lint(
  2745. '''class Foo {
  2746. virtual ~Foo();
  2747. virtual void foo();
  2748. };''',
  2749. '')
  2750. self.assert_multi_line_lint(
  2751. '''class Foo {
  2752. virtual inline ~Foo();
  2753. virtual void foo();
  2754. };''',
  2755. '')
  2756. self.assert_multi_line_lint(
  2757. '''class Foo {
  2758. inline virtual ~Foo();
  2759. virtual void foo();
  2760. };''',
  2761. '')
  2762. self.assert_multi_line_lint(
  2763. '''class Foo::Goo {
  2764. virtual ~Goo();
  2765. virtual void goo();
  2766. };''',
  2767. '')
  2768. self.assert_multi_line_lint(
  2769. 'class Foo { void foo(); };',
  2770. 'More than one command on the same line [whitespace/newline] [4]')
  2771. self.assert_multi_line_lint(
  2772. 'class MyClass {\n'
  2773. ' int getIntValue() { ASSERT(m_ptr); return *m_ptr; }\n'
  2774. '};\n',
  2775. '')
  2776. self.assert_multi_line_lint(
  2777. 'class MyClass {\n'
  2778. ' int getIntValue()\n'
  2779. ' {\n'
  2780. ' ASSERT(m_ptr); return *m_ptr;\n'
  2781. ' }\n'
  2782. '};\n',
  2783. 'More than one command on the same line [whitespace/newline] [4]')
  2784. self.assert_multi_line_lint(
  2785. '''class Qualified::Goo : public Foo {
  2786. virtual void goo();
  2787. };''',
  2788. '')
  2789. self.assert_multi_line_lint(
  2790. # Line-ending :
  2791. '''class Goo :
  2792. public Foo {
  2793. virtual void goo();
  2794. };''',
  2795. 'Labels should always be indented at least one space. If this is a '
  2796. 'member-initializer list in a constructor, the colon should be on the '
  2797. 'line after the definition header. [whitespace/labels] [4]')
  2798. def test_no_destructor_when_virtual_needed(self):
  2799. self.assert_multi_line_lint_re(
  2800. '''class Foo {
  2801. virtual void foo();
  2802. };''',
  2803. 'The class Foo probably needs a virtual destructor')
  2804. def test_destructor_non_virtual_when_virtual_needed(self):
  2805. self.assert_multi_line_lint_re(
  2806. '''class Foo {
  2807. ~Foo();
  2808. virtual void foo();
  2809. };''',
  2810. 'The class Foo probably needs a virtual destructor')
  2811. def test_no_warn_when_derived(self):
  2812. self.assert_multi_line_lint(
  2813. '''class Foo : public Goo {
  2814. virtual void foo();
  2815. };''',
  2816. '')
  2817. def test_internal_braces(self):
  2818. self.assert_multi_line_lint_re(
  2819. '''class Foo {
  2820. enum Goo {
  2821. GOO
  2822. };
  2823. virtual void foo();
  2824. };''',
  2825. 'The class Foo probably needs a virtual destructor')
  2826. def test_inner_class_needs_virtual_destructor(self):
  2827. self.assert_multi_line_lint_re(
  2828. '''class Foo {
  2829. class Goo {
  2830. virtual void goo();
  2831. };
  2832. };''',
  2833. 'The class Goo probably needs a virtual destructor')
  2834. def test_outer_class_needs_virtual_destructor(self):
  2835. self.assert_multi_line_lint_re(
  2836. '''class Foo {
  2837. class Goo {
  2838. };
  2839. virtual void foo();
  2840. };''',
  2841. 'The class Foo probably needs a virtual destructor')
  2842. def test_qualified_class_needs_virtual_destructor(self):
  2843. self.assert_multi_line_lint_re(
  2844. '''class Qualified::Foo {
  2845. virtual void foo();
  2846. };''',
  2847. 'The class Qualified::Foo probably needs a virtual destructor')
  2848. def test_multi_line_declaration_no_error(self):
  2849. self.assert_multi_line_lint_re(
  2850. '''class Foo
  2851. : public Goo {
  2852. virtual void foo();
  2853. };''',
  2854. '')
  2855. def test_multi_line_declaration_with_error(self):
  2856. self.assert_multi_line_lint(
  2857. '''class Foo
  2858. {
  2859. virtual void foo();
  2860. };''',
  2861. ['This { should be at the end of the previous line '
  2862. '[whitespace/braces] [4]',
  2863. 'The class Foo probably needs a virtual destructor due to having '
  2864. 'virtual method(s), one declared at line 3. [runtime/virtual] [4]'])
  2865. class PassPtrTest(CppStyleTestBase):
  2866. # For http://webkit.org/coding/RefPtr.html
  2867. def assert_pass_ptr_check(self, code, expected_message):
  2868. """Check warnings for Pass*Ptr are as expected.
  2869. Args:
  2870. code: C++ source code expected to generate a warning message.
  2871. expected_message: Message expected to be generated by the C++ code.
  2872. """
  2873. self.assertEquals(expected_message,
  2874. self.perform_pass_ptr_check(code))
  2875. def test_pass_ref_ptr_in_function(self):
  2876. self.assert_pass_ptr_check(
  2877. 'int myFunction()\n'
  2878. '{\n'
  2879. ' PassRefPtr<Type1> variable = variable2;\n'
  2880. '}',
  2881. 'Local variables should never be PassRefPtr (see '
  2882. 'http://webkit.org/coding/RefPtr.html). [readability/pass_ptr] [5]')
  2883. def test_pass_own_ptr_in_function(self):
  2884. self.assert_pass_ptr_check(
  2885. 'int myFunction()\n'
  2886. '{\n'
  2887. ' PassOwnPtr<Type1> variable = variable2;\n'
  2888. '}',
  2889. 'Local variables should never be PassOwnPtr (see '
  2890. 'http://webkit.org/coding/RefPtr.html). [readability/pass_ptr] [5]')
  2891. def test_pass_other_type_ptr_in_function(self):
  2892. self.assert_pass_ptr_check(
  2893. 'int myFunction()\n'
  2894. '{\n'
  2895. ' PassOtherTypePtr<Type1> variable;\n'
  2896. '}',
  2897. 'Local variables should never be PassOtherTypePtr (see '
  2898. 'http://webkit.org/coding/RefPtr.html). [readability/pass_ptr] [5]')
  2899. def test_pass_ref_ptr_return_value(self):
  2900. self.assert_pass_ptr_check(
  2901. 'PassRefPtr<Type1>\n'
  2902. 'myFunction(int)\n'
  2903. '{\n'
  2904. '}',
  2905. '')
  2906. self.assert_pass_ptr_check(
  2907. 'PassRefPtr<Type1> myFunction(int)\n'
  2908. '{\n'
  2909. '}',
  2910. '')
  2911. self.assert_pass_ptr_check(
  2912. 'PassRefPtr<Type1> myFunction();\n',
  2913. '')
  2914. self.assert_pass_ptr_check(
  2915. 'OwnRefPtr<Type1> myFunction();\n',
  2916. '')
  2917. self.assert_pass_ptr_check(
  2918. 'RefPtr<Type1> myFunction(int)\n'
  2919. '{\n'
  2920. '}',
  2921. 'The return type should use PassRefPtr instead of RefPtr. [readability/pass_ptr] [5]')
  2922. self.assert_pass_ptr_check(
  2923. 'OwnPtr<Type1> myFunction(int)\n'
  2924. '{\n'
  2925. '}',
  2926. 'The return type should use PassOwnPtr instead of OwnPtr. [readability/pass_ptr] [5]')
  2927. def test_ref_ptr_parameter_value(self):
  2928. self.assert_pass_ptr_check(
  2929. 'int myFunction(PassRefPtr<Type1>)\n'
  2930. '{\n'
  2931. '}',
  2932. '')
  2933. self.assert_pass_ptr_check(
  2934. 'int myFunction(RefPtr<Type1>)\n'
  2935. '{\n'
  2936. '}',
  2937. 'The parameter type should use PassRefPtr instead of RefPtr. [readability/pass_ptr] [5]')
  2938. self.assert_pass_ptr_check(
  2939. 'int myFunction(RefPtr<Type1>&)\n'
  2940. '{\n'
  2941. '}',
  2942. '')
  2943. def test_own_ptr_parameter_value(self):
  2944. self.assert_pass_ptr_check(
  2945. 'int myFunction(PassOwnPtr<Type1>)\n'
  2946. '{\n'
  2947. '}',
  2948. '')
  2949. self.assert_pass_ptr_check(
  2950. 'int myFunction(OwnPtr<Type1>)\n'
  2951. '{\n'
  2952. '}',
  2953. 'The parameter type should use PassOwnPtr instead of OwnPtr. [readability/pass_ptr] [5]')
  2954. self.assert_pass_ptr_check(
  2955. 'int myFunction(OwnPtr<Type1>& simple)\n'
  2956. '{\n'
  2957. '}',
  2958. '')
  2959. def test_ref_ptr_member_variable(self):
  2960. self.assert_pass_ptr_check(
  2961. 'class Foo {'
  2962. ' RefPtr<Type1> m_other;\n'
  2963. '};\n',
  2964. '')
  2965. class WebKitStyleTest(CppStyleTestBase):
  2966. # for http://webkit.org/coding/coding-style.html
  2967. def test_indentation(self):
  2968. # 1. Use spaces, not tabs. Tabs should only appear in files that
  2969. # require them for semantic meaning, like Makefiles.
  2970. self.assert_multi_line_lint(
  2971. 'class Foo {\n'
  2972. ' int goo;\n'
  2973. '};',
  2974. '')
  2975. self.assert_multi_line_lint(
  2976. 'class Foo {\n'
  2977. '\tint goo;\n'
  2978. '};',
  2979. 'Tab found; better to use spaces [whitespace/tab] [1]')
  2980. # 2. The indent size is 4 spaces.
  2981. self.assert_multi_line_lint(
  2982. 'class Foo {\n'
  2983. ' int goo;\n'
  2984. '};',
  2985. '')
  2986. self.assert_multi_line_lint(
  2987. 'class Foo {\n'
  2988. ' int goo;\n'
  2989. '};',
  2990. 'Weird number of spaces at line-start. Are you using a 4-space indent? [whitespace/indent] [3]')
  2991. # FIXME: No tests for 8-spaces.
  2992. # 3. In a header, code inside a namespace should not be indented.
  2993. self.assert_multi_line_lint(
  2994. 'namespace WebCore {\n\n'
  2995. 'class Document {\n'
  2996. ' int myVariable;\n'
  2997. '};\n'
  2998. '}',
  2999. '',
  3000. 'foo.h')
  3001. self.assert_multi_line_lint(
  3002. 'namespace OuterNamespace {\n'
  3003. ' namespace InnerNamespace {\n'
  3004. ' class Document {\n'
  3005. '};\n'
  3006. '};\n'
  3007. '}',
  3008. 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
  3009. 'foo.h')
  3010. self.assert_multi_line_lint(
  3011. 'namespace OuterNamespace {\n'
  3012. ' class Document {\n'
  3013. ' namespace InnerNamespace {\n'
  3014. '};\n'
  3015. '};\n'
  3016. '}',
  3017. 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
  3018. 'foo.h')
  3019. self.assert_multi_line_lint(
  3020. 'namespace WebCore {\n'
  3021. '#if 0\n'
  3022. ' class Document {\n'
  3023. '};\n'
  3024. '#endif\n'
  3025. '}',
  3026. 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
  3027. 'foo.h')
  3028. self.assert_multi_line_lint(
  3029. 'namespace WebCore {\n'
  3030. 'class Document {\n'
  3031. '};\n'
  3032. '}',
  3033. '',
  3034. 'foo.h')
  3035. # 4. In an implementation file (files with the extension .cpp, .c
  3036. # or .mm), code inside a namespace should not be indented.
  3037. self.assert_multi_line_lint(
  3038. 'namespace WebCore {\n\n'
  3039. 'Document::Foo()\n'
  3040. ' : foo(bar)\n'
  3041. ' , boo(far)\n'
  3042. '{\n'
  3043. ' stuff();\n'
  3044. '}',
  3045. '',
  3046. 'foo.cpp')
  3047. self.assert_multi_line_lint(
  3048. 'namespace OuterNamespace {\n'
  3049. 'namespace InnerNamespace {\n'
  3050. 'Document::Foo() { }\n'
  3051. ' void* p;\n'
  3052. '}\n'
  3053. '}\n',
  3054. 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
  3055. 'foo.cpp')
  3056. self.assert_multi_line_lint(
  3057. 'namespace OuterNamespace {\n'
  3058. 'namespace InnerNamespace {\n'
  3059. 'Document::Foo() { }\n'
  3060. '}\n'
  3061. ' void* p;\n'
  3062. '}\n',
  3063. 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
  3064. 'foo.cpp')
  3065. self.assert_multi_line_lint(
  3066. 'namespace WebCore {\n\n'
  3067. ' const char* foo = "start:;"\n'
  3068. ' "dfsfsfs";\n'
  3069. '}\n',
  3070. 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
  3071. 'foo.cpp')
  3072. self.assert_multi_line_lint(
  3073. 'namespace WebCore {\n\n'
  3074. 'const char* foo(void* a = ";", // ;\n'
  3075. ' void* b);\n'
  3076. ' void* p;\n'
  3077. '}\n',
  3078. 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
  3079. 'foo.cpp')
  3080. self.assert_multi_line_lint(
  3081. 'namespace WebCore {\n\n'
  3082. 'const char* foo[] = {\n'
  3083. ' "void* b);", // ;\n'
  3084. ' "asfdf",\n'
  3085. ' }\n'
  3086. ' void* p;\n'
  3087. '}\n',
  3088. 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
  3089. 'foo.cpp')
  3090. self.assert_multi_line_lint(
  3091. 'namespace WebCore {\n\n'
  3092. 'const char* foo[] = {\n'
  3093. ' "void* b);", // }\n'
  3094. ' "asfdf",\n'
  3095. ' }\n'
  3096. '}\n',
  3097. '',
  3098. 'foo.cpp')
  3099. self.assert_multi_line_lint(
  3100. ' namespace WebCore {\n\n'
  3101. ' void Document::Foo()\n'
  3102. ' {\n'
  3103. 'start: // infinite loops are fun!\n'
  3104. ' goto start;\n'
  3105. ' }',
  3106. 'namespace should never be indented. [whitespace/indent] [4]',
  3107. 'foo.cpp')
  3108. self.assert_multi_line_lint(
  3109. 'namespace WebCore {\n'
  3110. ' Document::Foo() { }\n'
  3111. '}',
  3112. 'Code inside a namespace should not be indented.'
  3113. ' [whitespace/indent] [4]',
  3114. 'foo.cpp')
  3115. self.assert_multi_line_lint(
  3116. 'namespace WebCore {\n'
  3117. '#define abc(x) x; \\\n'
  3118. ' x\n'
  3119. '}',
  3120. '',
  3121. 'foo.cpp')
  3122. self.assert_multi_line_lint(
  3123. 'namespace WebCore {\n'
  3124. '#define abc(x) x; \\\n'
  3125. ' x\n'
  3126. ' void* x;'
  3127. '}',
  3128. 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
  3129. 'foo.cpp')
  3130. # 5. A case label should line up with its switch statement. The
  3131. # case statement is indented.
  3132. self.assert_multi_line_lint(
  3133. ' switch (condition) {\n'
  3134. ' case fooCondition:\n'
  3135. ' case barCondition:\n'
  3136. ' i++;\n'
  3137. ' break;\n'
  3138. ' default:\n'
  3139. ' i--;\n'
  3140. ' }\n',
  3141. '')
  3142. self.assert_multi_line_lint(
  3143. ' switch (condition) {\n'
  3144. ' case fooCondition:\n'
  3145. ' switch (otherCondition) {\n'
  3146. ' default:\n'
  3147. ' return;\n'
  3148. ' }\n'
  3149. ' default:\n'
  3150. ' i--;\n'
  3151. ' }\n',
  3152. '')
  3153. self.assert_multi_line_lint(
  3154. ' switch (condition) {\n'
  3155. ' case fooCondition: break;\n'
  3156. ' default: return;\n'
  3157. ' }\n',
  3158. '')
  3159. self.assert_multi_line_lint(
  3160. ' switch (condition) {\n'
  3161. ' case fooCondition:\n'
  3162. ' case barCondition:\n'
  3163. ' i++;\n'
  3164. ' break;\n'
  3165. ' default:\n'
  3166. ' i--;\n'
  3167. ' }\n',
  3168. 'A case label should not be indented, but line up with its switch statement.'
  3169. ' [whitespace/indent] [4]')
  3170. self.assert_multi_line_lint(
  3171. ' switch (condition) {\n'
  3172. ' case fooCondition:\n'
  3173. ' break;\n'
  3174. ' default:\n'
  3175. ' i--;\n'
  3176. ' }\n',
  3177. 'A case label should not be indented, but line up with its switch statement.'
  3178. ' [whitespace/indent] [4]')
  3179. self.assert_multi_line_lint(
  3180. ' switch (condition) {\n'
  3181. ' case fooCondition:\n'
  3182. ' case barCondition:\n'
  3183. ' switch (otherCondition) {\n'
  3184. ' default:\n'
  3185. ' return;\n'
  3186. ' }\n'
  3187. ' default:\n'
  3188. ' i--;\n'
  3189. ' }\n',
  3190. 'A case label should not be indented, but line up with its switch statement.'
  3191. ' [whitespace/indent] [4]')
  3192. self.assert_multi_line_lint(
  3193. ' switch (condition) {\n'
  3194. ' case fooCondition:\n'
  3195. ' case barCondition:\n'
  3196. ' i++;\n'
  3197. ' break;\n\n'
  3198. ' default:\n'
  3199. ' i--;\n'
  3200. ' }\n',
  3201. 'Non-label code inside switch statements should be indented.'
  3202. ' [whitespace/indent] [4]')
  3203. self.assert_multi_line_lint(
  3204. ' switch (condition) {\n'
  3205. ' case fooCondition:\n'
  3206. ' case barCondition:\n'
  3207. ' switch (otherCondition) {\n'
  3208. ' default:\n'
  3209. ' return;\n'
  3210. ' }\n'
  3211. ' default:\n'
  3212. ' i--;\n'
  3213. ' }\n',
  3214. 'Non-label code inside switch statements should be indented.'
  3215. ' [whitespace/indent] [4]')
  3216. # 6. Boolean expressions at the same nesting level that span
  3217. # multiple lines should have their operators on the left side of
  3218. # the line instead of the right side.
  3219. self.assert_multi_line_lint(
  3220. ' return attr->name() == srcAttr\n'
  3221. ' || attr->name() == lowsrcAttr;\n',
  3222. '')
  3223. self.assert_multi_line_lint(
  3224. ' return attr->name() == srcAttr ||\n'
  3225. ' attr->name() == lowsrcAttr;\n',
  3226. 'Boolean expressions that span multiple lines should have their '
  3227. 'operators on the left side of the line instead of the right side.'
  3228. ' [whitespace/operators] [4]')
  3229. def test_spacing(self):
  3230. # 1. Do not place spaces around unary operators.
  3231. self.assert_multi_line_lint(
  3232. 'i++;',
  3233. '')
  3234. self.assert_multi_line_lint(
  3235. 'i ++;',
  3236. 'Extra space for operator ++; [whitespace/operators] [4]')
  3237. # 2. Do place spaces around binary and ternary operators.
  3238. self.assert_multi_line_lint(
  3239. 'y = m * x + b;',
  3240. '')
  3241. self.assert_multi_line_lint(
  3242. 'f(a, b);',
  3243. '')
  3244. self.assert_multi_line_lint(
  3245. 'c = a | b;',
  3246. '')
  3247. self.assert_multi_line_lint(
  3248. 'return condition ? 1 : 0;',
  3249. '')
  3250. self.assert_multi_line_lint(
  3251. 'y=m*x+b;',
  3252. 'Missing spaces around = [whitespace/operators] [4]')
  3253. self.assert_multi_line_lint(
  3254. 'f(a,b);',
  3255. 'Missing space after , [whitespace/comma] [3]')
  3256. self.assert_multi_line_lint(
  3257. 'c = a|b;',
  3258. 'Missing spaces around | [whitespace/operators] [3]')
  3259. # FIXME: We cannot catch this lint error.
  3260. # self.assert_multi_line_lint(
  3261. # 'return condition ? 1:0;',
  3262. # '')
  3263. # 3. Place spaces between control statements and their parentheses.
  3264. self.assert_multi_line_lint(
  3265. ' if (condition)\n'
  3266. ' doIt();\n',
  3267. '')
  3268. self.assert_multi_line_lint(
  3269. ' if(condition)\n'
  3270. ' doIt();\n',
  3271. 'Missing space before ( in if( [whitespace/parens] [5]')
  3272. # 4. Do not place spaces between a function and its parentheses,
  3273. # or between a parenthesis and its content.
  3274. self.assert_multi_line_lint(
  3275. 'f(a, b);',
  3276. '')
  3277. self.assert_multi_line_lint(
  3278. 'f (a, b);',
  3279. 'Extra space before ( in function call [whitespace/parens] [4]')
  3280. self.assert_multi_line_lint(
  3281. 'f( a, b );',
  3282. ['Extra space after ( in function call [whitespace/parens] [4]',
  3283. 'Extra space before ) [whitespace/parens] [2]'])
  3284. def test_line_breaking(self):
  3285. # 1. Each statement should get its own line.
  3286. self.assert_multi_line_lint(
  3287. ' x++;\n'
  3288. ' y++;\n'
  3289. ' if (condition);\n'
  3290. ' doIt();\n',
  3291. '')
  3292. self.assert_multi_line_lint(
  3293. ' if (condition) \\\n'
  3294. ' doIt();\n',
  3295. '')
  3296. self.assert_multi_line_lint(
  3297. ' x++; y++;',
  3298. 'More than one command on the same line [whitespace/newline] [4]')
  3299. self.assert_multi_line_lint(
  3300. ' if (condition) doIt();\n',
  3301. 'More than one command on the same line in if [whitespace/parens] [4]')
  3302. # Ensure that having a # in the line doesn't hide the error.
  3303. self.assert_multi_line_lint(
  3304. ' x++; char a[] = "#";',
  3305. 'More than one command on the same line [whitespace/newline] [4]')
  3306. # Ignore preprocessor if's.
  3307. self.assert_multi_line_lint(
  3308. ' #if (condition) || (condition2)\n',
  3309. '')
  3310. # 2. An else statement should go on the same line as a preceding
  3311. # close brace if one is present, else it should line up with the
  3312. # if statement.
  3313. self.assert_multi_line_lint(
  3314. 'if (condition) {\n'
  3315. ' doSomething();\n'
  3316. ' doSomethingAgain();\n'
  3317. '} else {\n'
  3318. ' doSomethingElse();\n'
  3319. ' doSomethingElseAgain();\n'
  3320. '}\n',
  3321. '')
  3322. self.assert_multi_line_lint(
  3323. 'if (condition)\n'
  3324. ' doSomething();\n'
  3325. 'else\n'
  3326. ' doSomethingElse();\n',
  3327. '')
  3328. self.assert_multi_line_lint(
  3329. 'if (condition)\n'
  3330. ' doSomething();\n'
  3331. 'else {\n'
  3332. ' doSomethingElse();\n'
  3333. ' doSomethingElseAgain();\n'
  3334. '}\n',
  3335. '')
  3336. self.assert_multi_line_lint(
  3337. '#define TEST_ASSERT(expression) do { if (!(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0)\n',
  3338. '')
  3339. self.assert_multi_line_lint(
  3340. '#define TEST_ASSERT(expression) do { if ( !(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0)\n',
  3341. 'Extra space after ( in if [whitespace/parens] [5]')
  3342. # FIXME: currently we only check first conditional, so we cannot detect errors in next ones.
  3343. # self.assert_multi_line_lint(
  3344. # '#define TEST_ASSERT(expression) do { if (!(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0 )\n',
  3345. # 'Mismatching spaces inside () in if [whitespace/parens] [5]')
  3346. self.assert_multi_line_lint(
  3347. 'if (condition) {\n'
  3348. ' doSomething();\n'
  3349. ' doSomethingAgain();\n'
  3350. '}\n'
  3351. 'else {\n'
  3352. ' doSomethingElse();\n'
  3353. ' doSomethingElseAgain();\n'
  3354. '}\n',
  3355. 'An else should appear on the same line as the preceding } [whitespace/newline] [4]')
  3356. self.assert_multi_line_lint(
  3357. 'if (condition) doSomething(); else doSomethingElse();\n',
  3358. ['More than one command on the same line [whitespace/newline] [4]',
  3359. 'Else clause should never be on same line as else (use 2 lines) [whitespace/newline] [4]',
  3360. 'More than one command on the same line in if [whitespace/parens] [4]'])
  3361. self.assert_multi_line_lint(
  3362. 'if (condition) doSomething(); else {\n'
  3363. ' doSomethingElse();\n'
  3364. '}\n',
  3365. ['More than one command on the same line in if [whitespace/parens] [4]',
  3366. 'One line control clauses should not use braces. [whitespace/braces] [4]'])
  3367. self.assert_multi_line_lint(
  3368. 'if (condition)\n'
  3369. ' doSomething();\n'
  3370. 'else {\n'
  3371. ' doSomethingElse();\n'
  3372. '}\n',
  3373. 'One line control clauses should not use braces. [whitespace/braces] [4]')
  3374. self.assert_multi_line_lint(
  3375. 'if (condition) {\n'
  3376. ' doSomething1();\n'
  3377. ' doSomething2();\n'
  3378. '} else {\n'
  3379. ' doSomethingElse();\n'
  3380. '}\n',
  3381. 'One line control clauses should not use braces. [whitespace/braces] [4]')
  3382. self.assert_multi_line_lint(
  3383. 'void func()\n'
  3384. '{\n'
  3385. ' while (condition) { }\n'
  3386. ' return 0;\n'
  3387. '}\n',
  3388. '')
  3389. self.assert_multi_line_lint(
  3390. 'void func()\n'
  3391. '{\n'
  3392. ' for (i = 0; i < 42; i++) { foobar(); }\n'
  3393. ' return 0;\n'
  3394. '}\n',
  3395. 'More than one command on the same line in for [whitespace/parens] [4]')
  3396. # 3. An else if statement should be written as an if statement
  3397. # when the prior if concludes with a return statement.
  3398. self.assert_multi_line_lint(
  3399. 'if (motivated) {\n'
  3400. ' if (liquid)\n'
  3401. ' return money;\n'
  3402. '} else if (tired)\n'
  3403. ' break;\n',
  3404. '')
  3405. self.assert_multi_line_lint(
  3406. 'if (condition)\n'
  3407. ' doSomething();\n'
  3408. 'else if (otherCondition)\n'
  3409. ' doSomethingElse();\n',
  3410. '')
  3411. self.assert_multi_line_lint(
  3412. 'if (condition)\n'
  3413. ' doSomething();\n'
  3414. 'else\n'
  3415. ' doSomethingElse();\n',
  3416. '')
  3417. self.assert_multi_line_lint(
  3418. 'if (condition)\n'
  3419. ' returnValue = foo;\n'
  3420. 'else if (otherCondition)\n'
  3421. ' returnValue = bar;\n',
  3422. '')
  3423. self.assert_multi_line_lint(
  3424. 'if (condition)\n'
  3425. ' returnValue = foo;\n'
  3426. 'else\n'
  3427. ' returnValue = bar;\n',
  3428. '')
  3429. self.assert_multi_line_lint(
  3430. 'if (condition)\n'
  3431. ' doSomething();\n'
  3432. 'else if (liquid)\n'
  3433. ' return money;\n'
  3434. 'else if (broke)\n'
  3435. ' return favor;\n'
  3436. 'else\n'
  3437. ' sleep(28800);\n',
  3438. '')
  3439. self.assert_multi_line_lint(
  3440. 'if (liquid) {\n'
  3441. ' prepare();\n'
  3442. ' return money;\n'
  3443. '} else if (greedy) {\n'
  3444. ' keep();\n'
  3445. ' return nothing;\n'
  3446. '}\n',
  3447. 'An else if statement should be written as an if statement when the '
  3448. 'prior "if" concludes with a return, break, continue or goto statement.'
  3449. ' [readability/control_flow] [4]')
  3450. self.assert_multi_line_lint(
  3451. ' if (stupid) {\n'
  3452. 'infiniteLoop:\n'
  3453. ' goto infiniteLoop;\n'
  3454. ' } else if (evil)\n'
  3455. ' goto hell;\n',
  3456. 'An else if statement should be written as an if statement when the '
  3457. 'prior "if" concludes with a return, break, continue or goto statement.'
  3458. ' [readability/control_flow] [4]')
  3459. self.assert_multi_line_lint(
  3460. 'if (liquid)\n'
  3461. '{\n'
  3462. ' prepare();\n'
  3463. ' return money;\n'
  3464. '}\n'
  3465. 'else if (greedy)\n'
  3466. ' keep();\n',
  3467. ['This { should be at the end of the previous line [whitespace/braces] [4]',
  3468. 'An else should appear on the same line as the preceding } [whitespace/newline] [4]',
  3469. 'An else if statement should be written as an if statement when the '
  3470. 'prior "if" concludes with a return, break, continue or goto statement.'
  3471. ' [readability/control_flow] [4]'])
  3472. self.assert_multi_line_lint(
  3473. 'if (gone)\n'
  3474. ' return;\n'
  3475. 'else if (here)\n'
  3476. ' go();\n',
  3477. 'An else if statement should be written as an if statement when the '
  3478. 'prior "if" concludes with a return, break, continue or goto statement.'
  3479. ' [readability/control_flow] [4]')
  3480. self.assert_multi_line_lint(
  3481. 'if (gone)\n'
  3482. ' return;\n'
  3483. 'else\n'
  3484. ' go();\n',
  3485. 'An else statement can be removed when the prior "if" concludes '
  3486. 'with a return, break, continue or goto statement.'
  3487. ' [readability/control_flow] [4]')
  3488. self.assert_multi_line_lint(
  3489. 'if (motivated) {\n'
  3490. ' prepare();\n'
  3491. ' continue;\n'
  3492. '} else {\n'
  3493. ' cleanUp();\n'
  3494. ' break;\n'
  3495. '}\n',
  3496. 'An else statement can be removed when the prior "if" concludes '
  3497. 'with a return, break, continue or goto statement.'
  3498. ' [readability/control_flow] [4]')
  3499. self.assert_multi_line_lint(
  3500. 'if (tired)\n'
  3501. ' break;\n'
  3502. 'else {\n'
  3503. ' prepare();\n'
  3504. ' continue;\n'
  3505. '}\n',
  3506. 'An else statement can be removed when the prior "if" concludes '
  3507. 'with a return, break, continue or goto statement.'
  3508. ' [readability/control_flow] [4]')
  3509. def test_braces(self):
  3510. # 1. Function definitions: place each brace on its own line.
  3511. self.assert_multi_line_lint(
  3512. 'int main()\n'
  3513. '{\n'
  3514. ' doSomething();\n'
  3515. '}\n',
  3516. '')
  3517. self.assert_multi_line_lint(
  3518. 'int main() {\n'
  3519. ' doSomething();\n'
  3520. '}\n',
  3521. 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
  3522. # 2. Other braces: place the open brace on the line preceding the
  3523. # code block; place the close brace on its own line.
  3524. self.assert_multi_line_lint(
  3525. 'class MyClass {\n'
  3526. ' int foo;\n'
  3527. '};\n',
  3528. '')
  3529. self.assert_multi_line_lint(
  3530. 'namespace WebCore {\n'
  3531. 'int foo;\n'
  3532. '};\n',
  3533. '')
  3534. self.assert_multi_line_lint(
  3535. 'for (int i = 0; i < 10; i++) {\n'
  3536. ' DoSomething();\n'
  3537. '};\n',
  3538. '')
  3539. self.assert_multi_line_lint(
  3540. 'class MyClass\n'
  3541. '{\n'
  3542. ' int foo;\n'
  3543. '};\n',
  3544. 'This { should be at the end of the previous line [whitespace/braces] [4]')
  3545. self.assert_multi_line_lint(
  3546. 'if (condition)\n'
  3547. '{\n'
  3548. ' int foo;\n'
  3549. '}\n',
  3550. 'This { should be at the end of the previous line [whitespace/braces] [4]')
  3551. self.assert_multi_line_lint(
  3552. 'for (int i = 0; i < 10; i++)\n'
  3553. '{\n'
  3554. ' int foo;\n'
  3555. '}\n',
  3556. 'This { should be at the end of the previous line [whitespace/braces] [4]')
  3557. self.assert_multi_line_lint(
  3558. 'while (true)\n'
  3559. '{\n'
  3560. ' int foo;\n'
  3561. '}\n',
  3562. 'This { should be at the end of the previous line [whitespace/braces] [4]')
  3563. self.assert_multi_line_lint(
  3564. 'foreach (Foo* foo, foos)\n'
  3565. '{\n'
  3566. ' int bar;\n'
  3567. '}\n',
  3568. 'This { should be at the end of the previous line [whitespace/braces] [4]')
  3569. self.assert_multi_line_lint(
  3570. 'switch (type)\n'
  3571. '{\n'
  3572. 'case foo: return;\n'
  3573. '}\n',
  3574. 'This { should be at the end of the previous line [whitespace/braces] [4]')
  3575. self.assert_multi_line_lint(
  3576. 'if (condition)\n'
  3577. '{\n'
  3578. ' int foo;\n'
  3579. '}\n',
  3580. 'This { should be at the end of the previous line [whitespace/braces] [4]')
  3581. self.assert_multi_line_lint(
  3582. 'for (int i = 0; i < 10; i++)\n'
  3583. '{\n'
  3584. ' int foo;\n'
  3585. '}\n',
  3586. 'This { should be at the end of the previous line [whitespace/braces] [4]')
  3587. self.assert_multi_line_lint(
  3588. 'while (true)\n'
  3589. '{\n'
  3590. ' int foo;\n'
  3591. '}\n',
  3592. 'This { should be at the end of the previous line [whitespace/braces] [4]')
  3593. self.assert_multi_line_lint(
  3594. 'switch (type)\n'
  3595. '{\n'
  3596. 'case foo: return;\n'
  3597. '}\n',
  3598. 'This { should be at the end of the previous line [whitespace/braces] [4]')
  3599. self.assert_multi_line_lint(
  3600. 'else if (type)\n'
  3601. '{\n'
  3602. 'case foo: return;\n'
  3603. '}\n',
  3604. 'This { should be at the end of the previous line [whitespace/braces] [4]')
  3605. # 3. One-line control clauses should not use braces unless
  3606. # comments are included or a single statement spans multiple
  3607. # lines.
  3608. self.assert_multi_line_lint(
  3609. 'if (true) {\n'
  3610. ' int foo;\n'
  3611. '}\n',
  3612. 'One line control clauses should not use braces. [whitespace/braces] [4]')
  3613. self.assert_multi_line_lint(
  3614. 'for (; foo; bar) {\n'
  3615. ' int foo;\n'
  3616. '}\n',
  3617. 'One line control clauses should not use braces. [whitespace/braces] [4]')
  3618. self.assert_multi_line_lint(
  3619. 'foreach (foo, foos) {\n'
  3620. ' int bar;\n'
  3621. '}\n',
  3622. 'One line control clauses should not use braces. [whitespace/braces] [4]')
  3623. self.assert_multi_line_lint(
  3624. 'while (true) {\n'
  3625. ' int foo;\n'
  3626. '}\n',
  3627. 'One line control clauses should not use braces. [whitespace/braces] [4]')
  3628. self.assert_multi_line_lint(
  3629. 'if (true)\n'
  3630. ' int foo;\n'
  3631. 'else {\n'
  3632. ' int foo;\n'
  3633. '}\n',
  3634. 'One line control clauses should not use braces. [whitespace/braces] [4]')
  3635. self.assert_multi_line_lint(
  3636. 'if (true) {\n'
  3637. ' int foo;\n'
  3638. '} else\n'
  3639. ' int foo;\n',
  3640. 'One line control clauses should not use braces. [whitespace/braces] [4]')
  3641. self.assert_multi_line_lint(
  3642. 'if (true) {\n'
  3643. ' // Some comment\n'
  3644. ' int foo;\n'
  3645. '}\n',
  3646. '')
  3647. self.assert_multi_line_lint(
  3648. 'if (true) {\n'
  3649. ' myFunction(reallyLongParam1, reallyLongParam2,\n'
  3650. ' reallyLongParam3);\n'
  3651. '}\n',
  3652. '')
  3653. # 4. Control clauses without a body should use empty braces.
  3654. self.assert_multi_line_lint(
  3655. 'for ( ; current; current = current->next) { }\n',
  3656. '')
  3657. self.assert_multi_line_lint(
  3658. 'for ( ; current;\n'
  3659. ' current = current->next) { }\n',
  3660. '')
  3661. self.assert_multi_line_lint(
  3662. 'for ( ; current; current = current->next);\n',
  3663. 'Semicolon defining empty statement for this loop. Use { } instead. [whitespace/semicolon] [5]')
  3664. self.assert_multi_line_lint(
  3665. 'while (true);\n',
  3666. 'Semicolon defining empty statement for this loop. Use { } instead. [whitespace/semicolon] [5]')
  3667. self.assert_multi_line_lint(
  3668. '} while (true);\n',
  3669. '')
  3670. def test_null_false_zero(self):
  3671. # 1. In C++, the null pointer value should be written as 0. In C,
  3672. # it should be written as NULL. In Objective-C and Objective-C++,
  3673. # follow the guideline for C or C++, respectively, but use nil to
  3674. # represent a null Objective-C object.
  3675. self.assert_lint(
  3676. 'functionCall(NULL)',
  3677. 'Use 0 instead of NULL.'
  3678. ' [readability/null] [5]',
  3679. 'foo.cpp')
  3680. self.assert_lint(
  3681. "// Don't use NULL in comments since it isn't in code.",
  3682. 'Use 0 or null instead of NULL (even in *comments*).'
  3683. ' [readability/null] [4]',
  3684. 'foo.cpp')
  3685. self.assert_lint(
  3686. '"A string with NULL" // and a comment with NULL is tricky to flag correctly in cpp_style.',
  3687. 'Use 0 or null instead of NULL (even in *comments*).'
  3688. ' [readability/null] [4]',
  3689. 'foo.cpp')
  3690. self.assert_lint(
  3691. '"A string containing NULL is ok"',
  3692. '',
  3693. 'foo.cpp')
  3694. self.assert_lint(
  3695. 'if (aboutNULL)',
  3696. '',
  3697. 'foo.cpp')
  3698. self.assert_lint(
  3699. 'myVariable = NULLify',
  3700. '',
  3701. 'foo.cpp')
  3702. # Make sure that the NULL check does not apply to C and Objective-C files.
  3703. self.assert_lint(
  3704. 'functionCall(NULL)',
  3705. '',
  3706. 'foo.c')
  3707. self.assert_lint(
  3708. 'functionCall(NULL)',
  3709. '',
  3710. 'foo.m')
  3711. # Make sure that the NULL check does not apply to g_object_{set,get} and
  3712. # g_str{join,concat}
  3713. self.assert_lint(
  3714. 'g_object_get(foo, "prop", &bar, NULL);',
  3715. '')
  3716. self.assert_lint(
  3717. 'g_object_set(foo, "prop", bar, NULL);',
  3718. '')
  3719. self.assert_lint(
  3720. 'g_build_filename(foo, bar, NULL);',
  3721. '')
  3722. self.assert_lint(
  3723. 'gst_bin_add_many(foo, bar, boo, NULL);',
  3724. '')
  3725. self.assert_lint(
  3726. 'gst_bin_remove_many(foo, bar, boo, NULL);',
  3727. '')
  3728. self.assert_lint(
  3729. 'gst_element_link_many(foo, bar, boo, NULL);',
  3730. '')
  3731. self.assert_lint(
  3732. 'gst_element_unlink_many(foo, bar, boo, NULL);',
  3733. '')
  3734. self.assert_lint(
  3735. 'gst_structure_get(foo, "value", G_TYPE_INT, &value, NULL);',
  3736. '')
  3737. self.assert_lint(
  3738. 'gst_structure_set(foo, "value", G_TYPE_INT, value, NULL);',
  3739. '')
  3740. self.assert_lint(
  3741. 'gst_structure_remove_fields(foo, "value", "bar", NULL);',
  3742. '')
  3743. self.assert_lint(
  3744. 'gst_structure_new("foo", "value", G_TYPE_INT, value, NULL);',
  3745. '')
  3746. self.assert_lint(
  3747. 'gst_structure_id_new(FOO, VALUE, G_TYPE_INT, value, NULL);',
  3748. '')
  3749. self.assert_lint(
  3750. 'gst_structure_id_set(FOO, VALUE, G_TYPE_INT, value, NULL);',
  3751. '')
  3752. self.assert_lint(
  3753. 'gst_structure_id_get(FOO, VALUE, G_TYPE_INT, &value, NULL);',
  3754. '')
  3755. self.assert_lint(
  3756. 'gchar* result = g_strconcat("part1", "part2", "part3", NULL);',
  3757. '')
  3758. self.assert_lint(
  3759. 'gchar* result = g_strconcat("part1", NULL);',
  3760. '')
  3761. self.assert_lint(
  3762. 'gchar* result = g_strjoin(",", "part1", "part2", "part3", NULL);',
  3763. '')
  3764. self.assert_lint(
  3765. 'gchar* result = g_strjoin(",", "part1", NULL);',
  3766. '')
  3767. self.assert_lint(
  3768. 'gchar* result = gdk_pixbuf_save_to_callback(pixbuf, function, data, type, error, NULL);',
  3769. '')
  3770. self.assert_lint(
  3771. 'gchar* result = gdk_pixbuf_save_to_buffer(pixbuf, function, data, type, error, NULL);',
  3772. '')
  3773. self.assert_lint(
  3774. 'gchar* result = gdk_pixbuf_save_to_stream(pixbuf, function, data, type, error, NULL);',
  3775. '')
  3776. self.assert_lint(
  3777. 'gtk_widget_style_get(style, "propertyName", &value, "otherName", &otherValue, NULL);',
  3778. '')
  3779. self.assert_lint(
  3780. 'gtk_widget_style_get_property(style, NULL, NULL);',
  3781. 'Use 0 instead of NULL. [readability/null] [5]',
  3782. 'foo.cpp')
  3783. self.assert_lint(
  3784. 'gtk_widget_style_get_valist(style, NULL, NULL);',
  3785. 'Use 0 instead of NULL. [readability/null] [5]',
  3786. 'foo.cpp')
  3787. # 2. C++ and C bool values should be written as true and
  3788. # false. Objective-C BOOL values should be written as YES and NO.
  3789. # FIXME: Implement this.
  3790. # 3. Tests for true/false, null/non-null, and zero/non-zero should
  3791. # all be done without equality comparisons.
  3792. self.assert_lint(
  3793. 'if (count == 0)',
  3794. 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
  3795. ' [readability/comparison_to_zero] [5]')
  3796. self.assert_lint_one_of_many_errors_re(
  3797. 'if (string != NULL)',
  3798. r'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons\.')
  3799. self.assert_lint(
  3800. 'if (condition == true)',
  3801. 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
  3802. ' [readability/comparison_to_zero] [5]')
  3803. self.assert_lint(
  3804. 'if (myVariable != /* Why would anyone put a comment here? */ false)',
  3805. 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
  3806. ' [readability/comparison_to_zero] [5]')
  3807. self.assert_lint(
  3808. 'if (0 /* This comment also looks odd to me. */ != aLongerVariableName)',
  3809. 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
  3810. ' [readability/comparison_to_zero] [5]')
  3811. self.assert_lint_one_of_many_errors_re(
  3812. 'if (NULL == thisMayBeNull)',
  3813. r'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons\.')
  3814. self.assert_lint(
  3815. 'if (true != anotherCondition)',
  3816. 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
  3817. ' [readability/comparison_to_zero] [5]')
  3818. self.assert_lint(
  3819. 'if (false == myBoolValue)',
  3820. 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
  3821. ' [readability/comparison_to_zero] [5]')
  3822. self.assert_lint(
  3823. 'if (fontType == trueType)',
  3824. '')
  3825. self.assert_lint(
  3826. 'if (othertrue == fontType)',
  3827. '')
  3828. self.assert_lint(
  3829. 'if (LIKELY(foo == 0))',
  3830. '')
  3831. self.assert_lint(
  3832. 'if (UNLIKELY(foo == 0))',
  3833. '')
  3834. self.assert_lint(
  3835. 'if (LIKELY(foo == NULL))',
  3836. 'Use 0 instead of NULL. [readability/null] [5]')
  3837. self.assert_lint(
  3838. 'if (UNLIKELY(foo == NULL))',
  3839. 'Use 0 instead of NULL. [readability/null] [5]')
  3840. def test_using_std(self):
  3841. self.assert_lint(
  3842. 'using std::min;',
  3843. "Use 'using namespace std;' instead of 'using std::min;'."
  3844. " [build/using_std] [4]",
  3845. 'foo.cpp')
  3846. def test_max_macro(self):
  3847. self.assert_lint(
  3848. 'int i = MAX(0, 1);',
  3849. '',
  3850. 'foo.c')
  3851. self.assert_lint(
  3852. 'int i = MAX(0, 1);',
  3853. 'Use std::max() or std::max<type>() instead of the MAX() macro.'
  3854. ' [runtime/max_min_macros] [4]',
  3855. 'foo.cpp')
  3856. self.assert_lint(
  3857. 'inline int foo() { return MAX(0, 1); }',
  3858. 'Use std::max() or std::max<type>() instead of the MAX() macro.'
  3859. ' [runtime/max_min_macros] [4]',
  3860. 'foo.h')
  3861. def test_min_macro(self):
  3862. self.assert_lint(
  3863. 'int i = MIN(0, 1);',
  3864. '',
  3865. 'foo.c')
  3866. self.assert_lint(
  3867. 'int i = MIN(0, 1);',
  3868. 'Use std::min() or std::min<type>() instead of the MIN() macro.'
  3869. ' [runtime/max_min_macros] [4]',
  3870. 'foo.cpp')
  3871. self.assert_lint(
  3872. 'inline int foo() { return MIN(0, 1); }',
  3873. 'Use std::min() or std::min<type>() instead of the MIN() macro.'
  3874. ' [runtime/max_min_macros] [4]',
  3875. 'foo.h')
  3876. def test_names(self):
  3877. name_underscore_error_message = " is incorrectly named. Don't use underscores in your identifier names. [readability/naming] [4]"
  3878. name_tooshort_error_message = " is incorrectly named. Don't use the single letter 'l' as an identifier name. [readability/naming] [4]"
  3879. # Basic cases from WebKit style guide.
  3880. self.assert_lint('struct Data;', '')
  3881. self.assert_lint('size_t bufferSize;', '')
  3882. self.assert_lint('class HTMLDocument;', '')
  3883. self.assert_lint('String mimeType();', '')
  3884. self.assert_lint('size_t buffer_size;',
  3885. 'buffer_size' + name_underscore_error_message)
  3886. self.assert_lint('short m_length;', '')
  3887. self.assert_lint('short _length;',
  3888. '_length' + name_underscore_error_message)
  3889. self.assert_lint('short length_;',
  3890. 'length_' + name_underscore_error_message)
  3891. self.assert_lint('unsigned _length;',
  3892. '_length' + name_underscore_error_message)
  3893. self.assert_lint('unsigned int _length;',
  3894. '_length' + name_underscore_error_message)
  3895. self.assert_lint('unsigned long long _length;',
  3896. '_length' + name_underscore_error_message)
  3897. # Allow underscores in Objective C files.
  3898. self.assert_lint('unsigned long long _length;',
  3899. '',
  3900. 'foo.m')
  3901. self.assert_lint('unsigned long long _length;',
  3902. '',
  3903. 'foo.mm')
  3904. self.assert_lint('#import "header_file.h"\n'
  3905. 'unsigned long long _length;',
  3906. '',
  3907. 'foo.h')
  3908. self.assert_lint('unsigned long long _length;\n'
  3909. '@interface WebFullscreenWindow;',
  3910. '',
  3911. 'foo.h')
  3912. self.assert_lint('unsigned long long _length;\n'
  3913. '@implementation WebFullscreenWindow;',
  3914. '',
  3915. 'foo.h')
  3916. self.assert_lint('unsigned long long _length;\n'
  3917. '@class WebWindowFadeAnimation;',
  3918. '',
  3919. 'foo.h')
  3920. # Variable name 'l' is easy to confuse with '1'
  3921. self.assert_lint('int l;', 'l' + name_tooshort_error_message)
  3922. self.assert_lint('size_t l;', 'l' + name_tooshort_error_message)
  3923. self.assert_lint('long long l;', 'l' + name_tooshort_error_message)
  3924. # Pointers, references, functions, templates, and adjectives.
  3925. self.assert_lint('char* under_score;',
  3926. 'under_score' + name_underscore_error_message)
  3927. self.assert_lint('const int UNDER_SCORE;',
  3928. 'UNDER_SCORE' + name_underscore_error_message)
  3929. self.assert_lint('static inline const char const& const under_score;',
  3930. 'under_score' + name_underscore_error_message)
  3931. self.assert_lint('WebCore::RenderObject* under_score;',
  3932. 'under_score' + name_underscore_error_message)
  3933. self.assert_lint('int func_name();',
  3934. 'func_name' + name_underscore_error_message)
  3935. self.assert_lint('RefPtr<RenderObject*> under_score;',
  3936. 'under_score' + name_underscore_error_message)
  3937. self.assert_lint('WTF::Vector<WTF::RefPtr<const RenderObject* const> > under_score;',
  3938. 'under_score' + name_underscore_error_message)
  3939. self.assert_lint('int under_score[];',
  3940. 'under_score' + name_underscore_error_message)
  3941. self.assert_lint('struct dirent* under_score;',
  3942. 'under_score' + name_underscore_error_message)
  3943. self.assert_lint('long under_score;',
  3944. 'under_score' + name_underscore_error_message)
  3945. self.assert_lint('long long under_score;',
  3946. 'under_score' + name_underscore_error_message)
  3947. self.assert_lint('long double under_score;',
  3948. 'under_score' + name_underscore_error_message)
  3949. self.assert_lint('long long int under_score;',
  3950. 'under_score' + name_underscore_error_message)
  3951. # Declarations in control statement.
  3952. self.assert_lint('if (int under_score = 42) {',
  3953. 'under_score' + name_underscore_error_message)
  3954. self.assert_lint('else if (int under_score = 42) {',
  3955. 'under_score' + name_underscore_error_message)
  3956. self.assert_lint('for (int under_score = 42; cond; i++) {',
  3957. 'under_score' + name_underscore_error_message)
  3958. self.assert_lint('while (foo & under_score = bar) {',
  3959. 'under_score' + name_underscore_error_message)
  3960. self.assert_lint('for (foo * under_score = p; cond; i++) {',
  3961. 'under_score' + name_underscore_error_message)
  3962. self.assert_lint('for (foo * under_score; cond; i++) {',
  3963. 'under_score' + name_underscore_error_message)
  3964. self.assert_lint('while (foo & value_in_thirdparty_library) {', '')
  3965. self.assert_lint('while (foo * value_in_thirdparty_library) {', '')
  3966. self.assert_lint('if (mli && S_OK == mli->foo()) {', '')
  3967. # More member variables and functions.
  3968. self.assert_lint('int SomeClass::s_validName', '')
  3969. self.assert_lint('int m_under_score;',
  3970. 'm_under_score' + name_underscore_error_message)
  3971. self.assert_lint('int SomeClass::s_under_score = 0;',
  3972. 'SomeClass::s_under_score' + name_underscore_error_message)
  3973. self.assert_lint('int SomeClass::under_score = 0;',
  3974. 'SomeClass::under_score' + name_underscore_error_message)
  3975. # Other statements.
  3976. self.assert_lint('return INT_MAX;', '')
  3977. self.assert_lint('return_t under_score;',
  3978. 'under_score' + name_underscore_error_message)
  3979. self.assert_lint('goto under_score;',
  3980. 'under_score' + name_underscore_error_message)
  3981. self.assert_lint('delete static_cast<Foo*>(p);', '')
  3982. # Multiple variables in one line.
  3983. self.assert_lint('void myFunction(int variable1, int another_variable);',
  3984. 'another_variable' + name_underscore_error_message)
  3985. self.assert_lint('int variable1, another_variable;',
  3986. 'another_variable' + name_underscore_error_message)
  3987. self.assert_lint('int first_variable, secondVariable;',
  3988. 'first_variable' + name_underscore_error_message)
  3989. self.assert_lint('void my_function(int variable_1, int variable_2);',
  3990. ['my_function' + name_underscore_error_message,
  3991. 'variable_1' + name_underscore_error_message,
  3992. 'variable_2' + name_underscore_error_message])
  3993. self.assert_lint('for (int variable_1, variable_2;;) {',
  3994. ['variable_1' + name_underscore_error_message,
  3995. 'variable_2' + name_underscore_error_message])
  3996. # There is an exception for op code functions but only in the JavaScriptCore directory.
  3997. self.assert_lint('void this_op_code(int var1, int var2)', '', 'Source/JavaScriptCore/foo.cpp')
  3998. self.assert_lint('void op_code(int var1, int var2)', '', 'Source/JavaScriptCore/foo.cpp')
  3999. self.assert_lint('void this_op_code(int var1, int var2)', 'this_op_code' + name_underscore_error_message)
  4000. # GObject requires certain magical names in class declarations.
  4001. self.assert_lint('void webkit_dom_object_init();', '')
  4002. self.assert_lint('void webkit_dom_object_class_init();', '')
  4003. # There is an exception for GTK+ API.
  4004. self.assert_lint('void webkit_web_view_load(int var1, int var2)', '', 'Source/Webkit/gtk/webkit/foo.cpp')
  4005. self.assert_lint('void webkit_web_view_load(int var1, int var2)', '', 'Source/Webkit2/UIProcess/gtk/foo.cpp')
  4006. # Test that this doesn't also apply to files not in a 'gtk' directory.
  4007. self.assert_lint('void webkit_web_view_load(int var1, int var2)',
  4008. 'webkit_web_view_load is incorrectly named. Don\'t use underscores in your identifier names.'
  4009. ' [readability/naming] [4]', 'Source/Webkit/webkit/foo.cpp')
  4010. # Test that this doesn't also apply to names that don't start with 'webkit_'.
  4011. self.assert_lint_one_of_many_errors_re('void otherkit_web_view_load(int var1, int var2)',
  4012. 'otherkit_web_view_load is incorrectly named. Don\'t use underscores in your identifier names.'
  4013. ' [readability/naming] [4]', 'Source/Webkit/webkit/foo.cpp')
  4014. # There is an exception for some unit tests that begin with "tst_".
  4015. self.assert_lint('void tst_QWebFrame::arrayObjectEnumerable(int var1, int var2)', '')
  4016. # The Qt API uses names that begin with "qt_".
  4017. self.assert_lint('void QTFrame::qt_drt_is_awesome(int var1, int var2)', '')
  4018. self.assert_lint('void qt_drt_is_awesome(int var1, int var2);', '')
  4019. # Cairo forward-declarations should not be a failure.
  4020. self.assert_lint('typedef struct _cairo cairo_t;', '')
  4021. self.assert_lint('typedef struct _cairo_surface cairo_surface_t;', '')
  4022. self.assert_lint('typedef struct _cairo_scaled_font cairo_scaled_font_t;', '')
  4023. # EFL forward-declarations should not be a failure.
  4024. self.assert_lint('typedef struct _Ecore_Evas Ecore_Evas;', '')
  4025. self.assert_lint('typedef struct _Ecore_Pipe Ecore_Pipe;', '')
  4026. self.assert_lint('typedef struct _Eina_Rectangle Eina_Rectangle;', '')
  4027. self.assert_lint('typedef struct _Evas_Object Evas_Object;', '')
  4028. # NPAPI functions that start with NPN_, NPP_ or NP_ are allowed.
  4029. self.assert_lint('void NPN_Status(NPP, const char*)', '')
  4030. self.assert_lint('NPError NPP_SetWindow(NPP instance, NPWindow *window)', '')
  4031. self.assert_lint('NPObject* NP_Allocate(NPP, NPClass*)', '')
  4032. # const_iterator is allowed as well.
  4033. self.assert_lint('typedef VectorType::const_iterator const_iterator;', '')
  4034. # vm_throw is allowed as well.
  4035. self.assert_lint('int vm_throw;', '')
  4036. # Bitfields.
  4037. self.assert_lint('unsigned _fillRule : 1;',
  4038. '_fillRule' + name_underscore_error_message)
  4039. # new operators in initialization.
  4040. self.assert_lint('OwnPtr<uint32_t> variable(new uint32_t);', '')
  4041. self.assert_lint('OwnPtr<uint32_t> variable(new (expr) uint32_t);', '')
  4042. self.assert_lint('OwnPtr<uint32_t> under_score(new uint32_t);',
  4043. 'under_score' + name_underscore_error_message)
  4044. def test_parameter_names(self):
  4045. # Leave meaningless variable names out of function declarations.
  4046. meaningless_variable_name_error_message = 'The parameter name "%s" adds no information, so it should be removed. [readability/parameter_name] [5]'
  4047. parameter_error_rules = ('-',
  4048. '+readability/parameter_name')
  4049. # No variable name, so no error.
  4050. self.assertEquals('',
  4051. self.perform_lint('void func(int);', 'test.cpp', parameter_error_rules))
  4052. # Verify that copying the name of the set function causes the error (with some odd casing).
  4053. self.assertEquals(meaningless_variable_name_error_message % 'itemCount',
  4054. self.perform_lint('void setItemCount(size_t itemCount);', 'test.cpp', parameter_error_rules))
  4055. self.assertEquals(meaningless_variable_name_error_message % 'abcCount',
  4056. self.perform_lint('void setABCCount(size_t abcCount);', 'test.cpp', parameter_error_rules))
  4057. # Verify that copying a type name will trigger the warning (even if the type is a template parameter).
  4058. self.assertEquals(meaningless_variable_name_error_message % 'context',
  4059. self.perform_lint('void funct(PassRefPtr<ScriptExecutionContext> context);', 'test.cpp', parameter_error_rules))
  4060. # Verify that acronyms as variable names trigger the error (for both set functions and type names).
  4061. self.assertEquals(meaningless_variable_name_error_message % 'ec',
  4062. self.perform_lint('void setExceptionCode(int ec);', 'test.cpp', parameter_error_rules))
  4063. self.assertEquals(meaningless_variable_name_error_message % 'ec',
  4064. self.perform_lint('void funct(ExceptionCode ec);', 'test.cpp', parameter_error_rules))
  4065. # 'object' alone, appended, or as part of an acronym is meaningless.
  4066. self.assertEquals(meaningless_variable_name_error_message % 'object',
  4067. self.perform_lint('void funct(RenderView object);', 'test.cpp', parameter_error_rules))
  4068. self.assertEquals(meaningless_variable_name_error_message % 'viewObject',
  4069. self.perform_lint('void funct(RenderView viewObject);', 'test.cpp', parameter_error_rules))
  4070. self.assertEquals(meaningless_variable_name_error_message % 'rvo',
  4071. self.perform_lint('void funct(RenderView rvo);', 'test.cpp', parameter_error_rules))
  4072. # Check that r, g, b, and a are allowed.
  4073. self.assertEquals('',
  4074. self.perform_lint('void setRGBAValues(int r, int g, int b, int a);', 'test.cpp', parameter_error_rules))
  4075. # Verify that a simple substring match isn't done which would cause false positives.
  4076. self.assertEquals('',
  4077. self.perform_lint('void setNateLateCount(size_t elate);', 'test.cpp', parameter_error_rules))
  4078. self.assertEquals('',
  4079. self.perform_lint('void funct(NateLate elate);', 'test.cpp', parameter_error_rules))
  4080. # Don't have generate warnings for functions (only declarations).
  4081. self.assertEquals('',
  4082. self.perform_lint('void funct(PassRefPtr<ScriptExecutionContext> context)\n'
  4083. '{\n'
  4084. '}\n', 'test.cpp', parameter_error_rules))
  4085. def test_comments(self):
  4086. # A comment at the beginning of a line is ok.
  4087. self.assert_lint('// comment', '')
  4088. self.assert_lint(' // comment', '')
  4089. self.assert_lint('} // namespace WebCore',
  4090. 'One space before end of line comments'
  4091. ' [whitespace/comments] [5]')
  4092. def test_webkit_export_check(self):
  4093. webkit_export_error_rules = ('-',
  4094. '+readability/webkit_export')
  4095. self.assertEquals('',
  4096. self.perform_lint('WEBKIT_EXPORT int foo();\n',
  4097. 'WebKit/chromium/public/test.h',
  4098. webkit_export_error_rules))
  4099. self.assertEquals('WEBKIT_EXPORT should only be used in header files. [readability/webkit_export] [5]',
  4100. self.perform_lint('WEBKIT_EXPORT int foo();\n',
  4101. 'WebKit/chromium/public/test.cpp',
  4102. webkit_export_error_rules))
  4103. self.assertEquals('WEBKIT_EXPORT should only appear in the chromium public directory. [readability/webkit_export] [5]',
  4104. self.perform_lint('WEBKIT_EXPORT int foo();\n',
  4105. 'WebKit/chromium/src/test.h',
  4106. webkit_export_error_rules))
  4107. self.assertEquals('WEBKIT_EXPORT should not be used on a function with a body. [readability/webkit_export] [5]',
  4108. self.perform_lint('WEBKIT_EXPORT int foo() { }\n',
  4109. 'WebKit/chromium/public/test.h',
  4110. webkit_export_error_rules))
  4111. self.assertEquals('WEBKIT_EXPORT should not be used on a function with a body. [readability/webkit_export] [5]',
  4112. self.perform_lint('WEBKIT_EXPORT inline int foo()\n'
  4113. '{\n'
  4114. '}\n',
  4115. 'WebKit/chromium/public/test.h',
  4116. webkit_export_error_rules))
  4117. self.assertEquals('WEBKIT_EXPORT should not be used with a pure virtual function. [readability/webkit_export] [5]',
  4118. self.perform_lint('{}\n'
  4119. 'WEBKIT_EXPORT\n'
  4120. 'virtual\n'
  4121. 'int\n'
  4122. 'foo() = 0;\n',
  4123. 'WebKit/chromium/public/test.h',
  4124. webkit_export_error_rules))
  4125. self.assertEquals('',
  4126. self.perform_lint('{}\n'
  4127. 'WEBKIT_EXPORT\n'
  4128. 'virtual\n'
  4129. 'int\n'
  4130. 'foo() = 0;\n',
  4131. 'test.h',
  4132. webkit_export_error_rules))
  4133. def test_other(self):
  4134. # FIXME: Implement this.
  4135. pass
  4136. class CppCheckerTest(unittest.TestCase):
  4137. """Tests CppChecker class."""
  4138. def mock_handle_style_error(self):
  4139. pass
  4140. def _checker(self):
  4141. return CppChecker("foo", "h", self.mock_handle_style_error, 3)
  4142. def test_init(self):
  4143. """Test __init__ constructor."""
  4144. checker = self._checker()
  4145. self.assertEquals(checker.file_extension, "h")
  4146. self.assertEquals(checker.file_path, "foo")
  4147. self.assertEquals(checker.handle_style_error, self.mock_handle_style_error)
  4148. self.assertEquals(checker.min_confidence, 3)
  4149. def test_eq(self):
  4150. """Test __eq__ equality function."""
  4151. checker1 = self._checker()
  4152. checker2 = self._checker()
  4153. # == calls __eq__.
  4154. self.assertTrue(checker1 == checker2)
  4155. def mock_handle_style_error2(self):
  4156. pass
  4157. # Verify that a difference in any argument cause equality to fail.
  4158. checker = CppChecker("foo", "h", self.mock_handle_style_error, 3)
  4159. self.assertFalse(checker == CppChecker("bar", "h", self.mock_handle_style_error, 3))
  4160. self.assertFalse(checker == CppChecker("foo", "c", self.mock_handle_style_error, 3))
  4161. self.assertFalse(checker == CppChecker("foo", "h", mock_handle_style_error2, 3))
  4162. self.assertFalse(checker == CppChecker("foo", "h", self.mock_handle_style_error, 4))
  4163. def test_ne(self):
  4164. """Test __ne__ inequality function."""
  4165. checker1 = self._checker()
  4166. checker2 = self._checker()
  4167. # != calls __ne__.
  4168. # By default, __ne__ always returns true on different objects.
  4169. # Thus, just check the distinguishing case to verify that the
  4170. # code defines __ne__.
  4171. self.assertFalse(checker1 != checker2)
  4172. def tearDown():
  4173. """A global check to make sure all error-categories have been tested.
  4174. The main tearDown() routine is the only code we can guarantee will be
  4175. run after all other tests have been executed.
  4176. """
  4177. try:
  4178. if _run_verifyallcategoriesseen:
  4179. ErrorCollector(None).verify_all_categories_are_seen()
  4180. except NameError:
  4181. # If nobody set the global _run_verifyallcategoriesseen, then
  4182. # we assume we shouldn't run the test
  4183. pass
  4184. if __name__ == '__main__':
  4185. import sys
  4186. # We don't want to run the verify_all_categories_are_seen() test unless
  4187. # we're running the full test suite: if we only run one test,
  4188. # obviously we're not going to see all the error categories. So we
  4189. # only run verify_all_categories_are_seen() when no commandline flags
  4190. # are passed in.
  4191. global _run_verifyallcategoriesseen
  4192. _run_verifyallcategoriesseen = (len(sys.argv) == 1)
  4193. unittest.main()