blob: bd05f570f61ce9c85671410bfbe015dc0be1f7d4 [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 ]),
Daniel Bratell39b5b062018-05-16 18:09:57909 # Using a Blink style include guard in Blink is no longer ok.
910 MockAffectedFile('third_party/blink/InBlink.h', [
Daniel Bratell8ba52722018-03-02 16:06:14911 '#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.
Daniel Bratell39b5b062018-05-16 18:09:57917 MockAffectedFile('third_party/blink/AlsoInBlink.h', [
Daniel Bratell8ba52722018-03-02 16:06:14918 '#ifndef WrongInBlink_h',
919 '#define WrongInBlink_h',
920 'struct McBoatFace;',
921 '#endif // WrongInBlink_h',
922 ]),
Daniel Bratell39b5b062018-05-16 18:09:57923 # Using a bad include guard in Blink is not accepted even if
924 # it's an old file.
925 MockAffectedFile('third_party/blink/StillInBlink.h', [
Daniel Bratell8ba52722018-03-02 16:06:14926 '// New contents',
927 '#ifndef AcceptedInBlink_h',
928 '#define AcceptedInBlink_h',
929 'struct McBoatFace;',
930 '#endif // AcceptedInBlink_h',
931 ], [
932 '// Old contents',
933 '#ifndef AcceptedInBlink_h',
934 '#define AcceptedInBlink_h',
935 'struct McBoatFace;',
936 '#endif // AcceptedInBlink_h',
937 ]),
Daniel Bratell39b5b062018-05-16 18:09:57938 # Using a non-Chromium include guard in third_party
939 # (outside blink) is accepted.
940 MockAffectedFile('third_party/foo/some_file.h', [
941 '#ifndef REQUIRED_RPCNDR_H_',
942 '#define REQUIRED_RPCNDR_H_',
943 'struct SomeFileFoo;',
944 '#endif // REQUIRED_RPCNDR_H_',
945 ]),
Daniel Bratell8ba52722018-03-02 16:06:14946 ]
947 msgs = PRESUBMIT._CheckForIncludeGuards(
948 mock_input_api, mock_output_api)
Daniel Bratell39b5b062018-05-16 18:09:57949 expected_fail_count = 7
Daniel Bratell8ba52722018-03-02 16:06:14950 self.assertEqual(expected_fail_count, len(msgs),
951 'Expected %d items, found %d: %s'
952 % (expected_fail_count, len(msgs), msgs))
953 self.assertEqual(msgs[0].items, [ 'content/browser/thing/bar.h' ])
954 self.assertEqual(msgs[0].message,
955 'Include guard CONTENT_BROWSER_THING_BAR_H_ '
956 'not covering the whole file')
957
958 self.assertEqual(msgs[1].items, [ 'content/browser/test1.h' ])
959 self.assertEqual(msgs[1].message,
960 'Missing include guard CONTENT_BROWSER_TEST1_H_')
961
962 self.assertEqual(msgs[2].items, [ 'content/browser/test2.h:3' ])
963 self.assertEqual(msgs[2].message,
964 'Missing "#define CONTENT_BROWSER_TEST2_H_" for '
965 'include guard')
966
967 self.assertEqual(msgs[3].items, [ 'content/browser/spleling.h:1' ])
968 self.assertEqual(msgs[3].message,
969 'Header using the wrong include guard name '
970 'CONTENT_BROWSER_SPLLEING_H_')
971
972 self.assertEqual(msgs[4].items, [ 'content/NotInBlink.h:1' ])
973 self.assertEqual(msgs[4].message,
974 'Header using the wrong include guard name '
975 'NotInBlink_h')
976
Daniel Bratell39b5b062018-05-16 18:09:57977 self.assertEqual(msgs[5].items, [ 'third_party/blink/InBlink.h:1' ])
Daniel Bratell8ba52722018-03-02 16:06:14978 self.assertEqual(msgs[5].message,
979 'Header using the wrong include guard name '
Daniel Bratell39b5b062018-05-16 18:09:57980 'InBlink_h')
981
982 self.assertEqual(msgs[6].items, [ 'third_party/blink/AlsoInBlink.h:1' ])
983 self.assertEqual(msgs[6].message,
984 'Header using the wrong include guard name '
Daniel Bratell8ba52722018-03-02 16:06:14985 'WrongInBlink_h')
986
yolandyan45001472016-12-21 21:12:42987class AndroidDeprecatedTestAnnotationTest(unittest.TestCase):
988 def testCheckAndroidTestAnnotationUsage(self):
989 mock_input_api = MockInputApi()
990 mock_output_api = MockOutputApi()
991
992 mock_input_api.files = [
993 MockAffectedFile('LalaLand.java', [
994 'random stuff'
995 ]),
996 MockAffectedFile('CorrectUsage.java', [
997 'import android.support.test.filters.LargeTest;',
998 'import android.support.test.filters.MediumTest;',
999 'import android.support.test.filters.SmallTest;',
1000 ]),
1001 MockAffectedFile('UsedDeprecatedLargeTestAnnotation.java', [
1002 'import android.test.suitebuilder.annotation.LargeTest;',
1003 ]),
1004 MockAffectedFile('UsedDeprecatedMediumTestAnnotation.java', [
1005 'import android.test.suitebuilder.annotation.MediumTest;',
1006 ]),
1007 MockAffectedFile('UsedDeprecatedSmallTestAnnotation.java', [
1008 'import android.test.suitebuilder.annotation.SmallTest;',
1009 ]),
1010 MockAffectedFile('UsedDeprecatedSmokeAnnotation.java', [
1011 'import android.test.suitebuilder.annotation.Smoke;',
1012 ])
1013 ]
1014 msgs = PRESUBMIT._CheckAndroidTestAnnotationUsage(
1015 mock_input_api, mock_output_api)
1016 self.assertEqual(1, len(msgs),
1017 'Expected %d items, found %d: %s'
1018 % (1, len(msgs), msgs))
1019 self.assertEqual(4, len(msgs[0].items),
1020 'Expected %d items, found %d: %s'
1021 % (4, len(msgs[0].items), msgs[0].items))
1022 self.assertTrue('UsedDeprecatedLargeTestAnnotation.java:1' in msgs[0].items,
1023 'UsedDeprecatedLargeTestAnnotation not found in errors')
1024 self.assertTrue('UsedDeprecatedMediumTestAnnotation.java:1'
1025 in msgs[0].items,
1026 'UsedDeprecatedMediumTestAnnotation not found in errors')
1027 self.assertTrue('UsedDeprecatedSmallTestAnnotation.java:1' in msgs[0].items,
1028 'UsedDeprecatedSmallTestAnnotation not found in errors')
1029 self.assertTrue('UsedDeprecatedSmokeAnnotation.java:1' in msgs[0].items,
1030 'UsedDeprecatedSmokeAnnotation not found in errors')
1031
Yoland Yanb92fa522017-08-28 17:37:061032class AndroidDeprecatedJUnitFrameworkTest(unittest.TestCase):
Wei-Yin Chen (陳威尹)032f1ac2018-07-27 21:21:271033 def testCheckAndroidTestJUnitFramework(self):
Yoland Yanb92fa522017-08-28 17:37:061034 mock_input_api = MockInputApi()
1035 mock_output_api = MockOutputApi()
yolandyan45001472016-12-21 21:12:421036
Yoland Yanb92fa522017-08-28 17:37:061037 mock_input_api.files = [
1038 MockAffectedFile('LalaLand.java', [
1039 'random stuff'
1040 ]),
1041 MockAffectedFile('CorrectUsage.java', [
1042 'import org.junit.ABC',
1043 'import org.junit.XYZ;',
1044 ]),
1045 MockAffectedFile('UsedDeprecatedJUnit.java', [
1046 'import junit.framework.*;',
1047 ]),
1048 MockAffectedFile('UsedDeprecatedJUnitAssert.java', [
1049 'import junit.framework.Assert;',
1050 ]),
1051 ]
1052 msgs = PRESUBMIT._CheckAndroidTestJUnitFrameworkImport(
1053 mock_input_api, mock_output_api)
1054 self.assertEqual(1, len(msgs),
1055 'Expected %d items, found %d: %s'
1056 % (1, len(msgs), msgs))
1057 self.assertEqual(2, len(msgs[0].items),
1058 'Expected %d items, found %d: %s'
1059 % (2, len(msgs[0].items), msgs[0].items))
1060 self.assertTrue('UsedDeprecatedJUnit.java:1' in msgs[0].items,
1061 'UsedDeprecatedJUnit.java not found in errors')
1062 self.assertTrue('UsedDeprecatedJUnitAssert.java:1'
1063 in msgs[0].items,
1064 'UsedDeprecatedJUnitAssert not found in errors')
1065
Wei-Yin Chen (陳威尹)032f1ac2018-07-27 21:21:271066class AndroidJUnitBaseClassTest(unittest.TestCase):
1067 def testCheckAndroidTestJUnitBaseClass(self):
Yoland Yanb92fa522017-08-28 17:37:061068 mock_input_api = MockInputApi()
1069 mock_output_api = MockOutputApi()
1070
1071 mock_input_api.files = [
1072 MockAffectedFile('LalaLand.java', [
1073 'random stuff'
1074 ]),
1075 MockAffectedFile('CorrectTest.java', [
1076 '@RunWith(ABC.class);'
1077 'public class CorrectTest {',
1078 '}',
1079 ]),
1080 MockAffectedFile('HistoricallyIncorrectTest.java', [
1081 'public class Test extends BaseCaseA {',
1082 '}',
1083 ], old_contents=[
1084 'public class Test extends BaseCaseB {',
1085 '}',
1086 ]),
1087 MockAffectedFile('CorrectTestWithInterface.java', [
1088 '@RunWith(ABC.class);'
1089 'public class CorrectTest implement Interface {',
1090 '}',
1091 ]),
1092 MockAffectedFile('IncorrectTest.java', [
1093 'public class IncorrectTest extends TestCase {',
1094 '}',
1095 ]),
Vaclav Brozekf01ed502018-03-16 19:38:241096 MockAffectedFile('IncorrectWithInterfaceTest.java', [
Yoland Yanb92fa522017-08-28 17:37:061097 'public class Test implements X extends BaseClass {',
1098 '}',
1099 ]),
Vaclav Brozekf01ed502018-03-16 19:38:241100 MockAffectedFile('IncorrectMultiLineTest.java', [
Yoland Yanb92fa522017-08-28 17:37:061101 'public class Test implements X, Y, Z',
1102 ' extends TestBase {',
1103 '}',
1104 ]),
1105 ]
1106 msgs = PRESUBMIT._CheckAndroidTestJUnitInheritance(
1107 mock_input_api, mock_output_api)
1108 self.assertEqual(1, len(msgs),
1109 'Expected %d items, found %d: %s'
1110 % (1, len(msgs), msgs))
1111 self.assertEqual(3, len(msgs[0].items),
1112 'Expected %d items, found %d: %s'
1113 % (3, len(msgs[0].items), msgs[0].items))
1114 self.assertTrue('IncorrectTest.java:1' in msgs[0].items,
1115 'IncorrectTest not found in errors')
Vaclav Brozekf01ed502018-03-16 19:38:241116 self.assertTrue('IncorrectWithInterfaceTest.java:1'
Yoland Yanb92fa522017-08-28 17:37:061117 in msgs[0].items,
Vaclav Brozekf01ed502018-03-16 19:38:241118 'IncorrectWithInterfaceTest not found in errors')
1119 self.assertTrue('IncorrectMultiLineTest.java:2' in msgs[0].items,
1120 'IncorrectMultiLineTest not found in errors')
yolandyan45001472016-12-21 21:12:421121
dgn4401aa52015-04-29 16:26:171122class LogUsageTest(unittest.TestCase):
1123
dgnaa68d5e2015-06-10 10:08:221124 def testCheckAndroidCrLogUsage(self):
1125 mock_input_api = MockInputApi()
1126 mock_output_api = MockOutputApi()
1127
1128 mock_input_api.files = [
1129 MockAffectedFile('RandomStuff.java', [
1130 'random stuff'
1131 ]),
dgn87d9fb62015-06-12 09:15:121132 MockAffectedFile('HasAndroidLog.java', [
1133 'import android.util.Log;',
1134 'some random stuff',
1135 'Log.d("TAG", "foo");',
1136 ]),
1137 MockAffectedFile('HasExplicitUtilLog.java', [
1138 'some random stuff',
1139 'android.util.Log.d("TAG", "foo");',
1140 ]),
1141 MockAffectedFile('IsInBasePackage.java', [
1142 'package org.chromium.base;',
dgn38736db2015-09-18 19:20:511143 'private static final String TAG = "cr_Foo";',
dgn87d9fb62015-06-12 09:15:121144 'Log.d(TAG, "foo");',
1145 ]),
1146 MockAffectedFile('IsInBasePackageButImportsLog.java', [
1147 'package org.chromium.base;',
1148 'import android.util.Log;',
dgn38736db2015-09-18 19:20:511149 'private static final String TAG = "cr_Foo";',
dgn87d9fb62015-06-12 09:15:121150 'Log.d(TAG, "foo");',
1151 ]),
1152 MockAffectedFile('HasBothLog.java', [
1153 'import org.chromium.base.Log;',
1154 'some random stuff',
dgn38736db2015-09-18 19:20:511155 'private static final String TAG = "cr_Foo";',
dgn87d9fb62015-06-12 09:15:121156 'Log.d(TAG, "foo");',
1157 'android.util.Log.d("TAG", "foo");',
1158 ]),
dgnaa68d5e2015-06-10 10:08:221159 MockAffectedFile('HasCorrectTag.java', [
1160 'import org.chromium.base.Log;',
1161 'some random stuff',
dgn38736db2015-09-18 19:20:511162 'private static final String TAG = "cr_Foo";',
1163 'Log.d(TAG, "foo");',
1164 ]),
1165 MockAffectedFile('HasOldTag.java', [
1166 'import org.chromium.base.Log;',
1167 'some random stuff',
dgnaa68d5e2015-06-10 10:08:221168 'private static final String TAG = "cr.Foo";',
1169 'Log.d(TAG, "foo");',
1170 ]),
dgn38736db2015-09-18 19:20:511171 MockAffectedFile('HasDottedTag.java', [
dgnaa68d5e2015-06-10 10:08:221172 'import org.chromium.base.Log;',
1173 'some random stuff',
dgn38736db2015-09-18 19:20:511174 'private static final String TAG = "cr_foo.bar";',
dgnaa68d5e2015-06-10 10:08:221175 'Log.d(TAG, "foo");',
1176 ]),
1177 MockAffectedFile('HasNoTagDecl.java', [
1178 'import org.chromium.base.Log;',
1179 'some random stuff',
1180 'Log.d(TAG, "foo");',
1181 ]),
1182 MockAffectedFile('HasIncorrectTagDecl.java', [
1183 'import org.chromium.base.Log;',
dgn38736db2015-09-18 19:20:511184 'private static final String TAHG = "cr_Foo";',
dgnaa68d5e2015-06-10 10:08:221185 'some random stuff',
1186 'Log.d(TAG, "foo");',
1187 ]),
1188 MockAffectedFile('HasInlineTag.java', [
1189 'import org.chromium.base.Log;',
1190 'some random stuff',
dgn38736db2015-09-18 19:20:511191 'private static final String TAG = "cr_Foo";',
dgnaa68d5e2015-06-10 10:08:221192 'Log.d("TAG", "foo");',
1193 ]),
dgn38736db2015-09-18 19:20:511194 MockAffectedFile('HasUnprefixedTag.java', [
dgnaa68d5e2015-06-10 10:08:221195 'import org.chromium.base.Log;',
1196 'some random stuff',
1197 'private static final String TAG = "rubbish";',
1198 'Log.d(TAG, "foo");',
1199 ]),
1200 MockAffectedFile('HasTooLongTag.java', [
1201 'import org.chromium.base.Log;',
1202 'some random stuff',
dgn38736db2015-09-18 19:20:511203 'private static final String TAG = "21_charachers_long___";',
dgnaa68d5e2015-06-10 10:08:221204 'Log.d(TAG, "foo");',
1205 ]),
1206 ]
1207
1208 msgs = PRESUBMIT._CheckAndroidCrLogUsage(
1209 mock_input_api, mock_output_api)
1210
dgn38736db2015-09-18 19:20:511211 self.assertEqual(5, len(msgs),
1212 'Expected %d items, found %d: %s' % (5, len(msgs), msgs))
dgnaa68d5e2015-06-10 10:08:221213
1214 # Declaration format
dgn38736db2015-09-18 19:20:511215 nb = len(msgs[0].items)
1216 self.assertEqual(2, nb,
1217 'Expected %d items, found %d: %s' % (2, nb, msgs[0].items))
dgnaa68d5e2015-06-10 10:08:221218 self.assertTrue('HasNoTagDecl.java' in msgs[0].items)
1219 self.assertTrue('HasIncorrectTagDecl.java' in msgs[0].items)
dgnaa68d5e2015-06-10 10:08:221220
1221 # Tag length
dgn38736db2015-09-18 19:20:511222 nb = len(msgs[1].items)
1223 self.assertEqual(1, nb,
1224 'Expected %d items, found %d: %s' % (1, nb, msgs[1].items))
dgnaa68d5e2015-06-10 10:08:221225 self.assertTrue('HasTooLongTag.java' in msgs[1].items)
1226
1227 # Tag must be a variable named TAG
dgn38736db2015-09-18 19:20:511228 nb = len(msgs[2].items)
1229 self.assertEqual(1, nb,
1230 'Expected %d items, found %d: %s' % (1, nb, msgs[2].items))
dgnaa68d5e2015-06-10 10:08:221231 self.assertTrue('HasInlineTag.java:4' in msgs[2].items)
1232
dgn87d9fb62015-06-12 09:15:121233 # Util Log usage
dgn38736db2015-09-18 19:20:511234 nb = len(msgs[3].items)
1235 self.assertEqual(2, nb,
1236 'Expected %d items, found %d: %s' % (2, nb, msgs[3].items))
dgn87d9fb62015-06-12 09:15:121237 self.assertTrue('HasAndroidLog.java:3' in msgs[3].items)
1238 self.assertTrue('IsInBasePackageButImportsLog.java:4' in msgs[3].items)
dgnaa68d5e2015-06-10 10:08:221239
dgn38736db2015-09-18 19:20:511240 # Tag must not contain
1241 nb = len(msgs[4].items)
1242 self.assertEqual(2, nb,
1243 'Expected %d items, found %d: %s' % (2, nb, msgs[4].items))
1244 self.assertTrue('HasDottedTag.java' in msgs[4].items)
1245 self.assertTrue('HasOldTag.java' in msgs[4].items)
1246
estadee17314a02017-01-12 16:22:161247class GoogleAnswerUrlFormatTest(unittest.TestCase):
1248
1249 def testCatchAnswerUrlId(self):
1250 input_api = MockInputApi()
1251 input_api.files = [
1252 MockFile('somewhere/file.cc',
1253 ['char* host = '
1254 ' "https://support.google.com/chrome/answer/123456";']),
1255 MockFile('somewhere_else/file.cc',
1256 ['char* host = '
1257 ' "https://support.google.com/chrome/a/answer/123456";']),
1258 ]
1259
1260 warnings = PRESUBMIT._CheckGoogleSupportAnswerUrl(
1261 input_api, MockOutputApi())
1262 self.assertEqual(1, len(warnings))
1263 self.assertEqual(2, len(warnings[0].items))
1264
1265 def testAllowAnswerUrlParam(self):
1266 input_api = MockInputApi()
1267 input_api.files = [
1268 MockFile('somewhere/file.cc',
1269 ['char* host = '
1270 ' "https://support.google.com/chrome/?p=cpn_crash_reports";']),
1271 ]
1272
1273 warnings = PRESUBMIT._CheckGoogleSupportAnswerUrl(
1274 input_api, MockOutputApi())
1275 self.assertEqual(0, len(warnings))
1276
reillyi38965732015-11-16 18:27:331277class HardcodedGoogleHostsTest(unittest.TestCase):
1278
1279 def testWarnOnAssignedLiterals(self):
1280 input_api = MockInputApi()
1281 input_api.files = [
1282 MockFile('content/file.cc',
1283 ['char* host = "https://www.google.com";']),
1284 MockFile('content/file.cc',
1285 ['char* host = "https://www.googleapis.com";']),
1286 MockFile('content/file.cc',
1287 ['char* host = "https://clients1.google.com";']),
1288 ]
1289
1290 warnings = PRESUBMIT._CheckHardcodedGoogleHostsInLowerLayers(
1291 input_api, MockOutputApi())
1292 self.assertEqual(1, len(warnings))
1293 self.assertEqual(3, len(warnings[0].items))
1294
1295 def testAllowInComment(self):
1296 input_api = MockInputApi()
1297 input_api.files = [
1298 MockFile('content/file.cc',
1299 ['char* host = "https://www.aol.com"; // google.com'])
1300 ]
1301
1302 warnings = PRESUBMIT._CheckHardcodedGoogleHostsInLowerLayers(
1303 input_api, MockOutputApi())
1304 self.assertEqual(0, len(warnings))
1305
dgn4401aa52015-04-29 16:26:171306
jbriance9e12f162016-11-25 07:57:501307class ForwardDeclarationTest(unittest.TestCase):
jbriance2c51e821a2016-12-12 08:24:311308 def testCheckHeadersOnlyOutsideThirdParty(self):
jbriance9e12f162016-11-25 07:57:501309 mock_input_api = MockInputApi()
1310 mock_input_api.files = [
1311 MockAffectedFile('somewhere/file.cc', [
1312 'class DummyClass;'
jbriance2c51e821a2016-12-12 08:24:311313 ]),
1314 MockAffectedFile('third_party/header.h', [
1315 'class DummyClass;'
jbriance9e12f162016-11-25 07:57:501316 ])
1317 ]
1318 warnings = PRESUBMIT._CheckUselessForwardDeclarations(mock_input_api,
1319 MockOutputApi())
1320 self.assertEqual(0, len(warnings))
1321
1322 def testNoNestedDeclaration(self):
1323 mock_input_api = MockInputApi()
1324 mock_input_api.files = [
1325 MockAffectedFile('somewhere/header.h', [
jbriance2c51e821a2016-12-12 08:24:311326 'class SomeClass {',
1327 ' protected:',
1328 ' class NotAMatch;',
jbriance9e12f162016-11-25 07:57:501329 '};'
1330 ])
1331 ]
1332 warnings = PRESUBMIT._CheckUselessForwardDeclarations(mock_input_api,
1333 MockOutputApi())
1334 self.assertEqual(0, len(warnings))
1335
1336 def testSubStrings(self):
1337 mock_input_api = MockInputApi()
1338 mock_input_api.files = [
1339 MockAffectedFile('somewhere/header.h', [
1340 'class NotUsefulClass;',
1341 'struct SomeStruct;',
1342 'UsefulClass *p1;',
1343 'SomeStructPtr *p2;'
1344 ])
1345 ]
1346 warnings = PRESUBMIT._CheckUselessForwardDeclarations(mock_input_api,
1347 MockOutputApi())
1348 self.assertEqual(2, len(warnings))
1349
1350 def testUselessForwardDeclaration(self):
1351 mock_input_api = MockInputApi()
1352 mock_input_api.files = [
1353 MockAffectedFile('somewhere/header.h', [
1354 'class DummyClass;',
1355 'struct DummyStruct;',
1356 'class UsefulClass;',
1357 'std::unique_ptr<UsefulClass> p;'
jbriance2c51e821a2016-12-12 08:24:311358 ])
jbriance9e12f162016-11-25 07:57:501359 ]
1360 warnings = PRESUBMIT._CheckUselessForwardDeclarations(mock_input_api,
1361 MockOutputApi())
1362 self.assertEqual(2, len(warnings))
1363
jbriance2c51e821a2016-12-12 08:24:311364 def testBlinkHeaders(self):
1365 mock_input_api = MockInputApi()
1366 mock_input_api.files = [
1367 MockAffectedFile('third_party/WebKit/header.h', [
1368 'class DummyClass;',
1369 'struct DummyStruct;',
1370 ]),
1371 MockAffectedFile('third_party\\WebKit\\header.h', [
1372 'class DummyClass;',
1373 'struct DummyStruct;',
1374 ])
1375 ]
1376 warnings = PRESUBMIT._CheckUselessForwardDeclarations(mock_input_api,
1377 MockOutputApi())
1378 self.assertEqual(4, len(warnings))
1379
jbriance9e12f162016-11-25 07:57:501380
dbeam1ec68ac2016-12-15 05:22:241381class RiskyJsTest(unittest.TestCase):
1382 def testArrowWarnInIos9Code(self):
1383 mock_input_api = MockInputApi()
1384 mock_output_api = MockOutputApi()
1385
1386 mock_input_api.files = [
1387 MockAffectedFile('components/blah.js', ["shouldn't use => here"]),
1388 ]
1389 warnings = PRESUBMIT._CheckForRiskyJsFeatures(
1390 mock_input_api, mock_output_api)
1391 self.assertEqual(1, len(warnings))
1392
1393 mock_input_api.files = [
1394 MockAffectedFile('ios/blee.js', ['might => break folks']),
1395 ]
1396 warnings = PRESUBMIT._CheckForRiskyJsFeatures(
1397 mock_input_api, mock_output_api)
1398 self.assertEqual(1, len(warnings))
1399
1400 mock_input_api.files = [
1401 MockAffectedFile('ui/webui/resources/blarg.js', ['on => iOS9']),
1402 ]
1403 warnings = PRESUBMIT._CheckForRiskyJsFeatures(
1404 mock_input_api, mock_output_api)
1405 self.assertEqual(1, len(warnings))
1406
1407 def testArrowsAllowedInChromeCode(self):
1408 mock_input_api = MockInputApi()
1409 mock_input_api.files = [
1410 MockAffectedFile('chrome/browser/resources/blah.js', 'arrow => OK here'),
1411 ]
1412 warnings = PRESUBMIT._CheckForRiskyJsFeatures(
1413 mock_input_api, MockOutputApi())
1414 self.assertEqual(0, len(warnings))
1415
dpapadd651231d82017-07-21 02:44:471416 def testConstLetWarningIos9Code(self):
1417 mock_input_api = MockInputApi()
1418 mock_output_api = MockOutputApi()
1419
1420 mock_input_api.files = [
1421 MockAffectedFile('components/blah.js', [" const foo = 'bar';"]),
1422 MockAffectedFile('ui/webui/resources/blah.js', [" let foo = 3;"]),
1423 ]
1424 warnings = PRESUBMIT._CheckForRiskyJsFeatures(
1425 mock_input_api, mock_output_api)
1426 self.assertEqual(2, len(warnings))
1427
rlanday6802cf632017-05-30 17:48:361428class RelativeIncludesTest(unittest.TestCase):
1429 def testThirdPartyNotWebKitIgnored(self):
1430 mock_input_api = MockInputApi()
1431 mock_input_api.files = [
1432 MockAffectedFile('third_party/test.cpp', '#include "../header.h"'),
1433 MockAffectedFile('third_party/test/test.cpp', '#include "../header.h"'),
1434 ]
1435
1436 mock_output_api = MockOutputApi()
1437
1438 errors = PRESUBMIT._CheckForRelativeIncludes(
1439 mock_input_api, mock_output_api)
1440 self.assertEqual(0, len(errors))
1441
1442 def testNonCppFileIgnored(self):
1443 mock_input_api = MockInputApi()
1444 mock_input_api.files = [
1445 MockAffectedFile('test.py', '#include "../header.h"'),
1446 ]
1447
1448 mock_output_api = MockOutputApi()
1449
1450 errors = PRESUBMIT._CheckForRelativeIncludes(
1451 mock_input_api, mock_output_api)
1452 self.assertEqual(0, len(errors))
1453
1454 def testInnocuousChangesAllowed(self):
1455 mock_input_api = MockInputApi()
1456 mock_input_api.files = [
1457 MockAffectedFile('test.cpp', '#include "header.h"'),
1458 MockAffectedFile('test2.cpp', '../'),
1459 ]
1460
1461 mock_output_api = MockOutputApi()
1462
1463 errors = PRESUBMIT._CheckForRelativeIncludes(
1464 mock_input_api, mock_output_api)
1465 self.assertEqual(0, len(errors))
1466
1467 def testRelativeIncludeNonWebKitProducesError(self):
1468 mock_input_api = MockInputApi()
1469 mock_input_api.files = [
1470 MockAffectedFile('test.cpp', ['#include "../header.h"']),
1471 ]
1472
1473 mock_output_api = MockOutputApi()
1474
1475 errors = PRESUBMIT._CheckForRelativeIncludes(
1476 mock_input_api, mock_output_api)
1477 self.assertEqual(1, len(errors))
1478
1479 def testRelativeIncludeWebKitProducesError(self):
1480 mock_input_api = MockInputApi()
1481 mock_input_api.files = [
1482 MockAffectedFile('third_party/WebKit/test.cpp',
1483 ['#include "../header.h']),
1484 ]
1485
1486 mock_output_api = MockOutputApi()
1487
1488 errors = PRESUBMIT._CheckForRelativeIncludes(
1489 mock_input_api, mock_output_api)
1490 self.assertEqual(1, len(errors))
dbeam1ec68ac2016-12-15 05:22:241491
Daniel Cheng13ca61a882017-08-25 15:11:251492
1493class MojoManifestOwnerTest(unittest.TestCase):
1494 def testMojoManifestChangeNeedsSecurityOwner(self):
1495 mock_input_api = MockInputApi()
1496 mock_input_api.files = [
1497 MockAffectedFile('services/goat/manifest.json',
1498 [
1499 '{',
1500 ' "name": "teleporter",',
1501 ' "display_name": "Goat Teleporter",'
1502 ' "interface_provider_specs": {',
1503 ' }',
1504 '}',
1505 ])
1506 ]
1507 mock_output_api = MockOutputApi()
1508 errors = PRESUBMIT._CheckIpcOwners(
1509 mock_input_api, mock_output_api)
1510 self.assertEqual(1, len(errors))
1511 self.assertEqual(
1512 'Found OWNERS files that need to be updated for IPC security review ' +
1513 'coverage.\nPlease update the OWNERS files below:', errors[0].message)
1514
1515 # No warning if already covered by an OWNERS rule.
1516
1517 def testNonManifestChangesDoNotRequireSecurityOwner(self):
1518 mock_input_api = MockInputApi()
1519 mock_input_api.files = [
1520 MockAffectedFile('services/goat/species.json',
1521 [
1522 '[',
1523 ' "anglo-nubian",',
1524 ' "angora"',
1525 ']',
1526 ])
1527 ]
1528 mock_output_api = MockOutputApi()
1529 errors = PRESUBMIT._CheckIpcOwners(
1530 mock_input_api, mock_output_api)
1531 self.assertEqual([], errors)
1532
1533
Miguel Casas-Sancheze0d46d42017-12-14 15:52:191534class CrbugUrlFormatTest(unittest.TestCase):
1535
1536 def testCheckCrbugLinksHaveHttps(self):
1537 input_api = MockInputApi()
1538 input_api.files = [
1539 MockFile('somewhere/file.cc',
1540 ['// TODO(developer): crbug.com should be linkified',
1541 '// TODO(developer): (crbug.com) should be linkified',
1542 '// TODO(developer): crbug/123 should be well formed',
1543 '// TODO(developer): http://crbug.com it\'s OK',
Miguel Casas68bdb652017-12-19 16:29:091544 '// TODO(developer): https://crbug.com is just great',
1545 '// TODO(crbug.com/123456): this pattern it\'s also OK']),
Miguel Casas-Sancheze0d46d42017-12-14 15:52:191546 ]
1547
1548 warnings = PRESUBMIT._CheckCrbugLinksHaveHttps(input_api, MockOutputApi())
1549 self.assertEqual(1, len(warnings))
Miguel Casas68bdb652017-12-19 16:29:091550 self.assertEqual(3, warnings[0].message.count('\n'));
Miguel Casas-Sancheze0d46d42017-12-14 15:52:191551
1552
Sylvain Defresnea8b73d252018-02-28 15:45:541553class BannedFunctionCheckTest(unittest.TestCase):
1554
1555 def testBannedIosObcjFunctions(self):
1556 input_api = MockInputApi()
1557 input_api.files = [
1558 MockFile('some/ios/file.mm',
1559 ['TEST(SomeClassTest, SomeInteraction) {',
1560 '}']),
1561 MockFile('some/mac/file.mm',
1562 ['TEST(SomeClassTest, SomeInteraction) {',
1563 '}']),
1564 MockFile('another/ios_file.mm',
1565 ['class SomeTest : public testing::Test {};']),
1566 ]
1567
1568 errors = PRESUBMIT._CheckNoBannedFunctions(input_api, MockOutputApi())
1569 self.assertEqual(1, len(errors))
1570 self.assertTrue('some/ios/file.mm' in errors[0].message)
1571 self.assertTrue('another/ios_file.mm' in errors[0].message)
1572 self.assertTrue('some/mac/file.mm' not in errors[0].message)
1573
1574
Wei-Yin Chen (陳威尹)032f1ac2018-07-27 21:21:271575class NoProductionCodeUsingTestOnlyFunctionsTest(unittest.TestCase):
Vaclav Brozekf01ed502018-03-16 19:38:241576 def testTruePositives(self):
1577 mock_input_api = MockInputApi()
1578 mock_input_api.files = [
1579 MockFile('some/path/foo.cc', ['foo_for_testing();']),
1580 MockFile('some/path/foo.mm', ['FooForTesting();']),
1581 MockFile('some/path/foo.cxx', ['FooForTests();']),
1582 MockFile('some/path/foo.cpp', ['foo_for_test();']),
1583 ]
1584
1585 results = PRESUBMIT._CheckNoProductionCodeUsingTestOnlyFunctions(
1586 mock_input_api, MockOutputApi())
1587 self.assertEqual(1, len(results))
1588 self.assertEqual(4, len(results[0].items))
1589 self.assertTrue('foo.cc' in results[0].items[0])
1590 self.assertTrue('foo.mm' in results[0].items[1])
1591 self.assertTrue('foo.cxx' in results[0].items[2])
1592 self.assertTrue('foo.cpp' in results[0].items[3])
1593
1594 def testFalsePositives(self):
1595 mock_input_api = MockInputApi()
1596 mock_input_api.files = [
1597 MockFile('some/path/foo.h', ['foo_for_testing();']),
1598 MockFile('some/path/foo.mm', ['FooForTesting() {']),
1599 MockFile('some/path/foo.cc', ['::FooForTests();']),
1600 MockFile('some/path/foo.cpp', ['// foo_for_test();']),
1601 ]
1602
1603 results = PRESUBMIT._CheckNoProductionCodeUsingTestOnlyFunctions(
1604 mock_input_api, MockOutputApi())
1605 self.assertEqual(0, len(results))
1606
1607
Wei-Yin Chen (陳威尹)032f1ac2018-07-27 21:21:271608class NoProductionJavaCodeUsingTestOnlyFunctionsTest(unittest.TestCase):
Vaclav Brozek7dbc28c2018-03-27 08:35:231609 def testTruePositives(self):
1610 mock_input_api = MockInputApi()
1611 mock_input_api.files = [
1612 MockFile('dir/java/src/foo.java', ['FooForTesting();']),
1613 MockFile('dir/java/src/bar.java', ['FooForTests(x);']),
1614 MockFile('dir/java/src/baz.java', ['FooForTest(','y',');']),
1615 MockFile('dir/java/src/mult.java', [
1616 'int x = SomethingLongHere()',
1617 ' * SomethingLongHereForTesting();'
1618 ]),
1619 ]
1620
1621 results = PRESUBMIT._CheckNoProductionCodeUsingTestOnlyFunctionsJava(
1622 mock_input_api, MockOutputApi())
1623 self.assertEqual(1, len(results))
1624 self.assertEqual(4, len(results[0].items))
1625 self.assertTrue('foo.java' in results[0].items[0])
1626 self.assertTrue('bar.java' in results[0].items[1])
1627 self.assertTrue('baz.java' in results[0].items[2])
1628 self.assertTrue('mult.java' in results[0].items[3])
1629
1630 def testFalsePositives(self):
1631 mock_input_api = MockInputApi()
1632 mock_input_api.files = [
1633 MockFile('dir/java/src/foo.xml', ['FooForTesting();']),
1634 MockFile('dir/java/src/foo.java', ['FooForTests() {']),
1635 MockFile('dir/java/src/bar.java', ['// FooForTest();']),
1636 MockFile('dir/java/src/bar2.java', ['x = 1; // FooForTest();']),
1637 MockFile('dir/javatests/src/baz.java', ['FooForTest(','y',');']),
1638 MockFile('dir/junit/src/baz.java', ['FooForTest(','y',');']),
1639 MockFile('dir/junit/src/javadoc.java', [
1640 '/** Use FooForTest(); to obtain foo in tests.'
1641 ' */'
1642 ]),
1643 MockFile('dir/junit/src/javadoc2.java', [
1644 '/** ',
1645 ' * Use FooForTest(); to obtain foo in tests.'
1646 ' */'
1647 ]),
1648 ]
1649
1650 results = PRESUBMIT._CheckNoProductionCodeUsingTestOnlyFunctionsJava(
1651 mock_input_api, MockOutputApi())
1652 self.assertEqual(0, len(results))
1653
1654
Wei-Yin Chen (陳威尹)032f1ac2018-07-27 21:21:271655class CheckUniquePtrTest(unittest.TestCase):
Vaclav Brozek851d9602018-04-04 16:13:051656 def testTruePositivesNullptr(self):
1657 mock_input_api = MockInputApi()
1658 mock_input_api.files = [
Vaclav Brozekc2fecf42018-04-06 16:40:161659 MockFile('dir/baz.cc', ['std::unique_ptr<T>()']),
1660 MockFile('dir/baz-p.cc', ['std::unique_ptr<T<P>>()']),
Vaclav Brozek851d9602018-04-04 16:13:051661 ]
1662
1663 results = PRESUBMIT._CheckUniquePtr(mock_input_api, MockOutputApi())
1664 self.assertEqual(1, len(results))
Vaclav Brozekc2fecf42018-04-06 16:40:161665 self.assertTrue('nullptr' in results[0].message)
Vaclav Brozek851d9602018-04-04 16:13:051666 self.assertEqual(2, len(results[0].items))
1667 self.assertTrue('baz.cc' in results[0].items[0])
1668 self.assertTrue('baz-p.cc' in results[0].items[1])
1669
1670 def testTruePositivesConstructor(self):
Vaclav Brozek52e18bf2018-04-03 07:05:241671 mock_input_api = MockInputApi()
1672 mock_input_api.files = [
Vaclav Brozekc2fecf42018-04-06 16:40:161673 MockFile('dir/foo.cc', ['return std::unique_ptr<T>(foo);']),
1674 MockFile('dir/bar.mm', ['bar = std::unique_ptr<T>(foo)']),
1675 MockFile('dir/mult.cc', [
Vaclav Brozek95face62018-04-04 14:15:111676 'return',
1677 ' std::unique_ptr<T>(barVeryVeryLongFooSoThatItWouldNotFitAbove);'
1678 ]),
Vaclav Brozekc2fecf42018-04-06 16:40:161679 MockFile('dir/mult2.cc', [
Vaclav Brozek95face62018-04-04 14:15:111680 'barVeryVeryLongLongBaaaaaarSoThatTheLineLimitIsAlmostReached =',
1681 ' std::unique_ptr<T>(foo);'
1682 ]),
Vaclav Brozekc2fecf42018-04-06 16:40:161683 MockFile('dir/mult3.cc', [
Vaclav Brozek95face62018-04-04 14:15:111684 'bar = std::unique_ptr<T>(',
1685 ' fooVeryVeryVeryLongStillGoingWellThisWillTakeAWhileFinallyThere);'
1686 ]),
Vaclav Brozek52e18bf2018-04-03 07:05:241687 ]
1688
1689 results = PRESUBMIT._CheckUniquePtr(mock_input_api, MockOutputApi())
Vaclav Brozek851d9602018-04-04 16:13:051690 self.assertEqual(1, len(results))
Vaclav Brozekc2fecf42018-04-06 16:40:161691 self.assertTrue('std::make_unique' in results[0].message)
Vaclav Brozek851d9602018-04-04 16:13:051692 self.assertEqual(5, len(results[0].items))
1693 self.assertTrue('foo.cc' in results[0].items[0])
1694 self.assertTrue('bar.mm' in results[0].items[1])
1695 self.assertTrue('mult.cc' in results[0].items[2])
1696 self.assertTrue('mult2.cc' in results[0].items[3])
1697 self.assertTrue('mult3.cc' in results[0].items[4])
Vaclav Brozek52e18bf2018-04-03 07:05:241698
1699 def testFalsePositives(self):
1700 mock_input_api = MockInputApi()
1701 mock_input_api.files = [
Vaclav Brozekc2fecf42018-04-06 16:40:161702 MockFile('dir/foo.cc', ['return std::unique_ptr<T[]>(foo);']),
1703 MockFile('dir/bar.mm', ['bar = std::unique_ptr<T[]>(foo)']),
1704 MockFile('dir/file.cc', ['std::unique_ptr<T> p = Foo();']),
1705 MockFile('dir/baz.cc', [
Vaclav Brozek52e18bf2018-04-03 07:05:241706 'std::unique_ptr<T> result = std::make_unique<T>();'
1707 ]),
Vaclav Brozeka54c528b2018-04-06 19:23:551708 MockFile('dir/baz2.cc', [
1709 'std::unique_ptr<T> result = std::make_unique<T>('
1710 ]),
1711 MockFile('dir/nested.cc', ['set<std::unique_ptr<T>>();']),
1712 MockFile('dir/nested2.cc', ['map<U, std::unique_ptr<T>>();']),
Vaclav Brozek52e18bf2018-04-03 07:05:241713 ]
1714
1715 results = PRESUBMIT._CheckUniquePtr(mock_input_api, MockOutputApi())
1716 self.assertEqual(0, len(results))
1717
1718
[email protected]2299dcf2012-11-15 19:56:241719if __name__ == '__main__':
1720 unittest.main()