blob: 997625b7789af6de507c4dc61bc6fd10a2c5bc97 [file] [log] [blame]
[email protected]2299dcf2012-11-15 19:56:241#!/usr/bin/env python
2# Copyright (c) 2012 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
Daniel Cheng4dcdb6b2017-04-13 08:30:176import os.path
[email protected]2299dcf2012-11-15 19:56:247import re
[email protected]99171a92014-06-03 08:44:478import subprocess
[email protected]2299dcf2012-11-15 19:56:249import unittest
10
11import PRESUBMIT
glidere61efad2015-02-18 17:39:4312from PRESUBMIT_test_mocks import MockChange, MockFile, MockAffectedFile
gayane3dff8c22014-12-04 17:09:5113from PRESUBMIT_test_mocks import MockInputApi, MockOutputApi
[email protected]2299dcf2012-11-15 19:56:2414
[email protected]99171a92014-06-03 08:44:4715_TEST_DATA_DIR = 'base/test/data/presubmit'
16
[email protected]b00342e7f2013-03-26 16:21:5417class VersionControlConflictsTest(unittest.TestCase):
[email protected]70ca77752012-11-20 03:45:0318 def testTypicalConflict(self):
19 lines = ['<<<<<<< HEAD',
20 ' base::ScopedTempDir temp_dir_;',
21 '=======',
22 ' ScopedTempDir temp_dir_;',
23 '>>>>>>> master']
24 errors = PRESUBMIT._CheckForVersionControlConflictsInFile(
25 MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
26 self.assertEqual(3, len(errors))
27 self.assertTrue('1' in errors[0])
28 self.assertTrue('3' in errors[1])
29 self.assertTrue('5' in errors[2])
30
dbeam95c35a2f2015-06-02 01:40:2331 def testIgnoresReadmes(self):
32 lines = ['A First Level Header',
33 '====================',
34 '',
35 'A Second Level Header',
36 '---------------------']
37 errors = PRESUBMIT._CheckForVersionControlConflictsInFile(
38 MockInputApi(), MockFile('some/polymer/README.md', lines))
39 self.assertEqual(0, len(errors))
40
mcasasb7440c282015-02-04 14:52:1941class UmaHistogramChangeMatchedOrNotTest(unittest.TestCase):
42 def testTypicalCorrectlyMatchedChange(self):
43 diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
Vaclav Brozekbdac817c2018-03-24 06:30:4744 diff_java = [
45 'RecordHistogram.recordBooleanHistogram("Bla.Foo.Dummy", true)']
mcasasb7440c282015-02-04 14:52:1946 diff_xml = ['<histogram name="Bla.Foo.Dummy"> </histogram>']
47 mock_input_api = MockInputApi()
48 mock_input_api.files = [
49 MockFile('some/path/foo.cc', diff_cc),
Vaclav Brozekbdac817c2018-03-24 06:30:4750 MockFile('some/path/foo.java', diff_java),
mcasasb7440c282015-02-04 14:52:1951 MockFile('tools/metrics/histograms/histograms.xml', diff_xml),
52 ]
53 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
54 MockOutputApi())
55 self.assertEqual(0, len(warnings))
56
57 def testTypicalNotMatchedChange(self):
58 diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
Vaclav Brozekbdac817c2018-03-24 06:30:4759 diff_java = [
60 'RecordHistogram.recordBooleanHistogram("Bla.Foo.Dummy", true)']
mcasasb7440c282015-02-04 14:52:1961 mock_input_api = MockInputApi()
Vaclav Brozekbdac817c2018-03-24 06:30:4762 mock_input_api.files = [
63 MockFile('some/path/foo.cc', diff_cc),
64 MockFile('some/path/foo.java', diff_java),
65 ]
mcasasb7440c282015-02-04 14:52:1966 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
67 MockOutputApi())
68 self.assertEqual(1, len(warnings))
69 self.assertEqual('warning', warnings[0].type)
Vaclav Brozekbdac817c2018-03-24 06:30:4770 self.assertTrue('foo.cc' in warnings[0].items[0])
71 self.assertTrue('foo.java' in warnings[0].items[1])
mcasasb7440c282015-02-04 14:52:1972
73 def testTypicalNotMatchedChangeViaSuffixes(self):
74 diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
Vaclav Brozekbdac817c2018-03-24 06:30:4775 diff_java = [
76 'RecordHistogram.recordBooleanHistogram("Bla.Foo.Dummy", true)']
mcasasb7440c282015-02-04 14:52:1977 diff_xml = ['<histogram_suffixes name="SuperHistogram">',
78 ' <suffix name="Dummy"/>',
79 ' <affected-histogram name="Snafu.Dummy"/>',
80 '</histogram>']
81 mock_input_api = MockInputApi()
82 mock_input_api.files = [
83 MockFile('some/path/foo.cc', diff_cc),
Vaclav Brozekbdac817c2018-03-24 06:30:4784 MockFile('some/path/foo.java', diff_java),
mcasasb7440c282015-02-04 14:52:1985 MockFile('tools/metrics/histograms/histograms.xml', diff_xml),
86 ]
87 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
88 MockOutputApi())
89 self.assertEqual(1, len(warnings))
90 self.assertEqual('warning', warnings[0].type)
Vaclav Brozekbdac817c2018-03-24 06:30:4791 self.assertTrue('foo.cc' in warnings[0].items[0])
92 self.assertTrue('foo.java' in warnings[0].items[1])
mcasasb7440c282015-02-04 14:52:1993
94 def testTypicalCorrectlyMatchedChangeViaSuffixes(self):
95 diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
Vaclav Brozekbdac817c2018-03-24 06:30:4796 diff_java = [
97 'RecordHistogram.recordBooleanHistogram("Bla.Foo.Dummy", true)']
mcasasb7440c282015-02-04 14:52:1998 diff_xml = ['<histogram_suffixes name="SuperHistogram">',
99 ' <suffix name="Dummy"/>',
100 ' <affected-histogram name="Bla.Foo"/>',
101 '</histogram>']
102 mock_input_api = MockInputApi()
103 mock_input_api.files = [
104 MockFile('some/path/foo.cc', diff_cc),
Vaclav Brozekbdac817c2018-03-24 06:30:47105 MockFile('some/path/foo.java', diff_java),
mcasasb7440c282015-02-04 14:52:19106 MockFile('tools/metrics/histograms/histograms.xml', diff_xml),
107 ]
108 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
109 MockOutputApi())
110 self.assertEqual(0, len(warnings))
111
112 def testTypicalCorrectlyMatchedChangeViaSuffixesWithSeparator(self):
113 diff_cc = ['UMA_HISTOGRAM_BOOL("Snafu_Dummy", true)']
Vaclav Brozekbdac817c2018-03-24 06:30:47114 diff_java = ['RecordHistogram.recordBooleanHistogram("Snafu_Dummy", true)']
mcasasb7440c282015-02-04 14:52:19115 diff_xml = ['<histogram_suffixes name="SuperHistogram" separator="_">',
116 ' <suffix name="Dummy"/>',
117 ' <affected-histogram name="Snafu"/>',
118 '</histogram>']
119 mock_input_api = MockInputApi()
120 mock_input_api.files = [
121 MockFile('some/path/foo.cc', diff_cc),
Vaclav Brozekbdac817c2018-03-24 06:30:47122 MockFile('some/path/foo.java', diff_java),
mcasasb7440c282015-02-04 14:52:19123 MockFile('tools/metrics/histograms/histograms.xml', diff_xml),
124 ]
125 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
126 MockOutputApi())
127 self.assertEqual(0, len(warnings))
[email protected]70ca77752012-11-20 03:45:03128
Vaclav Brozek8a8e2e202018-03-23 22:01:06129 def testNameMatch(self):
130 # Check that the detected histogram name is "Dummy" and not, e.g.,
131 # "Dummy\", true); // The \"correct"
132 diff_cc = ['UMA_HISTOGRAM_BOOL("Dummy", true); // The "correct" histogram']
Vaclav Brozekbdac817c2018-03-24 06:30:47133 diff_java = [
134 'RecordHistogram.recordBooleanHistogram("Dummy", true);'
135 + ' // The "correct" histogram']
Vaclav Brozek8a8e2e202018-03-23 22:01:06136 diff_xml = ['<histogram name="Dummy"> </histogram>']
137 mock_input_api = MockInputApi()
138 mock_input_api.files = [
139 MockFile('some/path/foo.cc', diff_cc),
Vaclav Brozekbdac817c2018-03-24 06:30:47140 MockFile('some/path/foo.java', diff_java),
Vaclav Brozek8a8e2e202018-03-23 22:01:06141 MockFile('tools/metrics/histograms/histograms.xml', diff_xml),
142 ]
143 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
144 MockOutputApi())
145 self.assertEqual(0, len(warnings))
146
147 def testSimilarMacroNames(self):
Vaclav Brozekbdac817c2018-03-24 06:30:47148 diff_cc = ['PUMA_HISTOGRAM_COOL("Mountain Lion", 42)']
149 diff_java = [
150 'FakeRecordHistogram.recordFakeHistogram("Mountain Lion", 42)']
Vaclav Brozek8a8e2e202018-03-23 22:01:06151 mock_input_api = MockInputApi()
152 mock_input_api.files = [
153 MockFile('some/path/foo.cc', diff_cc),
Vaclav Brozekbdac817c2018-03-24 06:30:47154 MockFile('some/path/foo.java', diff_java),
Vaclav Brozek8a8e2e202018-03-23 22:01:06155 ]
156 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
157 MockOutputApi())
158 self.assertEqual(0, len(warnings))
159
Vaclav Brozek0e730cbd2018-03-24 06:18:17160 def testMultiLine(self):
161 diff_cc = ['UMA_HISTOGRAM_BOOLEAN(', ' "Multi.Line", true)']
162 diff_cc2 = ['UMA_HISTOGRAM_BOOLEAN(', ' "Multi.Line"', ' , true)']
Vaclav Brozekbdac817c2018-03-24 06:30:47163 diff_java = [
164 'RecordHistogram.recordBooleanHistogram(',
165 ' "Multi.Line", true);',
166 ]
Vaclav Brozek0e730cbd2018-03-24 06:18:17167 mock_input_api = MockInputApi()
168 mock_input_api.files = [
169 MockFile('some/path/foo.cc', diff_cc),
170 MockFile('some/path/foo2.cc', diff_cc2),
Vaclav Brozekbdac817c2018-03-24 06:30:47171 MockFile('some/path/foo.java', diff_java),
Vaclav Brozek0e730cbd2018-03-24 06:18:17172 ]
173 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
174 MockOutputApi())
175 self.assertEqual(1, len(warnings))
176 self.assertEqual('warning', warnings[0].type)
177 self.assertTrue('foo.cc' in warnings[0].items[0])
178 self.assertTrue('foo2.cc' in warnings[0].items[1])
179
[email protected]b8079ae4a2012-12-05 19:56:49180class BadExtensionsTest(unittest.TestCase):
181 def testBadRejFile(self):
182 mock_input_api = MockInputApi()
183 mock_input_api.files = [
184 MockFile('some/path/foo.cc', ''),
185 MockFile('some/path/foo.cc.rej', ''),
186 MockFile('some/path2/bar.h.rej', ''),
187 ]
188
189 results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
190 self.assertEqual(1, len(results))
191 self.assertEqual(2, len(results[0].items))
192 self.assertTrue('foo.cc.rej' in results[0].items[0])
193 self.assertTrue('bar.h.rej' in results[0].items[1])
194
195 def testBadOrigFile(self):
196 mock_input_api = MockInputApi()
197 mock_input_api.files = [
198 MockFile('other/path/qux.h.orig', ''),
199 MockFile('other/path/qux.h', ''),
200 MockFile('other/path/qux.cc', ''),
201 ]
202
203 results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
204 self.assertEqual(1, len(results))
205 self.assertEqual(1, len(results[0].items))
206 self.assertTrue('qux.h.orig' in results[0].items[0])
207
208 def testGoodFiles(self):
209 mock_input_api = MockInputApi()
210 mock_input_api.files = [
211 MockFile('other/path/qux.h', ''),
212 MockFile('other/path/qux.cc', ''),
213 ]
214 results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
215 self.assertEqual(0, len(results))
216
217
glidere61efad2015-02-18 17:39:43218class CheckSingletonInHeadersTest(unittest.TestCase):
219 def testSingletonInArbitraryHeader(self):
220 diff_singleton_h = ['base::subtle::AtomicWord '
olli.raula36aa8be2015-09-10 11:14:22221 'base::Singleton<Type, Traits, DifferentiatingType>::']
222 diff_foo_h = ['// base::Singleton<Foo> in comment.',
223 'friend class base::Singleton<Foo>']
oysteinec430ad42015-10-22 20:55:24224 diff_foo2_h = [' //Foo* bar = base::Singleton<Foo>::get();']
olli.raula36aa8be2015-09-10 11:14:22225 diff_bad_h = ['Foo* foo = base::Singleton<Foo>::get();']
glidere61efad2015-02-18 17:39:43226 mock_input_api = MockInputApi()
227 mock_input_api.files = [MockAffectedFile('base/memory/singleton.h',
228 diff_singleton_h),
229 MockAffectedFile('foo.h', diff_foo_h),
oysteinec430ad42015-10-22 20:55:24230 MockAffectedFile('foo2.h', diff_foo2_h),
glidere61efad2015-02-18 17:39:43231 MockAffectedFile('bad.h', diff_bad_h)]
232 warnings = PRESUBMIT._CheckSingletonInHeaders(mock_input_api,
233 MockOutputApi())
234 self.assertEqual(1, len(warnings))
Sylvain Defresnea8b73d252018-02-28 15:45:54235 self.assertEqual(1, len(warnings[0].items))
glidere61efad2015-02-18 17:39:43236 self.assertEqual('error', warnings[0].type)
olli.raula36aa8be2015-09-10 11:14:22237 self.assertTrue('Found base::Singleton<T>' in warnings[0].message)
glidere61efad2015-02-18 17:39:43238
239 def testSingletonInCC(self):
olli.raula36aa8be2015-09-10 11:14:22240 diff_cc = ['Foo* foo = base::Singleton<Foo>::get();']
glidere61efad2015-02-18 17:39:43241 mock_input_api = MockInputApi()
242 mock_input_api.files = [MockAffectedFile('some/path/foo.cc', diff_cc)]
243 warnings = PRESUBMIT._CheckSingletonInHeaders(mock_input_api,
244 MockOutputApi())
245 self.assertEqual(0, len(warnings))
246
247
[email protected]b00342e7f2013-03-26 16:21:54248class InvalidOSMacroNamesTest(unittest.TestCase):
249 def testInvalidOSMacroNames(self):
250 lines = ['#if defined(OS_WINDOWS)',
251 ' #elif defined(OS_WINDOW)',
252 ' # if defined(OS_MACOSX) || defined(OS_CHROME)',
253 '# else // defined(OS_MAC)',
254 '#endif // defined(OS_MACOS)']
255 errors = PRESUBMIT._CheckForInvalidOSMacrosInFile(
256 MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
257 self.assertEqual(len(lines), len(errors))
258 self.assertTrue(':1 OS_WINDOWS' in errors[0])
259 self.assertTrue('(did you mean OS_WIN?)' in errors[0])
260
261 def testValidOSMacroNames(self):
262 lines = ['#if defined(%s)' % m for m in PRESUBMIT._VALID_OS_MACROS]
263 errors = PRESUBMIT._CheckForInvalidOSMacrosInFile(
264 MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
265 self.assertEqual(0, len(errors))
266
267
lliabraa35bab3932014-10-01 12:16:44268class InvalidIfDefinedMacroNamesTest(unittest.TestCase):
269 def testInvalidIfDefinedMacroNames(self):
270 lines = ['#if defined(TARGET_IPHONE_SIMULATOR)',
271 '#if !defined(TARGET_IPHONE_SIMULATOR)',
272 '#elif defined(TARGET_IPHONE_SIMULATOR)',
273 '#ifdef TARGET_IPHONE_SIMULATOR',
274 ' # ifdef TARGET_IPHONE_SIMULATOR',
275 '# if defined(VALID) || defined(TARGET_IPHONE_SIMULATOR)',
276 '# else // defined(TARGET_IPHONE_SIMULATOR)',
277 '#endif // defined(TARGET_IPHONE_SIMULATOR)',]
278 errors = PRESUBMIT._CheckForInvalidIfDefinedMacrosInFile(
279 MockInputApi(), MockFile('some/path/source.mm', lines))
280 self.assertEqual(len(lines), len(errors))
281
282 def testValidIfDefinedMacroNames(self):
283 lines = ['#if defined(FOO)',
284 '#ifdef BAR',]
285 errors = PRESUBMIT._CheckForInvalidIfDefinedMacrosInFile(
286 MockInputApi(), MockFile('some/path/source.cc', lines))
287 self.assertEqual(0, len(errors))
288
289
[email protected]f32e2d1e2013-07-26 21:39:08290class CheckAddedDepsHaveTetsApprovalsTest(unittest.TestCase):
Daniel Cheng4dcdb6b2017-04-13 08:30:17291
292 def calculate(self, old_include_rules, old_specific_include_rules,
293 new_include_rules, new_specific_include_rules):
294 return PRESUBMIT._CalculateAddedDeps(
295 os.path, 'include_rules = %r\nspecific_include_rules = %r' % (
296 old_include_rules, old_specific_include_rules),
297 'include_rules = %r\nspecific_include_rules = %r' % (
298 new_include_rules, new_specific_include_rules))
299
300 def testCalculateAddedDeps(self):
301 old_include_rules = [
302 '+base',
303 '-chrome',
304 '+content',
305 '-grit',
306 '-grit/",',
307 '+jni/fooblat.h',
308 '!sandbox',
[email protected]f32e2d1e2013-07-26 21:39:08309 ]
Daniel Cheng4dcdb6b2017-04-13 08:30:17310 old_specific_include_rules = {
311 'compositor\.*': {
312 '+cc',
313 },
314 }
315
316 new_include_rules = [
317 '-ash',
318 '+base',
319 '+chrome',
320 '+components',
321 '+content',
322 '+grit',
323 '+grit/generated_resources.h",',
324 '+grit/",',
325 '+jni/fooblat.h',
326 '+policy',
manzagop85e629e2017-05-09 22:11:48327 '+' + os.path.join('third_party', 'WebKit'),
Daniel Cheng4dcdb6b2017-04-13 08:30:17328 ]
329 new_specific_include_rules = {
330 'compositor\.*': {
331 '+cc',
332 },
333 'widget\.*': {
334 '+gpu',
335 },
336 }
337
[email protected]f32e2d1e2013-07-26 21:39:08338 expected = set([
manzagop85e629e2017-05-09 22:11:48339 os.path.join('chrome', 'DEPS'),
340 os.path.join('gpu', 'DEPS'),
341 os.path.join('components', 'DEPS'),
342 os.path.join('policy', 'DEPS'),
343 os.path.join('third_party', 'WebKit', 'DEPS'),
[email protected]f32e2d1e2013-07-26 21:39:08344 ])
Daniel Cheng4dcdb6b2017-04-13 08:30:17345 self.assertEqual(
346 expected,
347 self.calculate(old_include_rules, old_specific_include_rules,
348 new_include_rules, new_specific_include_rules))
349
350 def testCalculateAddedDepsIgnoresPermutations(self):
351 old_include_rules = [
352 '+base',
353 '+chrome',
354 ]
355 new_include_rules = [
356 '+chrome',
357 '+base',
358 ]
359 self.assertEqual(set(),
360 self.calculate(old_include_rules, {}, new_include_rules,
361 {}))
[email protected]f32e2d1e2013-07-26 21:39:08362
363
[email protected]99171a92014-06-03 08:44:47364class JSONParsingTest(unittest.TestCase):
365 def testSuccess(self):
366 input_api = MockInputApi()
367 filename = 'valid_json.json'
368 contents = ['// This is a comment.',
369 '{',
370 ' "key1": ["value1", "value2"],',
371 ' "key2": 3 // This is an inline comment.',
372 '}'
373 ]
374 input_api.files = [MockFile(filename, contents)]
375 self.assertEqual(None,
376 PRESUBMIT._GetJSONParseError(input_api, filename))
377
378 def testFailure(self):
379 input_api = MockInputApi()
380 test_data = [
381 ('invalid_json_1.json',
382 ['{ x }'],
[email protected]a3343272014-06-17 11:41:53383 'Expecting property name:'),
[email protected]99171a92014-06-03 08:44:47384 ('invalid_json_2.json',
385 ['// Hello world!',
386 '{ "hello": "world }'],
[email protected]a3343272014-06-17 11:41:53387 'Unterminated string starting at:'),
[email protected]99171a92014-06-03 08:44:47388 ('invalid_json_3.json',
389 ['{ "a": "b", "c": "d", }'],
[email protected]a3343272014-06-17 11:41:53390 'Expecting property name:'),
[email protected]99171a92014-06-03 08:44:47391 ('invalid_json_4.json',
392 ['{ "a": "b" "c": "d" }'],
[email protected]a3343272014-06-17 11:41:53393 'Expecting , delimiter:'),
[email protected]99171a92014-06-03 08:44:47394 ]
395
396 input_api.files = [MockFile(filename, contents)
397 for (filename, contents, _) in test_data]
398
399 for (filename, _, expected_error) in test_data:
400 actual_error = PRESUBMIT._GetJSONParseError(input_api, filename)
[email protected]a3343272014-06-17 11:41:53401 self.assertTrue(expected_error in str(actual_error),
402 "'%s' not found in '%s'" % (expected_error, actual_error))
[email protected]99171a92014-06-03 08:44:47403
404 def testNoEatComments(self):
405 input_api = MockInputApi()
406 file_with_comments = 'file_with_comments.json'
407 contents_with_comments = ['// This is a comment.',
408 '{',
409 ' "key1": ["value1", "value2"],',
410 ' "key2": 3 // This is an inline comment.',
411 '}'
412 ]
413 file_without_comments = 'file_without_comments.json'
414 contents_without_comments = ['{',
415 ' "key1": ["value1", "value2"],',
416 ' "key2": 3',
417 '}'
418 ]
419 input_api.files = [MockFile(file_with_comments, contents_with_comments),
420 MockFile(file_without_comments,
421 contents_without_comments)]
422
423 self.assertEqual('No JSON object could be decoded',
424 str(PRESUBMIT._GetJSONParseError(input_api,
425 file_with_comments,
426 eat_comments=False)))
427 self.assertEqual(None,
428 PRESUBMIT._GetJSONParseError(input_api,
429 file_without_comments,
430 eat_comments=False))
431
432
433class IDLParsingTest(unittest.TestCase):
434 def testSuccess(self):
435 input_api = MockInputApi()
436 filename = 'valid_idl_basics.idl'
437 contents = ['// Tests a valid IDL file.',
438 'namespace idl_basics {',
439 ' enum EnumType {',
440 ' name1,',
441 ' name2',
442 ' };',
443 '',
444 ' dictionary MyType1 {',
445 ' DOMString a;',
446 ' };',
447 '',
448 ' callback Callback1 = void();',
449 ' callback Callback2 = void(long x);',
450 ' callback Callback3 = void(MyType1 arg);',
451 ' callback Callback4 = void(EnumType type);',
452 '',
453 ' interface Functions {',
454 ' static void function1();',
455 ' static void function2(long x);',
456 ' static void function3(MyType1 arg);',
457 ' static void function4(Callback1 cb);',
458 ' static void function5(Callback2 cb);',
459 ' static void function6(Callback3 cb);',
460 ' static void function7(Callback4 cb);',
461 ' };',
462 '',
463 ' interface Events {',
464 ' static void onFoo1();',
465 ' static void onFoo2(long x);',
466 ' static void onFoo2(MyType1 arg);',
467 ' static void onFoo3(EnumType type);',
468 ' };',
469 '};'
470 ]
471 input_api.files = [MockFile(filename, contents)]
472 self.assertEqual(None,
473 PRESUBMIT._GetIDLParseError(input_api, filename))
474
475 def testFailure(self):
476 input_api = MockInputApi()
477 test_data = [
478 ('invalid_idl_1.idl',
479 ['//',
480 'namespace test {',
481 ' dictionary {',
482 ' DOMString s;',
483 ' };',
484 '};'],
485 'Unexpected "{" after keyword "dictionary".\n'),
486 # TODO(yoz): Disabled because it causes the IDL parser to hang.
487 # See crbug.com/363830.
488 # ('invalid_idl_2.idl',
489 # (['namespace test {',
490 # ' dictionary MissingSemicolon {',
491 # ' DOMString a',
492 # ' DOMString b;',
493 # ' };',
494 # '};'],
495 # 'Unexpected symbol DOMString after symbol a.'),
496 ('invalid_idl_3.idl',
497 ['//',
498 'namespace test {',
499 ' enum MissingComma {',
500 ' name1',
501 ' name2',
502 ' };',
503 '};'],
504 'Unexpected symbol name2 after symbol name1.'),
505 ('invalid_idl_4.idl',
506 ['//',
507 'namespace test {',
508 ' enum TrailingComma {',
509 ' name1,',
510 ' name2,',
511 ' };',
512 '};'],
513 'Trailing comma in block.'),
514 ('invalid_idl_5.idl',
515 ['//',
516 'namespace test {',
517 ' callback Callback1 = void(;',
518 '};'],
519 'Unexpected ";" after "(".'),
520 ('invalid_idl_6.idl',
521 ['//',
522 'namespace test {',
523 ' callback Callback1 = void(long );',
524 '};'],
525 'Unexpected ")" after symbol long.'),
526 ('invalid_idl_7.idl',
527 ['//',
528 'namespace test {',
529 ' interace Events {',
530 ' static void onFoo1();',
531 ' };',
532 '};'],
533 'Unexpected symbol Events after symbol interace.'),
534 ('invalid_idl_8.idl',
535 ['//',
536 'namespace test {',
537 ' interface NotEvent {',
538 ' static void onFoo1();',
539 ' };',
540 '};'],
541 'Did not process Interface Interface(NotEvent)'),
542 ('invalid_idl_9.idl',
543 ['//',
544 'namespace test {',
545 ' interface {',
546 ' static void function1();',
547 ' };',
548 '};'],
549 'Interface missing name.'),
550 ]
551
552 input_api.files = [MockFile(filename, contents)
553 for (filename, contents, _) in test_data]
554
555 for (filename, _, expected_error) in test_data:
556 actual_error = PRESUBMIT._GetIDLParseError(input_api, filename)
557 self.assertTrue(expected_error in str(actual_error),
558 "'%s' not found in '%s'" % (expected_error, actual_error))
559
560
[email protected]0bb112362014-07-26 04:38:32561class TryServerMasterTest(unittest.TestCase):
562 def testTryServerMasters(self):
563 bots = {
tandriie5587792016-07-14 00:34:50564 'master.tryserver.chromium.android': [
jbudorick3ae7a772016-05-20 02:36:04565 'android_archive_rel_ng',
566 'android_arm64_dbg_recipe',
567 'android_blink_rel',
568 'android_chromium_variable',
569 'android_chromium_variable_archive',
570 'android_chromium_variable_arm64',
571 'android_chromium_variable_cast_shell',
572 'android_chromium_variable_clang',
573 'android_chromium_variable_gn',
574 'android_chromium_variable_nexus4',
575 'android_clang_dbg_recipe',
576 'android_compile_dbg',
jbudorick3ae7a772016-05-20 02:36:04577 'android_compile_x64_dbg',
578 'android_compile_x86_dbg',
579 'android_coverage',
580 'android_cronet_tester'
581 'android_swarming_rel',
582 'cast_shell_android',
583 'linux_android_dbg_ng',
584 'linux_android_rel_ng',
585 ],
tandriie5587792016-07-14 00:34:50586 'master.tryserver.chromium.mac': [
[email protected]0bb112362014-07-26 04:38:32587 'ios_dbg_simulator',
588 'ios_rel_device',
589 'ios_rel_device_ninja',
590 'mac_asan',
591 'mac_asan_64',
592 'mac_chromium_compile_dbg',
593 'mac_chromium_compile_rel',
594 'mac_chromium_dbg',
595 'mac_chromium_rel',
[email protected]0bb112362014-07-26 04:38:32596 'mac_nacl_sdk',
597 'mac_nacl_sdk_build',
598 'mac_rel_naclmore',
[email protected]0bb112362014-07-26 04:38:32599 'mac_x64_rel',
600 'mac_xcodebuild',
601 ],
tandriie5587792016-07-14 00:34:50602 'master.tryserver.chromium.linux': [
[email protected]0bb112362014-07-26 04:38:32603 'chromium_presubmit',
604 'linux_arm_cross_compile',
605 'linux_arm_tester',
[email protected]0bb112362014-07-26 04:38:32606 'linux_chromeos_asan',
607 'linux_chromeos_browser_asan',
608 'linux_chromeos_valgrind',
[email protected]0bb112362014-07-26 04:38:32609 'linux_chromium_chromeos_dbg',
610 'linux_chromium_chromeos_rel',
[email protected]0bb112362014-07-26 04:38:32611 'linux_chromium_compile_dbg',
612 'linux_chromium_compile_rel',
613 'linux_chromium_dbg',
614 'linux_chromium_gn_dbg',
615 'linux_chromium_gn_rel',
616 'linux_chromium_rel',
[email protected]0bb112362014-07-26 04:38:32617 'linux_chromium_trusty32_dbg',
618 'linux_chromium_trusty32_rel',
619 'linux_chromium_trusty_dbg',
620 'linux_chromium_trusty_rel',
621 'linux_clang_tsan',
622 'linux_ecs_ozone',
623 'linux_layout',
624 'linux_layout_asan',
625 'linux_layout_rel',
626 'linux_layout_rel_32',
627 'linux_nacl_sdk',
628 'linux_nacl_sdk_bionic',
629 'linux_nacl_sdk_bionic_build',
630 'linux_nacl_sdk_build',
631 'linux_redux',
632 'linux_rel_naclmore',
633 'linux_rel_precise32',
634 'linux_valgrind',
635 'tools_build_presubmit',
636 ],
tandriie5587792016-07-14 00:34:50637 'master.tryserver.chromium.win': [
[email protected]0bb112362014-07-26 04:38:32638 'win8_aura',
639 'win8_chromium_dbg',
640 'win8_chromium_rel',
641 'win_chromium_compile_dbg',
642 'win_chromium_compile_rel',
643 'win_chromium_dbg',
644 'win_chromium_rel',
645 'win_chromium_rel',
[email protected]0bb112362014-07-26 04:38:32646 'win_chromium_x64_dbg',
647 'win_chromium_x64_rel',
[email protected]0bb112362014-07-26 04:38:32648 'win_nacl_sdk',
649 'win_nacl_sdk_build',
650 'win_rel_naclmore',
651 ],
652 }
653 for master, bots in bots.iteritems():
654 for bot in bots:
655 self.assertEqual(master, PRESUBMIT.GetTryServerMasterForBot(bot),
656 'bot=%s: expected %s, computed %s' % (
657 bot, master, PRESUBMIT.GetTryServerMasterForBot(bot)))
658
659
davileene0426252015-03-02 21:10:41660class UserMetricsActionTest(unittest.TestCase):
661 def testUserMetricsActionInActions(self):
662 input_api = MockInputApi()
663 file_with_user_action = 'file_with_user_action.cc'
664 contents_with_user_action = [
665 'base::UserMetricsAction("AboutChrome")'
666 ]
667
668 input_api.files = [MockFile(file_with_user_action,
669 contents_with_user_action)]
670
671 self.assertEqual(
672 [], PRESUBMIT._CheckUserActionUpdate(input_api, MockOutputApi()))
673
674
675 def testUserMetricsActionNotAddedToActions(self):
676 input_api = MockInputApi()
677 file_with_user_action = 'file_with_user_action.cc'
678 contents_with_user_action = [
679 'base::UserMetricsAction("NotInActionsXml")'
680 ]
681
682 input_api.files = [MockFile(file_with_user_action,
683 contents_with_user_action)]
684
685 output = PRESUBMIT._CheckUserActionUpdate(input_api, MockOutputApi())
686 self.assertEqual(
687 ('File %s line %d: %s is missing in '
688 'tools/metrics/actions/actions.xml. Please run '
689 'tools/metrics/actions/extract_actions.py to update.'
690 % (file_with_user_action, 1, 'NotInActionsXml')),
691 output[0].message)
692
693
agrievef32bcc72016-04-04 14:57:40694class PydepsNeedsUpdatingTest(unittest.TestCase):
695
696 class MockSubprocess(object):
697 CalledProcessError = subprocess.CalledProcessError
698
699 def setUp(self):
700 mock_all_pydeps = ['A.pydeps', 'B.pydeps']
701 self.old_ALL_PYDEPS_FILES = PRESUBMIT._ALL_PYDEPS_FILES
702 PRESUBMIT._ALL_PYDEPS_FILES = mock_all_pydeps
703 self.mock_input_api = MockInputApi()
704 self.mock_output_api = MockOutputApi()
705 self.mock_input_api.subprocess = PydepsNeedsUpdatingTest.MockSubprocess()
706 self.checker = PRESUBMIT.PydepsChecker(self.mock_input_api, mock_all_pydeps)
707 self.checker._file_cache = {
708 'A.pydeps': '# Generated by:\n# CMD A\nA.py\nC.py\n',
709 'B.pydeps': '# Generated by:\n# CMD B\nB.py\nC.py\n',
710 }
711
712 def tearDown(self):
713 PRESUBMIT._ALL_PYDEPS_FILES = self.old_ALL_PYDEPS_FILES
714
715 def _RunCheck(self):
716 return PRESUBMIT._CheckPydepsNeedsUpdating(self.mock_input_api,
717 self.mock_output_api,
718 checker_for_tests=self.checker)
719
720 def testAddedPydep(self):
pastarmovj89f7ee12016-09-20 14:58:13721 # PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
722 if self.mock_input_api.platform != 'linux2':
723 return []
724
agrievef32bcc72016-04-04 14:57:40725 self.mock_input_api.files = [
726 MockAffectedFile('new.pydeps', [], action='A'),
727 ]
728
Zhiling Huang45cabf32018-03-10 00:50:03729 self.mock_input_api.CreateMockFileInPath(
730 [x.LocalPath() for x in self.mock_input_api.AffectedFiles(
731 include_deletes=True)])
agrievef32bcc72016-04-04 14:57:40732 results = self._RunCheck()
733 self.assertEqual(1, len(results))
734 self.assertTrue('PYDEPS_FILES' in str(results[0]))
735
Zhiling Huang45cabf32018-03-10 00:50:03736 def testPydepNotInSrc(self):
737 self.mock_input_api.files = [
738 MockAffectedFile('new.pydeps', [], action='A'),
739 ]
740 self.mock_input_api.CreateMockFileInPath([])
741 results = self._RunCheck()
742 self.assertEqual(0, len(results))
743
agrievef32bcc72016-04-04 14:57:40744 def testRemovedPydep(self):
pastarmovj89f7ee12016-09-20 14:58:13745 # PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
746 if self.mock_input_api.platform != 'linux2':
747 return []
748
agrievef32bcc72016-04-04 14:57:40749 self.mock_input_api.files = [
750 MockAffectedFile(PRESUBMIT._ALL_PYDEPS_FILES[0], [], action='D'),
751 ]
Zhiling Huang45cabf32018-03-10 00:50:03752 self.mock_input_api.CreateMockFileInPath(
753 [x.LocalPath() for x in self.mock_input_api.AffectedFiles(
754 include_deletes=True)])
agrievef32bcc72016-04-04 14:57:40755 results = self._RunCheck()
756 self.assertEqual(1, len(results))
757 self.assertTrue('PYDEPS_FILES' in str(results[0]))
758
759 def testRandomPyIgnored(self):
pastarmovj89f7ee12016-09-20 14:58:13760 # PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
761 if self.mock_input_api.platform != 'linux2':
762 return []
763
agrievef32bcc72016-04-04 14:57:40764 self.mock_input_api.files = [
765 MockAffectedFile('random.py', []),
766 ]
767
768 results = self._RunCheck()
769 self.assertEqual(0, len(results), 'Unexpected results: %r' % results)
770
771 def testRelevantPyNoChange(self):
pastarmovj89f7ee12016-09-20 14:58:13772 # PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
773 if self.mock_input_api.platform != 'linux2':
774 return []
775
agrievef32bcc72016-04-04 14:57:40776 self.mock_input_api.files = [
777 MockAffectedFile('A.py', []),
778 ]
779
John Budorickab2fa102017-10-06 16:59:49780 def mock_check_output(cmd, shell=False, env=None):
agrievef32bcc72016-04-04 14:57:40781 self.assertEqual('CMD A --output ""', cmd)
782 return self.checker._file_cache['A.pydeps']
783
784 self.mock_input_api.subprocess.check_output = mock_check_output
785
786 results = self._RunCheck()
787 self.assertEqual(0, len(results), 'Unexpected results: %r' % results)
788
789 def testRelevantPyOneChange(self):
pastarmovj89f7ee12016-09-20 14:58:13790 # PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
791 if self.mock_input_api.platform != 'linux2':
792 return []
793
agrievef32bcc72016-04-04 14:57:40794 self.mock_input_api.files = [
795 MockAffectedFile('A.py', []),
796 ]
797
John Budorickab2fa102017-10-06 16:59:49798 def mock_check_output(cmd, shell=False, env=None):
agrievef32bcc72016-04-04 14:57:40799 self.assertEqual('CMD A --output ""', cmd)
800 return 'changed data'
801
802 self.mock_input_api.subprocess.check_output = mock_check_output
803
804 results = self._RunCheck()
805 self.assertEqual(1, len(results))
806 self.assertTrue('File is stale' in str(results[0]))
807
808 def testRelevantPyTwoChanges(self):
pastarmovj89f7ee12016-09-20 14:58:13809 # PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
810 if self.mock_input_api.platform != 'linux2':
811 return []
812
agrievef32bcc72016-04-04 14:57:40813 self.mock_input_api.files = [
814 MockAffectedFile('C.py', []),
815 ]
816
John Budorickab2fa102017-10-06 16:59:49817 def mock_check_output(cmd, shell=False, env=None):
agrievef32bcc72016-04-04 14:57:40818 return 'changed data'
819
820 self.mock_input_api.subprocess.check_output = mock_check_output
821
822 results = self._RunCheck()
823 self.assertEqual(2, len(results))
824 self.assertTrue('File is stale' in str(results[0]))
825 self.assertTrue('File is stale' in str(results[1]))
826
Daniel Bratell8ba52722018-03-02 16:06:14827class IncludeGuardTest(unittest.TestCase):
828 def testIncludeGuardChecks(self):
829 mock_input_api = MockInputApi()
830 mock_output_api = MockOutputApi()
831 mock_input_api.files = [
832 MockAffectedFile('content/browser/thing/foo.h', [
833 '// Comment',
834 '#ifndef CONTENT_BROWSER_THING_FOO_H_',
835 '#define CONTENT_BROWSER_THING_FOO_H_',
836 'struct McBoatFace;',
837 '#endif // CONTENT_BROWSER_THING_FOO_H_',
838 ]),
839 MockAffectedFile('content/browser/thing/bar.h', [
840 '#ifndef CONTENT_BROWSER_THING_BAR_H_',
841 '#define CONTENT_BROWSER_THING_BAR_H_',
842 'namespace content {',
843 '#endif // CONTENT_BROWSER_THING_BAR_H_',
844 '} // namespace content',
845 ]),
846 MockAffectedFile('content/browser/test1.h', [
847 'namespace content {',
848 '} // namespace content',
849 ]),
850 MockAffectedFile('content\\browser\\win.h', [
851 '#ifndef CONTENT_BROWSER_WIN_H_',
852 '#define CONTENT_BROWSER_WIN_H_',
853 'struct McBoatFace;',
854 '#endif // CONTENT_BROWSER_WIN_H_',
855 ]),
856 MockAffectedFile('content/browser/test2.h', [
857 '// Comment',
858 '#ifndef CONTENT_BROWSER_TEST2_H_',
859 'struct McBoatFace;',
860 '#endif // CONTENT_BROWSER_TEST2_H_',
861 ]),
862 MockAffectedFile('content/browser/internal.h', [
863 '// Comment',
864 '#ifndef CONTENT_BROWSER_INTERNAL_H_',
865 '#define CONTENT_BROWSER_INTERNAL_H_',
866 '// Comment',
867 '#ifndef INTERNAL_CONTENT_BROWSER_INTERNAL_H_',
868 '#define INTERNAL_CONTENT_BROWSER_INTERNAL_H_',
869 'namespace internal {',
870 '} // namespace internal',
871 '#endif // INTERNAL_CONTENT_BROWSER_THING_BAR_H_',
872 'namespace content {',
873 '} // namespace content',
874 '#endif // CONTENT_BROWSER_THING_BAR_H_',
875 ]),
876 MockAffectedFile('content/browser/thing/foo.cc', [
877 '// This is a non-header.',
878 ]),
879 MockAffectedFile('content/browser/disabled.h', [
880 '// no-include-guard-because-multiply-included',
881 'struct McBoatFace;',
882 ]),
883 # New files don't allow misspelled include guards.
884 MockAffectedFile('content/browser/spleling.h', [
885 '#ifndef CONTENT_BROWSER_SPLLEING_H_',
886 '#define CONTENT_BROWSER_SPLLEING_H_',
887 'struct McBoatFace;',
888 '#endif // CONTENT_BROWSER_SPLLEING_H_',
889 ]),
890 # Old files allow misspelled include guards (for now).
891 MockAffectedFile('chrome/old.h', [
892 '// New contents',
893 '#ifndef CHROME_ODL_H_',
894 '#define CHROME_ODL_H_',
895 '#endif // CHROME_ODL_H_',
896 ], [
897 '// Old contents',
898 '#ifndef CHROME_ODL_H_',
899 '#define CHROME_ODL_H_',
900 '#endif // CHROME_ODL_H_',
901 ]),
902 # Using a Blink style include guard outside Blink is wrong.
903 MockAffectedFile('content/NotInBlink.h', [
904 '#ifndef NotInBlink_h',
905 '#define NotInBlink_h',
906 'struct McBoatFace;',
907 '#endif // NotInBlink_h',
908 ]),
909 # Using a Blink style include guard in Blink is ok for now.
910 MockAffectedFile('third_party/WebKit/InBlink.h', [
911 '#ifndef InBlink_h',
912 '#define InBlink_h',
913 'struct McBoatFace;',
914 '#endif // InBlink_h',
915 ]),
916 # Using a bad include guard in Blink is not ok.
917 MockAffectedFile('third_party/WebKit/AlsoInBlink.h', [
918 '#ifndef WrongInBlink_h',
919 '#define WrongInBlink_h',
920 'struct McBoatFace;',
921 '#endif // WrongInBlink_h',
922 ]),
923 # Using a bad include guard in Blink is accepted if it's an old file.
924 MockAffectedFile('third_party/WebKit/StillInBlink.h', [
925 '// New contents',
926 '#ifndef AcceptedInBlink_h',
927 '#define AcceptedInBlink_h',
928 'struct McBoatFace;',
929 '#endif // AcceptedInBlink_h',
930 ], [
931 '// Old contents',
932 '#ifndef AcceptedInBlink_h',
933 '#define AcceptedInBlink_h',
934 'struct McBoatFace;',
935 '#endif // AcceptedInBlink_h',
936 ]),
937 ]
938 msgs = PRESUBMIT._CheckForIncludeGuards(
939 mock_input_api, mock_output_api)
940 expected_fail_count = 6
941 self.assertEqual(expected_fail_count, len(msgs),
942 'Expected %d items, found %d: %s'
943 % (expected_fail_count, len(msgs), msgs))
944 self.assertEqual(msgs[0].items, [ 'content/browser/thing/bar.h' ])
945 self.assertEqual(msgs[0].message,
946 'Include guard CONTENT_BROWSER_THING_BAR_H_ '
947 'not covering the whole file')
948
949 self.assertEqual(msgs[1].items, [ 'content/browser/test1.h' ])
950 self.assertEqual(msgs[1].message,
951 'Missing include guard CONTENT_BROWSER_TEST1_H_')
952
953 self.assertEqual(msgs[2].items, [ 'content/browser/test2.h:3' ])
954 self.assertEqual(msgs[2].message,
955 'Missing "#define CONTENT_BROWSER_TEST2_H_" for '
956 'include guard')
957
958 self.assertEqual(msgs[3].items, [ 'content/browser/spleling.h:1' ])
959 self.assertEqual(msgs[3].message,
960 'Header using the wrong include guard name '
961 'CONTENT_BROWSER_SPLLEING_H_')
962
963 self.assertEqual(msgs[4].items, [ 'content/NotInBlink.h:1' ])
964 self.assertEqual(msgs[4].message,
965 'Header using the wrong include guard name '
966 'NotInBlink_h')
967
968 self.assertEqual(msgs[5].items, [ 'third_party/WebKit/AlsoInBlink.h:1' ])
969 self.assertEqual(msgs[5].message,
970 'Header using the wrong include guard name '
971 'WrongInBlink_h')
972
yolandyan45001472016-12-21 21:12:42973class AndroidDeprecatedTestAnnotationTest(unittest.TestCase):
974 def testCheckAndroidTestAnnotationUsage(self):
975 mock_input_api = MockInputApi()
976 mock_output_api = MockOutputApi()
977
978 mock_input_api.files = [
979 MockAffectedFile('LalaLand.java', [
980 'random stuff'
981 ]),
982 MockAffectedFile('CorrectUsage.java', [
983 'import android.support.test.filters.LargeTest;',
984 'import android.support.test.filters.MediumTest;',
985 'import android.support.test.filters.SmallTest;',
986 ]),
987 MockAffectedFile('UsedDeprecatedLargeTestAnnotation.java', [
988 'import android.test.suitebuilder.annotation.LargeTest;',
989 ]),
990 MockAffectedFile('UsedDeprecatedMediumTestAnnotation.java', [
991 'import android.test.suitebuilder.annotation.MediumTest;',
992 ]),
993 MockAffectedFile('UsedDeprecatedSmallTestAnnotation.java', [
994 'import android.test.suitebuilder.annotation.SmallTest;',
995 ]),
996 MockAffectedFile('UsedDeprecatedSmokeAnnotation.java', [
997 'import android.test.suitebuilder.annotation.Smoke;',
998 ])
999 ]
1000 msgs = PRESUBMIT._CheckAndroidTestAnnotationUsage(
1001 mock_input_api, mock_output_api)
1002 self.assertEqual(1, len(msgs),
1003 'Expected %d items, found %d: %s'
1004 % (1, len(msgs), msgs))
1005 self.assertEqual(4, len(msgs[0].items),
1006 'Expected %d items, found %d: %s'
1007 % (4, len(msgs[0].items), msgs[0].items))
1008 self.assertTrue('UsedDeprecatedLargeTestAnnotation.java:1' in msgs[0].items,
1009 'UsedDeprecatedLargeTestAnnotation not found in errors')
1010 self.assertTrue('UsedDeprecatedMediumTestAnnotation.java:1'
1011 in msgs[0].items,
1012 'UsedDeprecatedMediumTestAnnotation not found in errors')
1013 self.assertTrue('UsedDeprecatedSmallTestAnnotation.java:1' in msgs[0].items,
1014 'UsedDeprecatedSmallTestAnnotation not found in errors')
1015 self.assertTrue('UsedDeprecatedSmokeAnnotation.java:1' in msgs[0].items,
1016 'UsedDeprecatedSmokeAnnotation not found in errors')
1017
Yoland Yanb92fa522017-08-28 17:37:061018class AndroidDeprecatedJUnitFrameworkTest(unittest.TestCase):
1019 def testCheckAndroidTestAnnotationUsage(self):
1020 mock_input_api = MockInputApi()
1021 mock_output_api = MockOutputApi()
yolandyan45001472016-12-21 21:12:421022
Yoland Yanb92fa522017-08-28 17:37:061023 mock_input_api.files = [
1024 MockAffectedFile('LalaLand.java', [
1025 'random stuff'
1026 ]),
1027 MockAffectedFile('CorrectUsage.java', [
1028 'import org.junit.ABC',
1029 'import org.junit.XYZ;',
1030 ]),
1031 MockAffectedFile('UsedDeprecatedJUnit.java', [
1032 'import junit.framework.*;',
1033 ]),
1034 MockAffectedFile('UsedDeprecatedJUnitAssert.java', [
1035 'import junit.framework.Assert;',
1036 ]),
1037 ]
1038 msgs = PRESUBMIT._CheckAndroidTestJUnitFrameworkImport(
1039 mock_input_api, mock_output_api)
1040 self.assertEqual(1, len(msgs),
1041 'Expected %d items, found %d: %s'
1042 % (1, len(msgs), msgs))
1043 self.assertEqual(2, len(msgs[0].items),
1044 'Expected %d items, found %d: %s'
1045 % (2, len(msgs[0].items), msgs[0].items))
1046 self.assertTrue('UsedDeprecatedJUnit.java:1' in msgs[0].items,
1047 'UsedDeprecatedJUnit.java not found in errors')
1048 self.assertTrue('UsedDeprecatedJUnitAssert.java:1'
1049 in msgs[0].items,
1050 'UsedDeprecatedJUnitAssert not found in errors')
1051
1052class AndroidJUnitBaseClass(unittest.TestCase):
1053 def testCheckAndroidTestAnnotationUsage(self):
1054 mock_input_api = MockInputApi()
1055 mock_output_api = MockOutputApi()
1056
1057 mock_input_api.files = [
1058 MockAffectedFile('LalaLand.java', [
1059 'random stuff'
1060 ]),
1061 MockAffectedFile('CorrectTest.java', [
1062 '@RunWith(ABC.class);'
1063 'public class CorrectTest {',
1064 '}',
1065 ]),
1066 MockAffectedFile('HistoricallyIncorrectTest.java', [
1067 'public class Test extends BaseCaseA {',
1068 '}',
1069 ], old_contents=[
1070 'public class Test extends BaseCaseB {',
1071 '}',
1072 ]),
1073 MockAffectedFile('CorrectTestWithInterface.java', [
1074 '@RunWith(ABC.class);'
1075 'public class CorrectTest implement Interface {',
1076 '}',
1077 ]),
1078 MockAffectedFile('IncorrectTest.java', [
1079 'public class IncorrectTest extends TestCase {',
1080 '}',
1081 ]),
Vaclav Brozekf01ed502018-03-16 19:38:241082 MockAffectedFile('IncorrectWithInterfaceTest.java', [
Yoland Yanb92fa522017-08-28 17:37:061083 'public class Test implements X extends BaseClass {',
1084 '}',
1085 ]),
Vaclav Brozekf01ed502018-03-16 19:38:241086 MockAffectedFile('IncorrectMultiLineTest.java', [
Yoland Yanb92fa522017-08-28 17:37:061087 'public class Test implements X, Y, Z',
1088 ' extends TestBase {',
1089 '}',
1090 ]),
1091 ]
1092 msgs = PRESUBMIT._CheckAndroidTestJUnitInheritance(
1093 mock_input_api, mock_output_api)
1094 self.assertEqual(1, len(msgs),
1095 'Expected %d items, found %d: %s'
1096 % (1, len(msgs), msgs))
1097 self.assertEqual(3, len(msgs[0].items),
1098 'Expected %d items, found %d: %s'
1099 % (3, len(msgs[0].items), msgs[0].items))
1100 self.assertTrue('IncorrectTest.java:1' in msgs[0].items,
1101 'IncorrectTest not found in errors')
Vaclav Brozekf01ed502018-03-16 19:38:241102 self.assertTrue('IncorrectWithInterfaceTest.java:1'
Yoland Yanb92fa522017-08-28 17:37:061103 in msgs[0].items,
Vaclav Brozekf01ed502018-03-16 19:38:241104 'IncorrectWithInterfaceTest not found in errors')
1105 self.assertTrue('IncorrectMultiLineTest.java:2' in msgs[0].items,
1106 'IncorrectMultiLineTest not found in errors')
yolandyan45001472016-12-21 21:12:421107
dgn4401aa52015-04-29 16:26:171108class LogUsageTest(unittest.TestCase):
1109
dgnaa68d5e2015-06-10 10:08:221110 def testCheckAndroidCrLogUsage(self):
1111 mock_input_api = MockInputApi()
1112 mock_output_api = MockOutputApi()
1113
1114 mock_input_api.files = [
1115 MockAffectedFile('RandomStuff.java', [
1116 'random stuff'
1117 ]),
dgn87d9fb62015-06-12 09:15:121118 MockAffectedFile('HasAndroidLog.java', [
1119 'import android.util.Log;',
1120 'some random stuff',
1121 'Log.d("TAG", "foo");',
1122 ]),
1123 MockAffectedFile('HasExplicitUtilLog.java', [
1124 'some random stuff',
1125 'android.util.Log.d("TAG", "foo");',
1126 ]),
1127 MockAffectedFile('IsInBasePackage.java', [
1128 'package org.chromium.base;',
dgn38736db2015-09-18 19:20:511129 'private static final String TAG = "cr_Foo";',
dgn87d9fb62015-06-12 09:15:121130 'Log.d(TAG, "foo");',
1131 ]),
1132 MockAffectedFile('IsInBasePackageButImportsLog.java', [
1133 'package org.chromium.base;',
1134 'import android.util.Log;',
dgn38736db2015-09-18 19:20:511135 'private static final String TAG = "cr_Foo";',
dgn87d9fb62015-06-12 09:15:121136 'Log.d(TAG, "foo");',
1137 ]),
1138 MockAffectedFile('HasBothLog.java', [
1139 'import org.chromium.base.Log;',
1140 'some random stuff',
dgn38736db2015-09-18 19:20:511141 'private static final String TAG = "cr_Foo";',
dgn87d9fb62015-06-12 09:15:121142 'Log.d(TAG, "foo");',
1143 'android.util.Log.d("TAG", "foo");',
1144 ]),
dgnaa68d5e2015-06-10 10:08:221145 MockAffectedFile('HasCorrectTag.java', [
1146 'import org.chromium.base.Log;',
1147 'some random stuff',
dgn38736db2015-09-18 19:20:511148 'private static final String TAG = "cr_Foo";',
1149 'Log.d(TAG, "foo");',
1150 ]),
1151 MockAffectedFile('HasOldTag.java', [
1152 'import org.chromium.base.Log;',
1153 'some random stuff',
dgnaa68d5e2015-06-10 10:08:221154 'private static final String TAG = "cr.Foo";',
1155 'Log.d(TAG, "foo");',
1156 ]),
dgn38736db2015-09-18 19:20:511157 MockAffectedFile('HasDottedTag.java', [
dgnaa68d5e2015-06-10 10:08:221158 'import org.chromium.base.Log;',
1159 'some random stuff',
dgn38736db2015-09-18 19:20:511160 'private static final String TAG = "cr_foo.bar";',
dgnaa68d5e2015-06-10 10:08:221161 'Log.d(TAG, "foo");',
1162 ]),
1163 MockAffectedFile('HasNoTagDecl.java', [
1164 'import org.chromium.base.Log;',
1165 'some random stuff',
1166 'Log.d(TAG, "foo");',
1167 ]),
1168 MockAffectedFile('HasIncorrectTagDecl.java', [
1169 'import org.chromium.base.Log;',
dgn38736db2015-09-18 19:20:511170 'private static final String TAHG = "cr_Foo";',
dgnaa68d5e2015-06-10 10:08:221171 'some random stuff',
1172 'Log.d(TAG, "foo");',
1173 ]),
1174 MockAffectedFile('HasInlineTag.java', [
1175 'import org.chromium.base.Log;',
1176 'some random stuff',
dgn38736db2015-09-18 19:20:511177 'private static final String TAG = "cr_Foo";',
dgnaa68d5e2015-06-10 10:08:221178 'Log.d("TAG", "foo");',
1179 ]),
dgn38736db2015-09-18 19:20:511180 MockAffectedFile('HasUnprefixedTag.java', [
dgnaa68d5e2015-06-10 10:08:221181 'import org.chromium.base.Log;',
1182 'some random stuff',
1183 'private static final String TAG = "rubbish";',
1184 'Log.d(TAG, "foo");',
1185 ]),
1186 MockAffectedFile('HasTooLongTag.java', [
1187 'import org.chromium.base.Log;',
1188 'some random stuff',
dgn38736db2015-09-18 19:20:511189 'private static final String TAG = "21_charachers_long___";',
dgnaa68d5e2015-06-10 10:08:221190 'Log.d(TAG, "foo");',
1191 ]),
1192 ]
1193
1194 msgs = PRESUBMIT._CheckAndroidCrLogUsage(
1195 mock_input_api, mock_output_api)
1196
dgn38736db2015-09-18 19:20:511197 self.assertEqual(5, len(msgs),
1198 'Expected %d items, found %d: %s' % (5, len(msgs), msgs))
dgnaa68d5e2015-06-10 10:08:221199
1200 # Declaration format
dgn38736db2015-09-18 19:20:511201 nb = len(msgs[0].items)
1202 self.assertEqual(2, nb,
1203 'Expected %d items, found %d: %s' % (2, nb, msgs[0].items))
dgnaa68d5e2015-06-10 10:08:221204 self.assertTrue('HasNoTagDecl.java' in msgs[0].items)
1205 self.assertTrue('HasIncorrectTagDecl.java' in msgs[0].items)
dgnaa68d5e2015-06-10 10:08:221206
1207 # Tag length
dgn38736db2015-09-18 19:20:511208 nb = len(msgs[1].items)
1209 self.assertEqual(1, nb,
1210 'Expected %d items, found %d: %s' % (1, nb, msgs[1].items))
dgnaa68d5e2015-06-10 10:08:221211 self.assertTrue('HasTooLongTag.java' in msgs[1].items)
1212
1213 # Tag must be a variable named TAG
dgn38736db2015-09-18 19:20:511214 nb = len(msgs[2].items)
1215 self.assertEqual(1, nb,
1216 'Expected %d items, found %d: %s' % (1, nb, msgs[2].items))
dgnaa68d5e2015-06-10 10:08:221217 self.assertTrue('HasInlineTag.java:4' in msgs[2].items)
1218
dgn87d9fb62015-06-12 09:15:121219 # Util Log usage
dgn38736db2015-09-18 19:20:511220 nb = len(msgs[3].items)
1221 self.assertEqual(2, nb,
1222 'Expected %d items, found %d: %s' % (2, nb, msgs[3].items))
dgn87d9fb62015-06-12 09:15:121223 self.assertTrue('HasAndroidLog.java:3' in msgs[3].items)
1224 self.assertTrue('IsInBasePackageButImportsLog.java:4' in msgs[3].items)
dgnaa68d5e2015-06-10 10:08:221225
dgn38736db2015-09-18 19:20:511226 # Tag must not contain
1227 nb = len(msgs[4].items)
1228 self.assertEqual(2, nb,
1229 'Expected %d items, found %d: %s' % (2, nb, msgs[4].items))
1230 self.assertTrue('HasDottedTag.java' in msgs[4].items)
1231 self.assertTrue('HasOldTag.java' in msgs[4].items)
1232
estadee17314a02017-01-12 16:22:161233class GoogleAnswerUrlFormatTest(unittest.TestCase):
1234
1235 def testCatchAnswerUrlId(self):
1236 input_api = MockInputApi()
1237 input_api.files = [
1238 MockFile('somewhere/file.cc',
1239 ['char* host = '
1240 ' "https://support.google.com/chrome/answer/123456";']),
1241 MockFile('somewhere_else/file.cc',
1242 ['char* host = '
1243 ' "https://support.google.com/chrome/a/answer/123456";']),
1244 ]
1245
1246 warnings = PRESUBMIT._CheckGoogleSupportAnswerUrl(
1247 input_api, MockOutputApi())
1248 self.assertEqual(1, len(warnings))
1249 self.assertEqual(2, len(warnings[0].items))
1250
1251 def testAllowAnswerUrlParam(self):
1252 input_api = MockInputApi()
1253 input_api.files = [
1254 MockFile('somewhere/file.cc',
1255 ['char* host = '
1256 ' "https://support.google.com/chrome/?p=cpn_crash_reports";']),
1257 ]
1258
1259 warnings = PRESUBMIT._CheckGoogleSupportAnswerUrl(
1260 input_api, MockOutputApi())
1261 self.assertEqual(0, len(warnings))
1262
reillyi38965732015-11-16 18:27:331263class HardcodedGoogleHostsTest(unittest.TestCase):
1264
1265 def testWarnOnAssignedLiterals(self):
1266 input_api = MockInputApi()
1267 input_api.files = [
1268 MockFile('content/file.cc',
1269 ['char* host = "https://www.google.com";']),
1270 MockFile('content/file.cc',
1271 ['char* host = "https://www.googleapis.com";']),
1272 MockFile('content/file.cc',
1273 ['char* host = "https://clients1.google.com";']),
1274 ]
1275
1276 warnings = PRESUBMIT._CheckHardcodedGoogleHostsInLowerLayers(
1277 input_api, MockOutputApi())
1278 self.assertEqual(1, len(warnings))
1279 self.assertEqual(3, len(warnings[0].items))
1280
1281 def testAllowInComment(self):
1282 input_api = MockInputApi()
1283 input_api.files = [
1284 MockFile('content/file.cc',
1285 ['char* host = "https://www.aol.com"; // google.com'])
1286 ]
1287
1288 warnings = PRESUBMIT._CheckHardcodedGoogleHostsInLowerLayers(
1289 input_api, MockOutputApi())
1290 self.assertEqual(0, len(warnings))
1291
dgn4401aa52015-04-29 16:26:171292
jbriance9e12f162016-11-25 07:57:501293class ForwardDeclarationTest(unittest.TestCase):
jbriance2c51e821a2016-12-12 08:24:311294 def testCheckHeadersOnlyOutsideThirdParty(self):
jbriance9e12f162016-11-25 07:57:501295 mock_input_api = MockInputApi()
1296 mock_input_api.files = [
1297 MockAffectedFile('somewhere/file.cc', [
1298 'class DummyClass;'
jbriance2c51e821a2016-12-12 08:24:311299 ]),
1300 MockAffectedFile('third_party/header.h', [
1301 'class DummyClass;'
jbriance9e12f162016-11-25 07:57:501302 ])
1303 ]
1304 warnings = PRESUBMIT._CheckUselessForwardDeclarations(mock_input_api,
1305 MockOutputApi())
1306 self.assertEqual(0, len(warnings))
1307
1308 def testNoNestedDeclaration(self):
1309 mock_input_api = MockInputApi()
1310 mock_input_api.files = [
1311 MockAffectedFile('somewhere/header.h', [
jbriance2c51e821a2016-12-12 08:24:311312 'class SomeClass {',
1313 ' protected:',
1314 ' class NotAMatch;',
jbriance9e12f162016-11-25 07:57:501315 '};'
1316 ])
1317 ]
1318 warnings = PRESUBMIT._CheckUselessForwardDeclarations(mock_input_api,
1319 MockOutputApi())
1320 self.assertEqual(0, len(warnings))
1321
1322 def testSubStrings(self):
1323 mock_input_api = MockInputApi()
1324 mock_input_api.files = [
1325 MockAffectedFile('somewhere/header.h', [
1326 'class NotUsefulClass;',
1327 'struct SomeStruct;',
1328 'UsefulClass *p1;',
1329 'SomeStructPtr *p2;'
1330 ])
1331 ]
1332 warnings = PRESUBMIT._CheckUselessForwardDeclarations(mock_input_api,
1333 MockOutputApi())
1334 self.assertEqual(2, len(warnings))
1335
1336 def testUselessForwardDeclaration(self):
1337 mock_input_api = MockInputApi()
1338 mock_input_api.files = [
1339 MockAffectedFile('somewhere/header.h', [
1340 'class DummyClass;',
1341 'struct DummyStruct;',
1342 'class UsefulClass;',
1343 'std::unique_ptr<UsefulClass> p;'
jbriance2c51e821a2016-12-12 08:24:311344 ])
jbriance9e12f162016-11-25 07:57:501345 ]
1346 warnings = PRESUBMIT._CheckUselessForwardDeclarations(mock_input_api,
1347 MockOutputApi())
1348 self.assertEqual(2, len(warnings))
1349
jbriance2c51e821a2016-12-12 08:24:311350 def testBlinkHeaders(self):
1351 mock_input_api = MockInputApi()
1352 mock_input_api.files = [
1353 MockAffectedFile('third_party/WebKit/header.h', [
1354 'class DummyClass;',
1355 'struct DummyStruct;',
1356 ]),
1357 MockAffectedFile('third_party\\WebKit\\header.h', [
1358 'class DummyClass;',
1359 'struct DummyStruct;',
1360 ])
1361 ]
1362 warnings = PRESUBMIT._CheckUselessForwardDeclarations(mock_input_api,
1363 MockOutputApi())
1364 self.assertEqual(4, len(warnings))
1365
jbriance9e12f162016-11-25 07:57:501366
dbeam1ec68ac2016-12-15 05:22:241367class RiskyJsTest(unittest.TestCase):
1368 def testArrowWarnInIos9Code(self):
1369 mock_input_api = MockInputApi()
1370 mock_output_api = MockOutputApi()
1371
1372 mock_input_api.files = [
1373 MockAffectedFile('components/blah.js', ["shouldn't use => here"]),
1374 ]
1375 warnings = PRESUBMIT._CheckForRiskyJsFeatures(
1376 mock_input_api, mock_output_api)
1377 self.assertEqual(1, len(warnings))
1378
1379 mock_input_api.files = [
1380 MockAffectedFile('ios/blee.js', ['might => break folks']),
1381 ]
1382 warnings = PRESUBMIT._CheckForRiskyJsFeatures(
1383 mock_input_api, mock_output_api)
1384 self.assertEqual(1, len(warnings))
1385
1386 mock_input_api.files = [
1387 MockAffectedFile('ui/webui/resources/blarg.js', ['on => iOS9']),
1388 ]
1389 warnings = PRESUBMIT._CheckForRiskyJsFeatures(
1390 mock_input_api, mock_output_api)
1391 self.assertEqual(1, len(warnings))
1392
1393 def testArrowsAllowedInChromeCode(self):
1394 mock_input_api = MockInputApi()
1395 mock_input_api.files = [
1396 MockAffectedFile('chrome/browser/resources/blah.js', 'arrow => OK here'),
1397 ]
1398 warnings = PRESUBMIT._CheckForRiskyJsFeatures(
1399 mock_input_api, MockOutputApi())
1400 self.assertEqual(0, len(warnings))
1401
dpapadd651231d82017-07-21 02:44:471402 def testConstLetWarningIos9Code(self):
1403 mock_input_api = MockInputApi()
1404 mock_output_api = MockOutputApi()
1405
1406 mock_input_api.files = [
1407 MockAffectedFile('components/blah.js', [" const foo = 'bar';"]),
1408 MockAffectedFile('ui/webui/resources/blah.js', [" let foo = 3;"]),
1409 ]
1410 warnings = PRESUBMIT._CheckForRiskyJsFeatures(
1411 mock_input_api, mock_output_api)
1412 self.assertEqual(2, len(warnings))
1413
rlanday6802cf632017-05-30 17:48:361414class RelativeIncludesTest(unittest.TestCase):
1415 def testThirdPartyNotWebKitIgnored(self):
1416 mock_input_api = MockInputApi()
1417 mock_input_api.files = [
1418 MockAffectedFile('third_party/test.cpp', '#include "../header.h"'),
1419 MockAffectedFile('third_party/test/test.cpp', '#include "../header.h"'),
1420 ]
1421
1422 mock_output_api = MockOutputApi()
1423
1424 errors = PRESUBMIT._CheckForRelativeIncludes(
1425 mock_input_api, mock_output_api)
1426 self.assertEqual(0, len(errors))
1427
1428 def testNonCppFileIgnored(self):
1429 mock_input_api = MockInputApi()
1430 mock_input_api.files = [
1431 MockAffectedFile('test.py', '#include "../header.h"'),
1432 ]
1433
1434 mock_output_api = MockOutputApi()
1435
1436 errors = PRESUBMIT._CheckForRelativeIncludes(
1437 mock_input_api, mock_output_api)
1438 self.assertEqual(0, len(errors))
1439
1440 def testInnocuousChangesAllowed(self):
1441 mock_input_api = MockInputApi()
1442 mock_input_api.files = [
1443 MockAffectedFile('test.cpp', '#include "header.h"'),
1444 MockAffectedFile('test2.cpp', '../'),
1445 ]
1446
1447 mock_output_api = MockOutputApi()
1448
1449 errors = PRESUBMIT._CheckForRelativeIncludes(
1450 mock_input_api, mock_output_api)
1451 self.assertEqual(0, len(errors))
1452
1453 def testRelativeIncludeNonWebKitProducesError(self):
1454 mock_input_api = MockInputApi()
1455 mock_input_api.files = [
1456 MockAffectedFile('test.cpp', ['#include "../header.h"']),
1457 ]
1458
1459 mock_output_api = MockOutputApi()
1460
1461 errors = PRESUBMIT._CheckForRelativeIncludes(
1462 mock_input_api, mock_output_api)
1463 self.assertEqual(1, len(errors))
1464
1465 def testRelativeIncludeWebKitProducesError(self):
1466 mock_input_api = MockInputApi()
1467 mock_input_api.files = [
1468 MockAffectedFile('third_party/WebKit/test.cpp',
1469 ['#include "../header.h']),
1470 ]
1471
1472 mock_output_api = MockOutputApi()
1473
1474 errors = PRESUBMIT._CheckForRelativeIncludes(
1475 mock_input_api, mock_output_api)
1476 self.assertEqual(1, len(errors))
dbeam1ec68ac2016-12-15 05:22:241477
Daniel Cheng13ca61a882017-08-25 15:11:251478
1479class MojoManifestOwnerTest(unittest.TestCase):
1480 def testMojoManifestChangeNeedsSecurityOwner(self):
1481 mock_input_api = MockInputApi()
1482 mock_input_api.files = [
1483 MockAffectedFile('services/goat/manifest.json',
1484 [
1485 '{',
1486 ' "name": "teleporter",',
1487 ' "display_name": "Goat Teleporter",'
1488 ' "interface_provider_specs": {',
1489 ' }',
1490 '}',
1491 ])
1492 ]
1493 mock_output_api = MockOutputApi()
1494 errors = PRESUBMIT._CheckIpcOwners(
1495 mock_input_api, mock_output_api)
1496 self.assertEqual(1, len(errors))
1497 self.assertEqual(
1498 'Found OWNERS files that need to be updated for IPC security review ' +
1499 'coverage.\nPlease update the OWNERS files below:', errors[0].message)
1500
1501 # No warning if already covered by an OWNERS rule.
1502
1503 def testNonManifestChangesDoNotRequireSecurityOwner(self):
1504 mock_input_api = MockInputApi()
1505 mock_input_api.files = [
1506 MockAffectedFile('services/goat/species.json',
1507 [
1508 '[',
1509 ' "anglo-nubian",',
1510 ' "angora"',
1511 ']',
1512 ])
1513 ]
1514 mock_output_api = MockOutputApi()
1515 errors = PRESUBMIT._CheckIpcOwners(
1516 mock_input_api, mock_output_api)
1517 self.assertEqual([], errors)
1518
1519
Miguel Casas-Sancheze0d46d42017-12-14 15:52:191520class CrbugUrlFormatTest(unittest.TestCase):
1521
1522 def testCheckCrbugLinksHaveHttps(self):
1523 input_api = MockInputApi()
1524 input_api.files = [
1525 MockFile('somewhere/file.cc',
1526 ['// TODO(developer): crbug.com should be linkified',
1527 '// TODO(developer): (crbug.com) should be linkified',
1528 '// TODO(developer): crbug/123 should be well formed',
1529 '// TODO(developer): http://crbug.com it\'s OK',
Miguel Casas68bdb652017-12-19 16:29:091530 '// TODO(developer): https://crbug.com is just great',
1531 '// TODO(crbug.com/123456): this pattern it\'s also OK']),
Miguel Casas-Sancheze0d46d42017-12-14 15:52:191532 ]
1533
1534 warnings = PRESUBMIT._CheckCrbugLinksHaveHttps(input_api, MockOutputApi())
1535 self.assertEqual(1, len(warnings))
Miguel Casas68bdb652017-12-19 16:29:091536 self.assertEqual(3, warnings[0].message.count('\n'));
Miguel Casas-Sancheze0d46d42017-12-14 15:52:191537
1538
Sylvain Defresnea8b73d252018-02-28 15:45:541539class BannedFunctionCheckTest(unittest.TestCase):
1540
1541 def testBannedIosObcjFunctions(self):
1542 input_api = MockInputApi()
1543 input_api.files = [
1544 MockFile('some/ios/file.mm',
1545 ['TEST(SomeClassTest, SomeInteraction) {',
1546 '}']),
1547 MockFile('some/mac/file.mm',
1548 ['TEST(SomeClassTest, SomeInteraction) {',
1549 '}']),
1550 MockFile('another/ios_file.mm',
1551 ['class SomeTest : public testing::Test {};']),
1552 ]
1553
1554 errors = PRESUBMIT._CheckNoBannedFunctions(input_api, MockOutputApi())
1555 self.assertEqual(1, len(errors))
1556 self.assertTrue('some/ios/file.mm' in errors[0].message)
1557 self.assertTrue('another/ios_file.mm' in errors[0].message)
1558 self.assertTrue('some/mac/file.mm' not in errors[0].message)
1559
1560
Vaclav Brozekf01ed502018-03-16 19:38:241561class NoProductionCodeUsingTestOnlyFunctions(unittest.TestCase):
1562 def testTruePositives(self):
1563 mock_input_api = MockInputApi()
1564 mock_input_api.files = [
1565 MockFile('some/path/foo.cc', ['foo_for_testing();']),
1566 MockFile('some/path/foo.mm', ['FooForTesting();']),
1567 MockFile('some/path/foo.cxx', ['FooForTests();']),
1568 MockFile('some/path/foo.cpp', ['foo_for_test();']),
1569 ]
1570
1571 results = PRESUBMIT._CheckNoProductionCodeUsingTestOnlyFunctions(
1572 mock_input_api, MockOutputApi())
1573 self.assertEqual(1, len(results))
1574 self.assertEqual(4, len(results[0].items))
1575 self.assertTrue('foo.cc' in results[0].items[0])
1576 self.assertTrue('foo.mm' in results[0].items[1])
1577 self.assertTrue('foo.cxx' in results[0].items[2])
1578 self.assertTrue('foo.cpp' in results[0].items[3])
1579
1580 def testFalsePositives(self):
1581 mock_input_api = MockInputApi()
1582 mock_input_api.files = [
1583 MockFile('some/path/foo.h', ['foo_for_testing();']),
1584 MockFile('some/path/foo.mm', ['FooForTesting() {']),
1585 MockFile('some/path/foo.cc', ['::FooForTests();']),
1586 MockFile('some/path/foo.cpp', ['// foo_for_test();']),
1587 ]
1588
1589 results = PRESUBMIT._CheckNoProductionCodeUsingTestOnlyFunctions(
1590 mock_input_api, MockOutputApi())
1591 self.assertEqual(0, len(results))
1592
1593
Vaclav Brozek7dbc28c2018-03-27 08:35:231594class NoProductionJavaCodeUsingTestOnlyFunctions(unittest.TestCase):
1595 def testTruePositives(self):
1596 mock_input_api = MockInputApi()
1597 mock_input_api.files = [
1598 MockFile('dir/java/src/foo.java', ['FooForTesting();']),
1599 MockFile('dir/java/src/bar.java', ['FooForTests(x);']),
1600 MockFile('dir/java/src/baz.java', ['FooForTest(','y',');']),
1601 MockFile('dir/java/src/mult.java', [
1602 'int x = SomethingLongHere()',
1603 ' * SomethingLongHereForTesting();'
1604 ]),
1605 ]
1606
1607 results = PRESUBMIT._CheckNoProductionCodeUsingTestOnlyFunctionsJava(
1608 mock_input_api, MockOutputApi())
1609 self.assertEqual(1, len(results))
1610 self.assertEqual(4, len(results[0].items))
1611 self.assertTrue('foo.java' in results[0].items[0])
1612 self.assertTrue('bar.java' in results[0].items[1])
1613 self.assertTrue('baz.java' in results[0].items[2])
1614 self.assertTrue('mult.java' in results[0].items[3])
1615
1616 def testFalsePositives(self):
1617 mock_input_api = MockInputApi()
1618 mock_input_api.files = [
1619 MockFile('dir/java/src/foo.xml', ['FooForTesting();']),
1620 MockFile('dir/java/src/foo.java', ['FooForTests() {']),
1621 MockFile('dir/java/src/bar.java', ['// FooForTest();']),
1622 MockFile('dir/java/src/bar2.java', ['x = 1; // FooForTest();']),
1623 MockFile('dir/javatests/src/baz.java', ['FooForTest(','y',');']),
1624 MockFile('dir/junit/src/baz.java', ['FooForTest(','y',');']),
1625 MockFile('dir/junit/src/javadoc.java', [
1626 '/** Use FooForTest(); to obtain foo in tests.'
1627 ' */'
1628 ]),
1629 MockFile('dir/junit/src/javadoc2.java', [
1630 '/** ',
1631 ' * Use FooForTest(); to obtain foo in tests.'
1632 ' */'
1633 ]),
1634 ]
1635
1636 results = PRESUBMIT._CheckNoProductionCodeUsingTestOnlyFunctionsJava(
1637 mock_input_api, MockOutputApi())
1638 self.assertEqual(0, len(results))
1639
1640
Vaclav Brozek52e18bf2018-04-03 07:05:241641class CheckUniquePtr(unittest.TestCase):
Vaclav Brozek851d9602018-04-04 16:13:051642 def testTruePositivesNullptr(self):
1643 mock_input_api = MockInputApi()
1644 mock_input_api.files = [
Vaclav Brozekc2fecf42018-04-06 16:40:161645 MockFile('dir/baz.cc', ['std::unique_ptr<T>()']),
1646 MockFile('dir/baz-p.cc', ['std::unique_ptr<T<P>>()']),
Vaclav Brozek851d9602018-04-04 16:13:051647 ]
1648
1649 results = PRESUBMIT._CheckUniquePtr(mock_input_api, MockOutputApi())
1650 self.assertEqual(1, len(results))
Vaclav Brozekc2fecf42018-04-06 16:40:161651 self.assertTrue('nullptr' in results[0].message)
Vaclav Brozek851d9602018-04-04 16:13:051652 self.assertEqual(2, len(results[0].items))
1653 self.assertTrue('baz.cc' in results[0].items[0])
1654 self.assertTrue('baz-p.cc' in results[0].items[1])
1655
1656 def testTruePositivesConstructor(self):
Vaclav Brozek52e18bf2018-04-03 07:05:241657 mock_input_api = MockInputApi()
1658 mock_input_api.files = [
Vaclav Brozekc2fecf42018-04-06 16:40:161659 MockFile('dir/foo.cc', ['return std::unique_ptr<T>(foo);']),
1660 MockFile('dir/bar.mm', ['bar = std::unique_ptr<T>(foo)']),
1661 MockFile('dir/mult.cc', [
Vaclav Brozek95face62018-04-04 14:15:111662 'return',
1663 ' std::unique_ptr<T>(barVeryVeryLongFooSoThatItWouldNotFitAbove);'
1664 ]),
Vaclav Brozekc2fecf42018-04-06 16:40:161665 MockFile('dir/mult2.cc', [
Vaclav Brozek95face62018-04-04 14:15:111666 'barVeryVeryLongLongBaaaaaarSoThatTheLineLimitIsAlmostReached =',
1667 ' std::unique_ptr<T>(foo);'
1668 ]),
Vaclav Brozekc2fecf42018-04-06 16:40:161669 MockFile('dir/mult3.cc', [
Vaclav Brozek95face62018-04-04 14:15:111670 'bar = std::unique_ptr<T>(',
1671 ' fooVeryVeryVeryLongStillGoingWellThisWillTakeAWhileFinallyThere);'
1672 ]),
Vaclav Brozek52e18bf2018-04-03 07:05:241673 ]
1674
1675 results = PRESUBMIT._CheckUniquePtr(mock_input_api, MockOutputApi())
Vaclav Brozek851d9602018-04-04 16:13:051676 self.assertEqual(1, len(results))
Vaclav Brozekc2fecf42018-04-06 16:40:161677 self.assertTrue('std::make_unique' in results[0].message)
Vaclav Brozek851d9602018-04-04 16:13:051678 self.assertEqual(5, len(results[0].items))
1679 self.assertTrue('foo.cc' in results[0].items[0])
1680 self.assertTrue('bar.mm' in results[0].items[1])
1681 self.assertTrue('mult.cc' in results[0].items[2])
1682 self.assertTrue('mult2.cc' in results[0].items[3])
1683 self.assertTrue('mult3.cc' in results[0].items[4])
Vaclav Brozek52e18bf2018-04-03 07:05:241684
1685 def testFalsePositives(self):
1686 mock_input_api = MockInputApi()
1687 mock_input_api.files = [
Vaclav Brozekc2fecf42018-04-06 16:40:161688 MockFile('dir/foo.cc', ['return std::unique_ptr<T[]>(foo);']),
1689 MockFile('dir/bar.mm', ['bar = std::unique_ptr<T[]>(foo)']),
1690 MockFile('dir/file.cc', ['std::unique_ptr<T> p = Foo();']),
1691 MockFile('dir/baz.cc', [
Vaclav Brozek52e18bf2018-04-03 07:05:241692 'std::unique_ptr<T> result = std::make_unique<T>();'
1693 ]),
Vaclav Brozeka54c528b2018-04-06 19:23:551694 MockFile('dir/baz2.cc', [
1695 'std::unique_ptr<T> result = std::make_unique<T>('
1696 ]),
1697 MockFile('dir/nested.cc', ['set<std::unique_ptr<T>>();']),
1698 MockFile('dir/nested2.cc', ['map<U, std::unique_ptr<T>>();']),
Vaclav Brozek52e18bf2018-04-03 07:05:241699 ]
1700
1701 results = PRESUBMIT._CheckUniquePtr(mock_input_api, MockOutputApi())
1702 self.assertEqual(0, len(results))
1703
1704
[email protected]2299dcf2012-11-15 19:56:241705if __name__ == '__main__':
1706 unittest.main()