PageRenderTime 49ms CodeModel.GetById 10ms RepoModel.GetById 0ms 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

Large files files are truncated, but you can click here to view the full 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 *…

Large files files are truncated, but you can click here to view the full file