blob: 970cc304bb00ff975c8bdb4e45edd83571ba300f [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]99171a92014-06-03 08:44:477import subprocess
[email protected]2299dcf2012-11-15 19:56:248import unittest
9
10import PRESUBMIT
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:3911from PRESUBMIT_test_mocks import MockFile, MockAffectedFile
gayane3dff8c22014-12-04 17:09:5112from PRESUBMIT_test_mocks import MockInputApi, MockOutputApi
[email protected]2299dcf2012-11-15 19:56:2413
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:3914
[email protected]99171a92014-06-03 08:44:4715_TEST_DATA_DIR = 'base/test/data/presubmit'
16
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:3917
[email protected]b00342e7f2013-03-26 16:21:5418class VersionControlConflictsTest(unittest.TestCase):
[email protected]70ca77752012-11-20 03:45:0319 def testTypicalConflict(self):
20 lines = ['<<<<<<< HEAD',
21 ' base::ScopedTempDir temp_dir_;',
22 '=======',
23 ' ScopedTempDir temp_dir_;',
24 '>>>>>>> master']
25 errors = PRESUBMIT._CheckForVersionControlConflictsInFile(
26 MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
27 self.assertEqual(3, len(errors))
28 self.assertTrue('1' in errors[0])
29 self.assertTrue('3' in errors[1])
30 self.assertTrue('5' in errors[2])
31
dbeam95c35a2f2015-06-02 01:40:2332 def testIgnoresReadmes(self):
33 lines = ['A First Level Header',
34 '====================',
35 '',
36 'A Second Level Header',
37 '---------------------']
38 errors = PRESUBMIT._CheckForVersionControlConflictsInFile(
39 MockInputApi(), MockFile('some/polymer/README.md', lines))
40 self.assertEqual(0, len(errors))
41
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:3942
mcasasb7440c282015-02-04 14:52:1943class UmaHistogramChangeMatchedOrNotTest(unittest.TestCase):
44 def testTypicalCorrectlyMatchedChange(self):
45 diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
Vaclav Brozekbdac817c2018-03-24 06:30:4746 diff_java = [
47 'RecordHistogram.recordBooleanHistogram("Bla.Foo.Dummy", true)']
mcasasb7440c282015-02-04 14:52:1948 diff_xml = ['<histogram name="Bla.Foo.Dummy"> </histogram>']
49 mock_input_api = MockInputApi()
50 mock_input_api.files = [
51 MockFile('some/path/foo.cc', diff_cc),
Vaclav Brozekbdac817c2018-03-24 06:30:4752 MockFile('some/path/foo.java', diff_java),
mcasasb7440c282015-02-04 14:52:1953 MockFile('tools/metrics/histograms/histograms.xml', diff_xml),
54 ]
55 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
56 MockOutputApi())
57 self.assertEqual(0, len(warnings))
58
59 def testTypicalNotMatchedChange(self):
60 diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
Vaclav Brozekbdac817c2018-03-24 06:30:4761 diff_java = [
62 'RecordHistogram.recordBooleanHistogram("Bla.Foo.Dummy", true)']
mcasasb7440c282015-02-04 14:52:1963 mock_input_api = MockInputApi()
Vaclav Brozekbdac817c2018-03-24 06:30:4764 mock_input_api.files = [
65 MockFile('some/path/foo.cc', diff_cc),
66 MockFile('some/path/foo.java', diff_java),
67 ]
mcasasb7440c282015-02-04 14:52:1968 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
69 MockOutputApi())
70 self.assertEqual(1, len(warnings))
71 self.assertEqual('warning', warnings[0].type)
Vaclav Brozekbdac817c2018-03-24 06:30:4772 self.assertTrue('foo.cc' in warnings[0].items[0])
73 self.assertTrue('foo.java' in warnings[0].items[1])
mcasasb7440c282015-02-04 14:52:1974
75 def testTypicalNotMatchedChangeViaSuffixes(self):
76 diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
Vaclav Brozekbdac817c2018-03-24 06:30:4777 diff_java = [
78 'RecordHistogram.recordBooleanHistogram("Bla.Foo.Dummy", true)']
mcasasb7440c282015-02-04 14:52:1979 diff_xml = ['<histogram_suffixes name="SuperHistogram">',
80 ' <suffix name="Dummy"/>',
81 ' <affected-histogram name="Snafu.Dummy"/>',
82 '</histogram>']
83 mock_input_api = MockInputApi()
84 mock_input_api.files = [
85 MockFile('some/path/foo.cc', diff_cc),
Vaclav Brozekbdac817c2018-03-24 06:30:4786 MockFile('some/path/foo.java', diff_java),
mcasasb7440c282015-02-04 14:52:1987 MockFile('tools/metrics/histograms/histograms.xml', diff_xml),
88 ]
89 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
90 MockOutputApi())
91 self.assertEqual(1, len(warnings))
92 self.assertEqual('warning', warnings[0].type)
Vaclav Brozekbdac817c2018-03-24 06:30:4793 self.assertTrue('foo.cc' in warnings[0].items[0])
94 self.assertTrue('foo.java' in warnings[0].items[1])
mcasasb7440c282015-02-04 14:52:1995
96 def testTypicalCorrectlyMatchedChangeViaSuffixes(self):
97 diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
Vaclav Brozekbdac817c2018-03-24 06:30:4798 diff_java = [
99 'RecordHistogram.recordBooleanHistogram("Bla.Foo.Dummy", true)']
mcasasb7440c282015-02-04 14:52:19100 diff_xml = ['<histogram_suffixes name="SuperHistogram">',
101 ' <suffix name="Dummy"/>',
102 ' <affected-histogram name="Bla.Foo"/>',
103 '</histogram>']
104 mock_input_api = MockInputApi()
105 mock_input_api.files = [
106 MockFile('some/path/foo.cc', diff_cc),
Vaclav Brozekbdac817c2018-03-24 06:30:47107 MockFile('some/path/foo.java', diff_java),
mcasasb7440c282015-02-04 14:52:19108 MockFile('tools/metrics/histograms/histograms.xml', diff_xml),
109 ]
110 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
111 MockOutputApi())
112 self.assertEqual(0, len(warnings))
113
114 def testTypicalCorrectlyMatchedChangeViaSuffixesWithSeparator(self):
115 diff_cc = ['UMA_HISTOGRAM_BOOL("Snafu_Dummy", true)']
Vaclav Brozekbdac817c2018-03-24 06:30:47116 diff_java = ['RecordHistogram.recordBooleanHistogram("Snafu_Dummy", true)']
mcasasb7440c282015-02-04 14:52:19117 diff_xml = ['<histogram_suffixes name="SuperHistogram" separator="_">',
118 ' <suffix name="Dummy"/>',
119 ' <affected-histogram name="Snafu"/>',
120 '</histogram>']
121 mock_input_api = MockInputApi()
122 mock_input_api.files = [
123 MockFile('some/path/foo.cc', diff_cc),
Vaclav Brozekbdac817c2018-03-24 06:30:47124 MockFile('some/path/foo.java', diff_java),
mcasasb7440c282015-02-04 14:52:19125 MockFile('tools/metrics/histograms/histograms.xml', diff_xml),
126 ]
127 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
128 MockOutputApi())
129 self.assertEqual(0, len(warnings))
[email protected]70ca77752012-11-20 03:45:03130
Makoto Shimazu3ad422cd2019-05-08 02:35:14131 def testCorrectlyMatchedChangeViaSuffixesWithLineWrapping(self):
132 diff_cc = [
133 'UMA_HISTOGRAM_BOOL("LongHistogramNameNeedsLineWrapping.Dummy", true)']
134 diff_java = ['RecordHistogram.recordBooleanHistogram(' +
135 '"LongHistogramNameNeedsLineWrapping.Dummy", true)']
136 diff_xml = ['<histogram_suffixes',
137 ' name="LongHistogramNameNeedsLineWrapping"',
138 ' separator=".">',
139 ' <suffix name="Dummy"/>',
140 ' <affected-histogram',
141 ' name="LongHistogramNameNeedsLineWrapping"/>',
142 '</histogram>']
143 mock_input_api = MockInputApi()
144 mock_input_api.files = [
145 MockFile('some/path/foo.cc', diff_cc),
146 MockFile('some/path/foo.java', diff_java),
147 MockFile('tools/metrics/histograms/histograms.xml', diff_xml),
148 ]
149 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
150 MockOutputApi())
151 self.assertEqual(0, len(warnings))
152
Vaclav Brozek8a8e2e202018-03-23 22:01:06153 def testNameMatch(self):
154 # Check that the detected histogram name is "Dummy" and not, e.g.,
155 # "Dummy\", true); // The \"correct"
156 diff_cc = ['UMA_HISTOGRAM_BOOL("Dummy", true); // The "correct" histogram']
Vaclav Brozekbdac817c2018-03-24 06:30:47157 diff_java = [
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:39158 'RecordHistogram.recordBooleanHistogram("Dummy", true);' +
159 ' // The "correct" histogram']
Vaclav Brozek8a8e2e202018-03-23 22:01:06160 diff_xml = ['<histogram name="Dummy"> </histogram>']
161 mock_input_api = MockInputApi()
162 mock_input_api.files = [
163 MockFile('some/path/foo.cc', diff_cc),
Vaclav Brozekbdac817c2018-03-24 06:30:47164 MockFile('some/path/foo.java', diff_java),
Vaclav Brozek8a8e2e202018-03-23 22:01:06165 MockFile('tools/metrics/histograms/histograms.xml', diff_xml),
166 ]
167 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
168 MockOutputApi())
169 self.assertEqual(0, len(warnings))
170
171 def testSimilarMacroNames(self):
Vaclav Brozekbdac817c2018-03-24 06:30:47172 diff_cc = ['PUMA_HISTOGRAM_COOL("Mountain Lion", 42)']
173 diff_java = [
174 'FakeRecordHistogram.recordFakeHistogram("Mountain Lion", 42)']
Vaclav Brozek8a8e2e202018-03-23 22:01:06175 mock_input_api = MockInputApi()
176 mock_input_api.files = [
177 MockFile('some/path/foo.cc', diff_cc),
Vaclav Brozekbdac817c2018-03-24 06:30:47178 MockFile('some/path/foo.java', diff_java),
Vaclav Brozek8a8e2e202018-03-23 22:01:06179 ]
180 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
181 MockOutputApi())
182 self.assertEqual(0, len(warnings))
183
Vaclav Brozek0e730cbd2018-03-24 06:18:17184 def testMultiLine(self):
185 diff_cc = ['UMA_HISTOGRAM_BOOLEAN(', ' "Multi.Line", true)']
186 diff_cc2 = ['UMA_HISTOGRAM_BOOLEAN(', ' "Multi.Line"', ' , true)']
Vaclav Brozekbdac817c2018-03-24 06:30:47187 diff_java = [
188 'RecordHistogram.recordBooleanHistogram(',
189 ' "Multi.Line", true);',
190 ]
Vaclav Brozek0e730cbd2018-03-24 06:18:17191 mock_input_api = MockInputApi()
192 mock_input_api.files = [
193 MockFile('some/path/foo.cc', diff_cc),
194 MockFile('some/path/foo2.cc', diff_cc2),
Vaclav Brozekbdac817c2018-03-24 06:30:47195 MockFile('some/path/foo.java', diff_java),
Vaclav Brozek0e730cbd2018-03-24 06:18:17196 ]
197 warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
198 MockOutputApi())
199 self.assertEqual(1, len(warnings))
200 self.assertEqual('warning', warnings[0].type)
201 self.assertTrue('foo.cc' in warnings[0].items[0])
202 self.assertTrue('foo2.cc' in warnings[0].items[1])
203
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:39204
[email protected]b8079ae4a2012-12-05 19:56:49205class BadExtensionsTest(unittest.TestCase):
206 def testBadRejFile(self):
207 mock_input_api = MockInputApi()
208 mock_input_api.files = [
209 MockFile('some/path/foo.cc', ''),
210 MockFile('some/path/foo.cc.rej', ''),
211 MockFile('some/path2/bar.h.rej', ''),
212 ]
213
214 results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
215 self.assertEqual(1, len(results))
216 self.assertEqual(2, len(results[0].items))
217 self.assertTrue('foo.cc.rej' in results[0].items[0])
218 self.assertTrue('bar.h.rej' in results[0].items[1])
219
220 def testBadOrigFile(self):
221 mock_input_api = MockInputApi()
222 mock_input_api.files = [
223 MockFile('other/path/qux.h.orig', ''),
224 MockFile('other/path/qux.h', ''),
225 MockFile('other/path/qux.cc', ''),
226 ]
227
228 results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
229 self.assertEqual(1, len(results))
230 self.assertEqual(1, len(results[0].items))
231 self.assertTrue('qux.h.orig' in results[0].items[0])
232
233 def testGoodFiles(self):
234 mock_input_api = MockInputApi()
235 mock_input_api.files = [
236 MockFile('other/path/qux.h', ''),
237 MockFile('other/path/qux.cc', ''),
238 ]
239 results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
240 self.assertEqual(0, len(results))
241
242
glidere61efad2015-02-18 17:39:43243class CheckSingletonInHeadersTest(unittest.TestCase):
244 def testSingletonInArbitraryHeader(self):
245 diff_singleton_h = ['base::subtle::AtomicWord '
olli.raula36aa8be2015-09-10 11:14:22246 'base::Singleton<Type, Traits, DifferentiatingType>::']
247 diff_foo_h = ['// base::Singleton<Foo> in comment.',
248 'friend class base::Singleton<Foo>']
oysteinec430ad42015-10-22 20:55:24249 diff_foo2_h = [' //Foo* bar = base::Singleton<Foo>::get();']
olli.raula36aa8be2015-09-10 11:14:22250 diff_bad_h = ['Foo* foo = base::Singleton<Foo>::get();']
glidere61efad2015-02-18 17:39:43251 mock_input_api = MockInputApi()
252 mock_input_api.files = [MockAffectedFile('base/memory/singleton.h',
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:39253 diff_singleton_h),
glidere61efad2015-02-18 17:39:43254 MockAffectedFile('foo.h', diff_foo_h),
oysteinec430ad42015-10-22 20:55:24255 MockAffectedFile('foo2.h', diff_foo2_h),
glidere61efad2015-02-18 17:39:43256 MockAffectedFile('bad.h', diff_bad_h)]
257 warnings = PRESUBMIT._CheckSingletonInHeaders(mock_input_api,
258 MockOutputApi())
259 self.assertEqual(1, len(warnings))
Sylvain Defresnea8b73d252018-02-28 15:45:54260 self.assertEqual(1, len(warnings[0].items))
glidere61efad2015-02-18 17:39:43261 self.assertEqual('error', warnings[0].type)
olli.raula36aa8be2015-09-10 11:14:22262 self.assertTrue('Found base::Singleton<T>' in warnings[0].message)
glidere61efad2015-02-18 17:39:43263
264 def testSingletonInCC(self):
olli.raula36aa8be2015-09-10 11:14:22265 diff_cc = ['Foo* foo = base::Singleton<Foo>::get();']
glidere61efad2015-02-18 17:39:43266 mock_input_api = MockInputApi()
267 mock_input_api.files = [MockAffectedFile('some/path/foo.cc', diff_cc)]
268 warnings = PRESUBMIT._CheckSingletonInHeaders(mock_input_api,
269 MockOutputApi())
270 self.assertEqual(0, len(warnings))
271
272
[email protected]b00342e7f2013-03-26 16:21:54273class InvalidOSMacroNamesTest(unittest.TestCase):
274 def testInvalidOSMacroNames(self):
275 lines = ['#if defined(OS_WINDOWS)',
276 ' #elif defined(OS_WINDOW)',
277 ' # if defined(OS_MACOSX) || defined(OS_CHROME)',
278 '# else // defined(OS_MAC)',
279 '#endif // defined(OS_MACOS)']
280 errors = PRESUBMIT._CheckForInvalidOSMacrosInFile(
281 MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
282 self.assertEqual(len(lines), len(errors))
283 self.assertTrue(':1 OS_WINDOWS' in errors[0])
284 self.assertTrue('(did you mean OS_WIN?)' in errors[0])
285
286 def testValidOSMacroNames(self):
287 lines = ['#if defined(%s)' % m for m in PRESUBMIT._VALID_OS_MACROS]
288 errors = PRESUBMIT._CheckForInvalidOSMacrosInFile(
289 MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
290 self.assertEqual(0, len(errors))
291
292
lliabraa35bab3932014-10-01 12:16:44293class InvalidIfDefinedMacroNamesTest(unittest.TestCase):
294 def testInvalidIfDefinedMacroNames(self):
295 lines = ['#if defined(TARGET_IPHONE_SIMULATOR)',
296 '#if !defined(TARGET_IPHONE_SIMULATOR)',
297 '#elif defined(TARGET_IPHONE_SIMULATOR)',
298 '#ifdef TARGET_IPHONE_SIMULATOR',
299 ' # ifdef TARGET_IPHONE_SIMULATOR',
300 '# if defined(VALID) || defined(TARGET_IPHONE_SIMULATOR)',
301 '# else // defined(TARGET_IPHONE_SIMULATOR)',
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:39302 '#endif // defined(TARGET_IPHONE_SIMULATOR)']
lliabraa35bab3932014-10-01 12:16:44303 errors = PRESUBMIT._CheckForInvalidIfDefinedMacrosInFile(
304 MockInputApi(), MockFile('some/path/source.mm', lines))
305 self.assertEqual(len(lines), len(errors))
306
307 def testValidIfDefinedMacroNames(self):
308 lines = ['#if defined(FOO)',
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:39309 '#ifdef BAR']
lliabraa35bab3932014-10-01 12:16:44310 errors = PRESUBMIT._CheckForInvalidIfDefinedMacrosInFile(
311 MockInputApi(), MockFile('some/path/source.cc', lines))
312 self.assertEqual(0, len(errors))
313
314
[email protected]f32e2d1e2013-07-26 21:39:08315class CheckAddedDepsHaveTetsApprovalsTest(unittest.TestCase):
Daniel Cheng4dcdb6b2017-04-13 08:30:17316
317 def calculate(self, old_include_rules, old_specific_include_rules,
318 new_include_rules, new_specific_include_rules):
319 return PRESUBMIT._CalculateAddedDeps(
320 os.path, 'include_rules = %r\nspecific_include_rules = %r' % (
321 old_include_rules, old_specific_include_rules),
322 'include_rules = %r\nspecific_include_rules = %r' % (
323 new_include_rules, new_specific_include_rules))
324
325 def testCalculateAddedDeps(self):
326 old_include_rules = [
327 '+base',
328 '-chrome',
329 '+content',
330 '-grit',
331 '-grit/",',
332 '+jni/fooblat.h',
333 '!sandbox',
[email protected]f32e2d1e2013-07-26 21:39:08334 ]
Daniel Cheng4dcdb6b2017-04-13 08:30:17335 old_specific_include_rules = {
336 'compositor\.*': {
337 '+cc',
338 },
339 }
340
341 new_include_rules = [
342 '-ash',
343 '+base',
344 '+chrome',
345 '+components',
346 '+content',
347 '+grit',
348 '+grit/generated_resources.h",',
349 '+grit/",',
350 '+jni/fooblat.h',
351 '+policy',
manzagop85e629e2017-05-09 22:11:48352 '+' + os.path.join('third_party', 'WebKit'),
Daniel Cheng4dcdb6b2017-04-13 08:30:17353 ]
354 new_specific_include_rules = {
355 'compositor\.*': {
356 '+cc',
357 },
358 'widget\.*': {
359 '+gpu',
360 },
361 }
362
[email protected]f32e2d1e2013-07-26 21:39:08363 expected = set([
manzagop85e629e2017-05-09 22:11:48364 os.path.join('chrome', 'DEPS'),
365 os.path.join('gpu', 'DEPS'),
366 os.path.join('components', 'DEPS'),
367 os.path.join('policy', 'DEPS'),
368 os.path.join('third_party', 'WebKit', 'DEPS'),
[email protected]f32e2d1e2013-07-26 21:39:08369 ])
Daniel Cheng4dcdb6b2017-04-13 08:30:17370 self.assertEqual(
371 expected,
372 self.calculate(old_include_rules, old_specific_include_rules,
373 new_include_rules, new_specific_include_rules))
374
375 def testCalculateAddedDepsIgnoresPermutations(self):
376 old_include_rules = [
377 '+base',
378 '+chrome',
379 ]
380 new_include_rules = [
381 '+chrome',
382 '+base',
383 ]
384 self.assertEqual(set(),
385 self.calculate(old_include_rules, {}, new_include_rules,
386 {}))
[email protected]f32e2d1e2013-07-26 21:39:08387
388
[email protected]99171a92014-06-03 08:44:47389class JSONParsingTest(unittest.TestCase):
390 def testSuccess(self):
391 input_api = MockInputApi()
392 filename = 'valid_json.json'
393 contents = ['// This is a comment.',
394 '{',
395 ' "key1": ["value1", "value2"],',
396 ' "key2": 3 // This is an inline comment.',
397 '}'
398 ]
399 input_api.files = [MockFile(filename, contents)]
400 self.assertEqual(None,
401 PRESUBMIT._GetJSONParseError(input_api, filename))
402
403 def testFailure(self):
404 input_api = MockInputApi()
405 test_data = [
406 ('invalid_json_1.json',
407 ['{ x }'],
[email protected]a3343272014-06-17 11:41:53408 'Expecting property name:'),
[email protected]99171a92014-06-03 08:44:47409 ('invalid_json_2.json',
410 ['// Hello world!',
411 '{ "hello": "world }'],
[email protected]a3343272014-06-17 11:41:53412 'Unterminated string starting at:'),
[email protected]99171a92014-06-03 08:44:47413 ('invalid_json_3.json',
414 ['{ "a": "b", "c": "d", }'],
[email protected]a3343272014-06-17 11:41:53415 'Expecting property name:'),
[email protected]99171a92014-06-03 08:44:47416 ('invalid_json_4.json',
417 ['{ "a": "b" "c": "d" }'],
[email protected]a3343272014-06-17 11:41:53418 'Expecting , delimiter:'),
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:39419 ]
[email protected]99171a92014-06-03 08:44:47420
421 input_api.files = [MockFile(filename, contents)
422 for (filename, contents, _) in test_data]
423
424 for (filename, _, expected_error) in test_data:
425 actual_error = PRESUBMIT._GetJSONParseError(input_api, filename)
[email protected]a3343272014-06-17 11:41:53426 self.assertTrue(expected_error in str(actual_error),
427 "'%s' not found in '%s'" % (expected_error, actual_error))
[email protected]99171a92014-06-03 08:44:47428
429 def testNoEatComments(self):
430 input_api = MockInputApi()
431 file_with_comments = 'file_with_comments.json'
432 contents_with_comments = ['// This is a comment.',
433 '{',
434 ' "key1": ["value1", "value2"],',
435 ' "key2": 3 // This is an inline comment.',
436 '}'
437 ]
438 file_without_comments = 'file_without_comments.json'
439 contents_without_comments = ['{',
440 ' "key1": ["value1", "value2"],',
441 ' "key2": 3',
442 '}'
443 ]
444 input_api.files = [MockFile(file_with_comments, contents_with_comments),
445 MockFile(file_without_comments,
446 contents_without_comments)]
447
448 self.assertEqual('No JSON object could be decoded',
449 str(PRESUBMIT._GetJSONParseError(input_api,
450 file_with_comments,
451 eat_comments=False)))
452 self.assertEqual(None,
453 PRESUBMIT._GetJSONParseError(input_api,
454 file_without_comments,
455 eat_comments=False))
456
457
458class IDLParsingTest(unittest.TestCase):
459 def testSuccess(self):
460 input_api = MockInputApi()
461 filename = 'valid_idl_basics.idl'
462 contents = ['// Tests a valid IDL file.',
463 'namespace idl_basics {',
464 ' enum EnumType {',
465 ' name1,',
466 ' name2',
467 ' };',
468 '',
469 ' dictionary MyType1 {',
470 ' DOMString a;',
471 ' };',
472 '',
473 ' callback Callback1 = void();',
474 ' callback Callback2 = void(long x);',
475 ' callback Callback3 = void(MyType1 arg);',
476 ' callback Callback4 = void(EnumType type);',
477 '',
478 ' interface Functions {',
479 ' static void function1();',
480 ' static void function2(long x);',
481 ' static void function3(MyType1 arg);',
482 ' static void function4(Callback1 cb);',
483 ' static void function5(Callback2 cb);',
484 ' static void function6(Callback3 cb);',
485 ' static void function7(Callback4 cb);',
486 ' };',
487 '',
488 ' interface Events {',
489 ' static void onFoo1();',
490 ' static void onFoo2(long x);',
491 ' static void onFoo2(MyType1 arg);',
492 ' static void onFoo3(EnumType type);',
493 ' };',
494 '};'
495 ]
496 input_api.files = [MockFile(filename, contents)]
497 self.assertEqual(None,
498 PRESUBMIT._GetIDLParseError(input_api, filename))
499
500 def testFailure(self):
501 input_api = MockInputApi()
502 test_data = [
503 ('invalid_idl_1.idl',
504 ['//',
505 'namespace test {',
506 ' dictionary {',
507 ' DOMString s;',
508 ' };',
509 '};'],
510 'Unexpected "{" after keyword "dictionary".\n'),
511 # TODO(yoz): Disabled because it causes the IDL parser to hang.
512 # See crbug.com/363830.
513 # ('invalid_idl_2.idl',
514 # (['namespace test {',
515 # ' dictionary MissingSemicolon {',
516 # ' DOMString a',
517 # ' DOMString b;',
518 # ' };',
519 # '};'],
520 # 'Unexpected symbol DOMString after symbol a.'),
521 ('invalid_idl_3.idl',
522 ['//',
523 'namespace test {',
524 ' enum MissingComma {',
525 ' name1',
526 ' name2',
527 ' };',
528 '};'],
529 'Unexpected symbol name2 after symbol name1.'),
530 ('invalid_idl_4.idl',
531 ['//',
532 'namespace test {',
533 ' enum TrailingComma {',
534 ' name1,',
535 ' name2,',
536 ' };',
537 '};'],
538 'Trailing comma in block.'),
539 ('invalid_idl_5.idl',
540 ['//',
541 'namespace test {',
542 ' callback Callback1 = void(;',
543 '};'],
544 'Unexpected ";" after "(".'),
545 ('invalid_idl_6.idl',
546 ['//',
547 'namespace test {',
548 ' callback Callback1 = void(long );',
549 '};'],
550 'Unexpected ")" after symbol long.'),
551 ('invalid_idl_7.idl',
552 ['//',
553 'namespace test {',
554 ' interace Events {',
555 ' static void onFoo1();',
556 ' };',
557 '};'],
558 'Unexpected symbol Events after symbol interace.'),
559 ('invalid_idl_8.idl',
560 ['//',
561 'namespace test {',
562 ' interface NotEvent {',
563 ' static void onFoo1();',
564 ' };',
565 '};'],
566 'Did not process Interface Interface(NotEvent)'),
567 ('invalid_idl_9.idl',
568 ['//',
569 'namespace test {',
570 ' interface {',
571 ' static void function1();',
572 ' };',
573 '};'],
574 'Interface missing name.'),
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:39575 ]
[email protected]99171a92014-06-03 08:44:47576
577 input_api.files = [MockFile(filename, contents)
578 for (filename, contents, _) in test_data]
579
580 for (filename, _, expected_error) in test_data:
581 actual_error = PRESUBMIT._GetIDLParseError(input_api, filename)
582 self.assertTrue(expected_error in str(actual_error),
583 "'%s' not found in '%s'" % (expected_error, actual_error))
584
585
[email protected]0bb112362014-07-26 04:38:32586class TryServerMasterTest(unittest.TestCase):
587 def testTryServerMasters(self):
588 bots = {
tandriie5587792016-07-14 00:34:50589 'master.tryserver.chromium.android': [
jbudorick3ae7a772016-05-20 02:36:04590 'android_archive_rel_ng',
591 'android_arm64_dbg_recipe',
592 'android_blink_rel',
jbudorick3ae7a772016-05-20 02:36:04593 'android_clang_dbg_recipe',
594 'android_compile_dbg',
jbudorick3ae7a772016-05-20 02:36:04595 'android_compile_x64_dbg',
596 'android_compile_x86_dbg',
597 'android_coverage',
598 'android_cronet_tester'
599 'android_swarming_rel',
600 'cast_shell_android',
601 'linux_android_dbg_ng',
602 'linux_android_rel_ng',
603 ],
tandriie5587792016-07-14 00:34:50604 'master.tryserver.chromium.mac': [
[email protected]0bb112362014-07-26 04:38:32605 'ios_dbg_simulator',
606 'ios_rel_device',
607 'ios_rel_device_ninja',
608 'mac_asan',
609 'mac_asan_64',
610 'mac_chromium_compile_dbg',
611 'mac_chromium_compile_rel',
612 'mac_chromium_dbg',
613 'mac_chromium_rel',
[email protected]0bb112362014-07-26 04:38:32614 'mac_nacl_sdk',
615 'mac_nacl_sdk_build',
616 'mac_rel_naclmore',
[email protected]0bb112362014-07-26 04:38:32617 'mac_x64_rel',
618 'mac_xcodebuild',
619 ],
tandriie5587792016-07-14 00:34:50620 'master.tryserver.chromium.linux': [
[email protected]0bb112362014-07-26 04:38:32621 'chromium_presubmit',
622 'linux_arm_cross_compile',
623 'linux_arm_tester',
[email protected]0bb112362014-07-26 04:38:32624 'linux_chromeos_asan',
625 'linux_chromeos_browser_asan',
626 'linux_chromeos_valgrind',
[email protected]0bb112362014-07-26 04:38:32627 'linux_chromium_chromeos_dbg',
628 'linux_chromium_chromeos_rel',
[email protected]0bb112362014-07-26 04:38:32629 'linux_chromium_compile_dbg',
630 'linux_chromium_compile_rel',
631 'linux_chromium_dbg',
632 'linux_chromium_gn_dbg',
633 'linux_chromium_gn_rel',
634 'linux_chromium_rel',
[email protected]0bb112362014-07-26 04:38:32635 'linux_chromium_trusty32_dbg',
636 'linux_chromium_trusty32_rel',
637 'linux_chromium_trusty_dbg',
638 'linux_chromium_trusty_rel',
639 'linux_clang_tsan',
640 'linux_ecs_ozone',
641 'linux_layout',
642 'linux_layout_asan',
643 'linux_layout_rel',
644 'linux_layout_rel_32',
645 'linux_nacl_sdk',
646 'linux_nacl_sdk_bionic',
647 'linux_nacl_sdk_bionic_build',
648 'linux_nacl_sdk_build',
649 'linux_redux',
650 'linux_rel_naclmore',
651 'linux_rel_precise32',
652 'linux_valgrind',
653 'tools_build_presubmit',
654 ],
tandriie5587792016-07-14 00:34:50655 'master.tryserver.chromium.win': [
[email protected]0bb112362014-07-26 04:38:32656 'win8_aura',
657 'win8_chromium_dbg',
658 'win8_chromium_rel',
659 'win_chromium_compile_dbg',
660 'win_chromium_compile_rel',
661 'win_chromium_dbg',
662 'win_chromium_rel',
663 'win_chromium_rel',
[email protected]0bb112362014-07-26 04:38:32664 'win_chromium_x64_dbg',
665 'win_chromium_x64_rel',
[email protected]0bb112362014-07-26 04:38:32666 'win_nacl_sdk',
667 'win_nacl_sdk_build',
668 'win_rel_naclmore',
669 ],
670 }
671 for master, bots in bots.iteritems():
672 for bot in bots:
673 self.assertEqual(master, PRESUBMIT.GetTryServerMasterForBot(bot),
674 'bot=%s: expected %s, computed %s' % (
675 bot, master, PRESUBMIT.GetTryServerMasterForBot(bot)))
676
677
davileene0426252015-03-02 21:10:41678class UserMetricsActionTest(unittest.TestCase):
679 def testUserMetricsActionInActions(self):
680 input_api = MockInputApi()
681 file_with_user_action = 'file_with_user_action.cc'
682 contents_with_user_action = [
683 'base::UserMetricsAction("AboutChrome")'
684 ]
685
686 input_api.files = [MockFile(file_with_user_action,
687 contents_with_user_action)]
688
689 self.assertEqual(
690 [], PRESUBMIT._CheckUserActionUpdate(input_api, MockOutputApi()))
691
davileene0426252015-03-02 21:10:41692 def testUserMetricsActionNotAddedToActions(self):
693 input_api = MockInputApi()
694 file_with_user_action = 'file_with_user_action.cc'
695 contents_with_user_action = [
696 'base::UserMetricsAction("NotInActionsXml")'
697 ]
698
699 input_api.files = [MockFile(file_with_user_action,
700 contents_with_user_action)]
701
702 output = PRESUBMIT._CheckUserActionUpdate(input_api, MockOutputApi())
703 self.assertEqual(
704 ('File %s line %d: %s is missing in '
705 'tools/metrics/actions/actions.xml. Please run '
706 'tools/metrics/actions/extract_actions.py to update.'
707 % (file_with_user_action, 1, 'NotInActionsXml')),
708 output[0].message)
709
710
agrievef32bcc72016-04-04 14:57:40711class PydepsNeedsUpdatingTest(unittest.TestCase):
712
713 class MockSubprocess(object):
714 CalledProcessError = subprocess.CalledProcessError
715
716 def setUp(self):
717 mock_all_pydeps = ['A.pydeps', 'B.pydeps']
718 self.old_ALL_PYDEPS_FILES = PRESUBMIT._ALL_PYDEPS_FILES
719 PRESUBMIT._ALL_PYDEPS_FILES = mock_all_pydeps
720 self.mock_input_api = MockInputApi()
721 self.mock_output_api = MockOutputApi()
722 self.mock_input_api.subprocess = PydepsNeedsUpdatingTest.MockSubprocess()
723 self.checker = PRESUBMIT.PydepsChecker(self.mock_input_api, mock_all_pydeps)
724 self.checker._file_cache = {
725 'A.pydeps': '# Generated by:\n# CMD A\nA.py\nC.py\n',
726 'B.pydeps': '# Generated by:\n# CMD B\nB.py\nC.py\n',
727 }
728
729 def tearDown(self):
730 PRESUBMIT._ALL_PYDEPS_FILES = self.old_ALL_PYDEPS_FILES
731
732 def _RunCheck(self):
733 return PRESUBMIT._CheckPydepsNeedsUpdating(self.mock_input_api,
734 self.mock_output_api,
735 checker_for_tests=self.checker)
736
737 def testAddedPydep(self):
pastarmovj89f7ee12016-09-20 14:58:13738 # PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
739 if self.mock_input_api.platform != 'linux2':
740 return []
741
agrievef32bcc72016-04-04 14:57:40742 self.mock_input_api.files = [
743 MockAffectedFile('new.pydeps', [], action='A'),
744 ]
745
Zhiling Huang45cabf32018-03-10 00:50:03746 self.mock_input_api.CreateMockFileInPath(
747 [x.LocalPath() for x in self.mock_input_api.AffectedFiles(
748 include_deletes=True)])
agrievef32bcc72016-04-04 14:57:40749 results = self._RunCheck()
750 self.assertEqual(1, len(results))
751 self.assertTrue('PYDEPS_FILES' in str(results[0]))
752
Zhiling Huang45cabf32018-03-10 00:50:03753 def testPydepNotInSrc(self):
754 self.mock_input_api.files = [
755 MockAffectedFile('new.pydeps', [], action='A'),
756 ]
757 self.mock_input_api.CreateMockFileInPath([])
758 results = self._RunCheck()
759 self.assertEqual(0, len(results))
760
agrievef32bcc72016-04-04 14:57:40761 def testRemovedPydep(self):
pastarmovj89f7ee12016-09-20 14:58:13762 # PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
763 if self.mock_input_api.platform != 'linux2':
764 return []
765
agrievef32bcc72016-04-04 14:57:40766 self.mock_input_api.files = [
767 MockAffectedFile(PRESUBMIT._ALL_PYDEPS_FILES[0], [], action='D'),
768 ]
Zhiling Huang45cabf32018-03-10 00:50:03769 self.mock_input_api.CreateMockFileInPath(
770 [x.LocalPath() for x in self.mock_input_api.AffectedFiles(
771 include_deletes=True)])
agrievef32bcc72016-04-04 14:57:40772 results = self._RunCheck()
773 self.assertEqual(1, len(results))
774 self.assertTrue('PYDEPS_FILES' in str(results[0]))
775
776 def testRandomPyIgnored(self):
pastarmovj89f7ee12016-09-20 14:58:13777 # PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
778 if self.mock_input_api.platform != 'linux2':
779 return []
780
agrievef32bcc72016-04-04 14:57:40781 self.mock_input_api.files = [
782 MockAffectedFile('random.py', []),
783 ]
784
785 results = self._RunCheck()
786 self.assertEqual(0, len(results), 'Unexpected results: %r' % results)
787
788 def testRelevantPyNoChange(self):
pastarmovj89f7ee12016-09-20 14:58:13789 # PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
790 if self.mock_input_api.platform != 'linux2':
791 return []
792
agrievef32bcc72016-04-04 14:57:40793 self.mock_input_api.files = [
794 MockAffectedFile('A.py', []),
795 ]
796
John Budorickab2fa102017-10-06 16:59:49797 def mock_check_output(cmd, shell=False, env=None):
agrievef32bcc72016-04-04 14:57:40798 self.assertEqual('CMD A --output ""', cmd)
799 return self.checker._file_cache['A.pydeps']
800
801 self.mock_input_api.subprocess.check_output = mock_check_output
802
803 results = self._RunCheck()
804 self.assertEqual(0, len(results), 'Unexpected results: %r' % results)
805
806 def testRelevantPyOneChange(self):
pastarmovj89f7ee12016-09-20 14:58:13807 # PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
808 if self.mock_input_api.platform != 'linux2':
809 return []
810
agrievef32bcc72016-04-04 14:57:40811 self.mock_input_api.files = [
812 MockAffectedFile('A.py', []),
813 ]
814
John Budorickab2fa102017-10-06 16:59:49815 def mock_check_output(cmd, shell=False, env=None):
agrievef32bcc72016-04-04 14:57:40816 self.assertEqual('CMD A --output ""', cmd)
817 return 'changed data'
818
819 self.mock_input_api.subprocess.check_output = mock_check_output
820
821 results = self._RunCheck()
822 self.assertEqual(1, len(results))
823 self.assertTrue('File is stale' in str(results[0]))
824
825 def testRelevantPyTwoChanges(self):
pastarmovj89f7ee12016-09-20 14:58:13826 # PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
827 if self.mock_input_api.platform != 'linux2':
828 return []
829
agrievef32bcc72016-04-04 14:57:40830 self.mock_input_api.files = [
831 MockAffectedFile('C.py', []),
832 ]
833
John Budorickab2fa102017-10-06 16:59:49834 def mock_check_output(cmd, shell=False, env=None):
agrievef32bcc72016-04-04 14:57:40835 return 'changed data'
836
837 self.mock_input_api.subprocess.check_output = mock_check_output
838
839 results = self._RunCheck()
840 self.assertEqual(2, len(results))
841 self.assertTrue('File is stale' in str(results[0]))
842 self.assertTrue('File is stale' in str(results[1]))
843
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:39844
Daniel Bratell8ba52722018-03-02 16:06:14845class IncludeGuardTest(unittest.TestCase):
846 def testIncludeGuardChecks(self):
847 mock_input_api = MockInputApi()
848 mock_output_api = MockOutputApi()
849 mock_input_api.files = [
850 MockAffectedFile('content/browser/thing/foo.h', [
851 '// Comment',
852 '#ifndef CONTENT_BROWSER_THING_FOO_H_',
853 '#define CONTENT_BROWSER_THING_FOO_H_',
854 'struct McBoatFace;',
855 '#endif // CONTENT_BROWSER_THING_FOO_H_',
856 ]),
857 MockAffectedFile('content/browser/thing/bar.h', [
858 '#ifndef CONTENT_BROWSER_THING_BAR_H_',
859 '#define CONTENT_BROWSER_THING_BAR_H_',
860 'namespace content {',
861 '#endif // CONTENT_BROWSER_THING_BAR_H_',
862 '} // namespace content',
863 ]),
864 MockAffectedFile('content/browser/test1.h', [
865 'namespace content {',
866 '} // namespace content',
867 ]),
868 MockAffectedFile('content\\browser\\win.h', [
869 '#ifndef CONTENT_BROWSER_WIN_H_',
870 '#define CONTENT_BROWSER_WIN_H_',
871 'struct McBoatFace;',
872 '#endif // CONTENT_BROWSER_WIN_H_',
873 ]),
874 MockAffectedFile('content/browser/test2.h', [
875 '// Comment',
876 '#ifndef CONTENT_BROWSER_TEST2_H_',
877 'struct McBoatFace;',
878 '#endif // CONTENT_BROWSER_TEST2_H_',
879 ]),
880 MockAffectedFile('content/browser/internal.h', [
881 '// Comment',
882 '#ifndef CONTENT_BROWSER_INTERNAL_H_',
883 '#define CONTENT_BROWSER_INTERNAL_H_',
884 '// Comment',
885 '#ifndef INTERNAL_CONTENT_BROWSER_INTERNAL_H_',
886 '#define INTERNAL_CONTENT_BROWSER_INTERNAL_H_',
887 'namespace internal {',
888 '} // namespace internal',
889 '#endif // INTERNAL_CONTENT_BROWSER_THING_BAR_H_',
890 'namespace content {',
891 '} // namespace content',
892 '#endif // CONTENT_BROWSER_THING_BAR_H_',
893 ]),
894 MockAffectedFile('content/browser/thing/foo.cc', [
895 '// This is a non-header.',
896 ]),
897 MockAffectedFile('content/browser/disabled.h', [
898 '// no-include-guard-because-multiply-included',
899 'struct McBoatFace;',
900 ]),
901 # New files don't allow misspelled include guards.
902 MockAffectedFile('content/browser/spleling.h', [
903 '#ifndef CONTENT_BROWSER_SPLLEING_H_',
904 '#define CONTENT_BROWSER_SPLLEING_H_',
905 'struct McBoatFace;',
906 '#endif // CONTENT_BROWSER_SPLLEING_H_',
907 ]),
Olivier Robinbba137492018-07-30 11:31:34908 # New files don't allow + in include guards.
909 MockAffectedFile('content/browser/foo+bar.h', [
910 '#ifndef CONTENT_BROWSER_FOO+BAR_H_',
911 '#define CONTENT_BROWSER_FOO+BAR_H_',
912 'struct McBoatFace;',
913 '#endif // CONTENT_BROWSER_FOO+BAR_H_',
914 ]),
Daniel Bratell8ba52722018-03-02 16:06:14915 # Old files allow misspelled include guards (for now).
916 MockAffectedFile('chrome/old.h', [
917 '// New contents',
918 '#ifndef CHROME_ODL_H_',
919 '#define CHROME_ODL_H_',
920 '#endif // CHROME_ODL_H_',
921 ], [
922 '// Old contents',
923 '#ifndef CHROME_ODL_H_',
924 '#define CHROME_ODL_H_',
925 '#endif // CHROME_ODL_H_',
926 ]),
927 # Using a Blink style include guard outside Blink is wrong.
928 MockAffectedFile('content/NotInBlink.h', [
929 '#ifndef NotInBlink_h',
930 '#define NotInBlink_h',
931 'struct McBoatFace;',
932 '#endif // NotInBlink_h',
933 ]),
Daniel Bratell39b5b062018-05-16 18:09:57934 # Using a Blink style include guard in Blink is no longer ok.
935 MockAffectedFile('third_party/blink/InBlink.h', [
Daniel Bratell8ba52722018-03-02 16:06:14936 '#ifndef InBlink_h',
937 '#define InBlink_h',
938 'struct McBoatFace;',
939 '#endif // InBlink_h',
940 ]),
941 # Using a bad include guard in Blink is not ok.
Daniel Bratell39b5b062018-05-16 18:09:57942 MockAffectedFile('third_party/blink/AlsoInBlink.h', [
Daniel Bratell8ba52722018-03-02 16:06:14943 '#ifndef WrongInBlink_h',
944 '#define WrongInBlink_h',
945 'struct McBoatFace;',
946 '#endif // WrongInBlink_h',
947 ]),
Daniel Bratell39b5b062018-05-16 18:09:57948 # Using a bad include guard in Blink is not accepted even if
949 # it's an old file.
950 MockAffectedFile('third_party/blink/StillInBlink.h', [
Daniel Bratell8ba52722018-03-02 16:06:14951 '// New contents',
952 '#ifndef AcceptedInBlink_h',
953 '#define AcceptedInBlink_h',
954 'struct McBoatFace;',
955 '#endif // AcceptedInBlink_h',
956 ], [
957 '// Old contents',
958 '#ifndef AcceptedInBlink_h',
959 '#define AcceptedInBlink_h',
960 'struct McBoatFace;',
961 '#endif // AcceptedInBlink_h',
962 ]),
Daniel Bratell39b5b062018-05-16 18:09:57963 # Using a non-Chromium include guard in third_party
964 # (outside blink) is accepted.
965 MockAffectedFile('third_party/foo/some_file.h', [
966 '#ifndef REQUIRED_RPCNDR_H_',
967 '#define REQUIRED_RPCNDR_H_',
968 'struct SomeFileFoo;',
969 '#endif // REQUIRED_RPCNDR_H_',
970 ]),
Daniel Bratell8ba52722018-03-02 16:06:14971 ]
972 msgs = PRESUBMIT._CheckForIncludeGuards(
973 mock_input_api, mock_output_api)
Olivier Robinbba137492018-07-30 11:31:34974 expected_fail_count = 8
Daniel Bratell8ba52722018-03-02 16:06:14975 self.assertEqual(expected_fail_count, len(msgs),
976 'Expected %d items, found %d: %s'
977 % (expected_fail_count, len(msgs), msgs))
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:39978 self.assertEqual(msgs[0].items, ['content/browser/thing/bar.h'])
Daniel Bratell8ba52722018-03-02 16:06:14979 self.assertEqual(msgs[0].message,
980 'Include guard CONTENT_BROWSER_THING_BAR_H_ '
981 'not covering the whole file')
982
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:39983 self.assertEqual(msgs[1].items, ['content/browser/test1.h'])
Daniel Bratell8ba52722018-03-02 16:06:14984 self.assertEqual(msgs[1].message,
985 'Missing include guard CONTENT_BROWSER_TEST1_H_')
986
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:39987 self.assertEqual(msgs[2].items, ['content/browser/test2.h:3'])
Daniel Bratell8ba52722018-03-02 16:06:14988 self.assertEqual(msgs[2].message,
989 'Missing "#define CONTENT_BROWSER_TEST2_H_" for '
990 'include guard')
991
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:39992 self.assertEqual(msgs[3].items, ['content/browser/spleling.h:1'])
Daniel Bratell8ba52722018-03-02 16:06:14993 self.assertEqual(msgs[3].message,
994 'Header using the wrong include guard name '
995 'CONTENT_BROWSER_SPLLEING_H_')
996
Olivier Robinbba137492018-07-30 11:31:34997 self.assertEqual(msgs[4].items, ['content/browser/foo+bar.h'])
Daniel Bratell8ba52722018-03-02 16:06:14998 self.assertEqual(msgs[4].message,
Olivier Robinbba137492018-07-30 11:31:34999 'Missing include guard CONTENT_BROWSER_FOO_BAR_H_')
1000
1001 self.assertEqual(msgs[5].items, ['content/NotInBlink.h:1'])
1002 self.assertEqual(msgs[5].message,
Daniel Bratell8ba52722018-03-02 16:06:141003 'Header using the wrong include guard name '
1004 'NotInBlink_h')
1005
Olivier Robinbba137492018-07-30 11:31:341006 self.assertEqual(msgs[6].items, ['third_party/blink/InBlink.h:1'])
1007 self.assertEqual(msgs[6].message,
Daniel Bratell8ba52722018-03-02 16:06:141008 'Header using the wrong include guard name '
Daniel Bratell39b5b062018-05-16 18:09:571009 'InBlink_h')
1010
Olivier Robinbba137492018-07-30 11:31:341011 self.assertEqual(msgs[7].items, ['third_party/blink/AlsoInBlink.h:1'])
1012 self.assertEqual(msgs[7].message,
Daniel Bratell39b5b062018-05-16 18:09:571013 'Header using the wrong include guard name '
Daniel Bratell8ba52722018-03-02 16:06:141014 'WrongInBlink_h')
1015
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:391016
yolandyan45001472016-12-21 21:12:421017class AndroidDeprecatedTestAnnotationTest(unittest.TestCase):
1018 def testCheckAndroidTestAnnotationUsage(self):
1019 mock_input_api = MockInputApi()
1020 mock_output_api = MockOutputApi()
1021
1022 mock_input_api.files = [
1023 MockAffectedFile('LalaLand.java', [
1024 'random stuff'
1025 ]),
1026 MockAffectedFile('CorrectUsage.java', [
1027 'import android.support.test.filters.LargeTest;',
1028 'import android.support.test.filters.MediumTest;',
1029 'import android.support.test.filters.SmallTest;',
1030 ]),
1031 MockAffectedFile('UsedDeprecatedLargeTestAnnotation.java', [
1032 'import android.test.suitebuilder.annotation.LargeTest;',
1033 ]),
1034 MockAffectedFile('UsedDeprecatedMediumTestAnnotation.java', [
1035 'import android.test.suitebuilder.annotation.MediumTest;',
1036 ]),
1037 MockAffectedFile('UsedDeprecatedSmallTestAnnotation.java', [
1038 'import android.test.suitebuilder.annotation.SmallTest;',
1039 ]),
1040 MockAffectedFile('UsedDeprecatedSmokeAnnotation.java', [
1041 'import android.test.suitebuilder.annotation.Smoke;',
1042 ])
1043 ]
1044 msgs = PRESUBMIT._CheckAndroidTestAnnotationUsage(
1045 mock_input_api, mock_output_api)
1046 self.assertEqual(1, len(msgs),
1047 'Expected %d items, found %d: %s'
1048 % (1, len(msgs), msgs))
1049 self.assertEqual(4, len(msgs[0].items),
1050 'Expected %d items, found %d: %s'
1051 % (4, len(msgs[0].items), msgs[0].items))
1052 self.assertTrue('UsedDeprecatedLargeTestAnnotation.java:1' in msgs[0].items,
1053 'UsedDeprecatedLargeTestAnnotation not found in errors')
1054 self.assertTrue('UsedDeprecatedMediumTestAnnotation.java:1'
1055 in msgs[0].items,
1056 'UsedDeprecatedMediumTestAnnotation not found in errors')
1057 self.assertTrue('UsedDeprecatedSmallTestAnnotation.java:1' in msgs[0].items,
1058 'UsedDeprecatedSmallTestAnnotation not found in errors')
1059 self.assertTrue('UsedDeprecatedSmokeAnnotation.java:1' in msgs[0].items,
1060 'UsedDeprecatedSmokeAnnotation not found in errors')
1061
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:391062
Yoland Yanb92fa522017-08-28 17:37:061063class AndroidDeprecatedJUnitFrameworkTest(unittest.TestCase):
Wei-Yin Chen (陳威尹)032f1ac2018-07-27 21:21:271064 def testCheckAndroidTestJUnitFramework(self):
Yoland Yanb92fa522017-08-28 17:37:061065 mock_input_api = MockInputApi()
1066 mock_output_api = MockOutputApi()
yolandyan45001472016-12-21 21:12:421067
Yoland Yanb92fa522017-08-28 17:37:061068 mock_input_api.files = [
1069 MockAffectedFile('LalaLand.java', [
1070 'random stuff'
1071 ]),
1072 MockAffectedFile('CorrectUsage.java', [
1073 'import org.junit.ABC',
1074 'import org.junit.XYZ;',
1075 ]),
1076 MockAffectedFile('UsedDeprecatedJUnit.java', [
1077 'import junit.framework.*;',
1078 ]),
1079 MockAffectedFile('UsedDeprecatedJUnitAssert.java', [
1080 'import junit.framework.Assert;',
1081 ]),
1082 ]
1083 msgs = PRESUBMIT._CheckAndroidTestJUnitFrameworkImport(
1084 mock_input_api, mock_output_api)
1085 self.assertEqual(1, len(msgs),
1086 'Expected %d items, found %d: %s'
1087 % (1, len(msgs), msgs))
1088 self.assertEqual(2, len(msgs[0].items),
1089 'Expected %d items, found %d: %s'
1090 % (2, len(msgs[0].items), msgs[0].items))
1091 self.assertTrue('UsedDeprecatedJUnit.java:1' in msgs[0].items,
1092 'UsedDeprecatedJUnit.java not found in errors')
1093 self.assertTrue('UsedDeprecatedJUnitAssert.java:1'
1094 in msgs[0].items,
1095 'UsedDeprecatedJUnitAssert not found in errors')
1096
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:391097
Wei-Yin Chen (陳威尹)032f1ac2018-07-27 21:21:271098class AndroidJUnitBaseClassTest(unittest.TestCase):
1099 def testCheckAndroidTestJUnitBaseClass(self):
Yoland Yanb92fa522017-08-28 17:37:061100 mock_input_api = MockInputApi()
1101 mock_output_api = MockOutputApi()
1102
1103 mock_input_api.files = [
1104 MockAffectedFile('LalaLand.java', [
1105 'random stuff'
1106 ]),
1107 MockAffectedFile('CorrectTest.java', [
1108 '@RunWith(ABC.class);'
1109 'public class CorrectTest {',
1110 '}',
1111 ]),
1112 MockAffectedFile('HistoricallyIncorrectTest.java', [
1113 'public class Test extends BaseCaseA {',
1114 '}',
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:391115 ], old_contents=[
Yoland Yanb92fa522017-08-28 17:37:061116 'public class Test extends BaseCaseB {',
1117 '}',
1118 ]),
1119 MockAffectedFile('CorrectTestWithInterface.java', [
1120 '@RunWith(ABC.class);'
1121 'public class CorrectTest implement Interface {',
1122 '}',
1123 ]),
1124 MockAffectedFile('IncorrectTest.java', [
1125 'public class IncorrectTest extends TestCase {',
1126 '}',
1127 ]),
Vaclav Brozekf01ed502018-03-16 19:38:241128 MockAffectedFile('IncorrectWithInterfaceTest.java', [
Yoland Yanb92fa522017-08-28 17:37:061129 'public class Test implements X extends BaseClass {',
1130 '}',
1131 ]),
Vaclav Brozekf01ed502018-03-16 19:38:241132 MockAffectedFile('IncorrectMultiLineTest.java', [
Yoland Yanb92fa522017-08-28 17:37:061133 'public class Test implements X, Y, Z',
1134 ' extends TestBase {',
1135 '}',
1136 ]),
1137 ]
1138 msgs = PRESUBMIT._CheckAndroidTestJUnitInheritance(
1139 mock_input_api, mock_output_api)
1140 self.assertEqual(1, len(msgs),
1141 'Expected %d items, found %d: %s'
1142 % (1, len(msgs), msgs))
1143 self.assertEqual(3, len(msgs[0].items),
1144 'Expected %d items, found %d: %s'
1145 % (3, len(msgs[0].items), msgs[0].items))
1146 self.assertTrue('IncorrectTest.java:1' in msgs[0].items,
1147 'IncorrectTest not found in errors')
Vaclav Brozekf01ed502018-03-16 19:38:241148 self.assertTrue('IncorrectWithInterfaceTest.java:1'
Yoland Yanb92fa522017-08-28 17:37:061149 in msgs[0].items,
Vaclav Brozekf01ed502018-03-16 19:38:241150 'IncorrectWithInterfaceTest not found in errors')
1151 self.assertTrue('IncorrectMultiLineTest.java:2' in msgs[0].items,
1152 'IncorrectMultiLineTest not found in errors')
yolandyan45001472016-12-21 21:12:421153
Jinsong Fan91ebbbd2019-04-16 14:57:171154class AndroidDebuggableBuildTest(unittest.TestCase):
1155
1156 def testCheckAndroidDebuggableBuild(self):
1157 mock_input_api = MockInputApi()
1158 mock_output_api = MockOutputApi()
1159
1160 mock_input_api.files = [
1161 MockAffectedFile('RandomStuff.java', [
1162 'random stuff'
1163 ]),
1164 MockAffectedFile('CorrectUsage.java', [
1165 'import org.chromium.base.BuildInfo;',
1166 'some random stuff',
1167 'boolean isOsDebuggable = BuildInfo.isDebugAndroid();',
1168 ]),
1169 MockAffectedFile('JustCheckUserdebugBuild.java', [
1170 'import android.os.Build;',
1171 'some random stuff',
1172 'boolean isOsDebuggable = Build.TYPE.equals("userdebug")',
1173 ]),
1174 MockAffectedFile('JustCheckEngineeringBuild.java', [
1175 'import android.os.Build;',
1176 'some random stuff',
1177 'boolean isOsDebuggable = "eng".equals(Build.TYPE)',
1178 ]),
1179 MockAffectedFile('UsedBuildType.java', [
1180 'import android.os.Build;',
1181 'some random stuff',
1182 'boolean isOsDebuggable = Build.TYPE.equals("userdebug")'
1183 '|| "eng".equals(Build.TYPE)',
1184 ]),
1185 MockAffectedFile('UsedExplicitBuildType.java', [
1186 'some random stuff',
1187 'boolean isOsDebuggable = android.os.Build.TYPE.equals("userdebug")'
1188 '|| "eng".equals(android.os.Build.TYPE)',
1189 ]),
1190 ]
1191
1192 msgs = PRESUBMIT._CheckAndroidDebuggableBuild(
1193 mock_input_api, mock_output_api)
1194 self.assertEqual(1, len(msgs),
1195 'Expected %d items, found %d: %s'
1196 % (1, len(msgs), msgs))
1197 self.assertEqual(4, len(msgs[0].items),
1198 'Expected %d items, found %d: %s'
1199 % (4, len(msgs[0].items), msgs[0].items))
1200 self.assertTrue('JustCheckUserdebugBuild.java:3' in msgs[0].items)
1201 self.assertTrue('JustCheckEngineeringBuild.java:3' in msgs[0].items)
1202 self.assertTrue('UsedBuildType.java:3' in msgs[0].items)
1203 self.assertTrue('UsedExplicitBuildType.java:2' in msgs[0].items)
1204
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:391205
dgn4401aa52015-04-29 16:26:171206class LogUsageTest(unittest.TestCase):
1207
dgnaa68d5e2015-06-10 10:08:221208 def testCheckAndroidCrLogUsage(self):
1209 mock_input_api = MockInputApi()
1210 mock_output_api = MockOutputApi()
1211
1212 mock_input_api.files = [
1213 MockAffectedFile('RandomStuff.java', [
1214 'random stuff'
1215 ]),
dgn87d9fb62015-06-12 09:15:121216 MockAffectedFile('HasAndroidLog.java', [
1217 'import android.util.Log;',
1218 'some random stuff',
1219 'Log.d("TAG", "foo");',
1220 ]),
1221 MockAffectedFile('HasExplicitUtilLog.java', [
1222 'some random stuff',
1223 'android.util.Log.d("TAG", "foo");',
1224 ]),
1225 MockAffectedFile('IsInBasePackage.java', [
1226 'package org.chromium.base;',
dgn38736db2015-09-18 19:20:511227 'private static final String TAG = "cr_Foo";',
dgn87d9fb62015-06-12 09:15:121228 'Log.d(TAG, "foo");',
1229 ]),
1230 MockAffectedFile('IsInBasePackageButImportsLog.java', [
1231 'package org.chromium.base;',
1232 'import android.util.Log;',
dgn38736db2015-09-18 19:20:511233 'private static final String TAG = "cr_Foo";',
dgn87d9fb62015-06-12 09:15:121234 'Log.d(TAG, "foo");',
1235 ]),
1236 MockAffectedFile('HasBothLog.java', [
1237 'import org.chromium.base.Log;',
1238 'some random stuff',
dgn38736db2015-09-18 19:20:511239 'private static final String TAG = "cr_Foo";',
dgn87d9fb62015-06-12 09:15:121240 'Log.d(TAG, "foo");',
1241 'android.util.Log.d("TAG", "foo");',
1242 ]),
dgnaa68d5e2015-06-10 10:08:221243 MockAffectedFile('HasCorrectTag.java', [
1244 'import org.chromium.base.Log;',
1245 'some random stuff',
dgn38736db2015-09-18 19:20:511246 'private static final String TAG = "cr_Foo";',
1247 'Log.d(TAG, "foo");',
1248 ]),
1249 MockAffectedFile('HasOldTag.java', [
1250 'import org.chromium.base.Log;',
1251 'some random stuff',
dgnaa68d5e2015-06-10 10:08:221252 'private static final String TAG = "cr.Foo";',
1253 'Log.d(TAG, "foo");',
1254 ]),
dgn38736db2015-09-18 19:20:511255 MockAffectedFile('HasDottedTag.java', [
dgnaa68d5e2015-06-10 10:08:221256 'import org.chromium.base.Log;',
1257 'some random stuff',
dgn38736db2015-09-18 19:20:511258 'private static final String TAG = "cr_foo.bar";',
dgnaa68d5e2015-06-10 10:08:221259 'Log.d(TAG, "foo");',
1260 ]),
1261 MockAffectedFile('HasNoTagDecl.java', [
1262 'import org.chromium.base.Log;',
1263 'some random stuff',
1264 'Log.d(TAG, "foo");',
1265 ]),
1266 MockAffectedFile('HasIncorrectTagDecl.java', [
1267 'import org.chromium.base.Log;',
dgn38736db2015-09-18 19:20:511268 'private static final String TAHG = "cr_Foo";',
dgnaa68d5e2015-06-10 10:08:221269 'some random stuff',
1270 'Log.d(TAG, "foo");',
1271 ]),
1272 MockAffectedFile('HasInlineTag.java', [
1273 'import org.chromium.base.Log;',
1274 'some random stuff',
dgn38736db2015-09-18 19:20:511275 'private static final String TAG = "cr_Foo";',
dgnaa68d5e2015-06-10 10:08:221276 'Log.d("TAG", "foo");',
1277 ]),
dgn38736db2015-09-18 19:20:511278 MockAffectedFile('HasUnprefixedTag.java', [
dgnaa68d5e2015-06-10 10:08:221279 'import org.chromium.base.Log;',
1280 'some random stuff',
1281 'private static final String TAG = "rubbish";',
1282 'Log.d(TAG, "foo");',
1283 ]),
1284 MockAffectedFile('HasTooLongTag.java', [
1285 'import org.chromium.base.Log;',
1286 'some random stuff',
dgn38736db2015-09-18 19:20:511287 'private static final String TAG = "21_charachers_long___";',
dgnaa68d5e2015-06-10 10:08:221288 'Log.d(TAG, "foo");',
1289 ]),
1290 ]
1291
1292 msgs = PRESUBMIT._CheckAndroidCrLogUsage(
1293 mock_input_api, mock_output_api)
1294
dgn38736db2015-09-18 19:20:511295 self.assertEqual(5, len(msgs),
1296 'Expected %d items, found %d: %s' % (5, len(msgs), msgs))
dgnaa68d5e2015-06-10 10:08:221297
1298 # Declaration format
dgn38736db2015-09-18 19:20:511299 nb = len(msgs[0].items)
1300 self.assertEqual(2, nb,
1301 'Expected %d items, found %d: %s' % (2, nb, msgs[0].items))
dgnaa68d5e2015-06-10 10:08:221302 self.assertTrue('HasNoTagDecl.java' in msgs[0].items)
1303 self.assertTrue('HasIncorrectTagDecl.java' in msgs[0].items)
dgnaa68d5e2015-06-10 10:08:221304
1305 # Tag length
dgn38736db2015-09-18 19:20:511306 nb = len(msgs[1].items)
1307 self.assertEqual(1, nb,
1308 'Expected %d items, found %d: %s' % (1, nb, msgs[1].items))
dgnaa68d5e2015-06-10 10:08:221309 self.assertTrue('HasTooLongTag.java' in msgs[1].items)
1310
1311 # Tag must be a variable named TAG
dgn38736db2015-09-18 19:20:511312 nb = len(msgs[2].items)
1313 self.assertEqual(1, nb,
1314 'Expected %d items, found %d: %s' % (1, nb, msgs[2].items))
dgnaa68d5e2015-06-10 10:08:221315 self.assertTrue('HasInlineTag.java:4' in msgs[2].items)
1316
dgn87d9fb62015-06-12 09:15:121317 # Util Log usage
dgn38736db2015-09-18 19:20:511318 nb = len(msgs[3].items)
1319 self.assertEqual(2, nb,
1320 'Expected %d items, found %d: %s' % (2, nb, msgs[3].items))
dgn87d9fb62015-06-12 09:15:121321 self.assertTrue('HasAndroidLog.java:3' in msgs[3].items)
1322 self.assertTrue('IsInBasePackageButImportsLog.java:4' in msgs[3].items)
dgnaa68d5e2015-06-10 10:08:221323
dgn38736db2015-09-18 19:20:511324 # Tag must not contain
1325 nb = len(msgs[4].items)
1326 self.assertEqual(2, nb,
1327 'Expected %d items, found %d: %s' % (2, nb, msgs[4].items))
1328 self.assertTrue('HasDottedTag.java' in msgs[4].items)
1329 self.assertTrue('HasOldTag.java' in msgs[4].items)
1330
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:391331
estadee17314a02017-01-12 16:22:161332class GoogleAnswerUrlFormatTest(unittest.TestCase):
1333
1334 def testCatchAnswerUrlId(self):
1335 input_api = MockInputApi()
1336 input_api.files = [
1337 MockFile('somewhere/file.cc',
1338 ['char* host = '
1339 ' "https://support.google.com/chrome/answer/123456";']),
1340 MockFile('somewhere_else/file.cc',
1341 ['char* host = '
1342 ' "https://support.google.com/chrome/a/answer/123456";']),
1343 ]
1344
1345 warnings = PRESUBMIT._CheckGoogleSupportAnswerUrl(
1346 input_api, MockOutputApi())
1347 self.assertEqual(1, len(warnings))
1348 self.assertEqual(2, len(warnings[0].items))
1349
1350 def testAllowAnswerUrlParam(self):
1351 input_api = MockInputApi()
1352 input_api.files = [
1353 MockFile('somewhere/file.cc',
1354 ['char* host = '
1355 ' "https://support.google.com/chrome/?p=cpn_crash_reports";']),
1356 ]
1357
1358 warnings = PRESUBMIT._CheckGoogleSupportAnswerUrl(
1359 input_api, MockOutputApi())
1360 self.assertEqual(0, len(warnings))
1361
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:391362
reillyi38965732015-11-16 18:27:331363class HardcodedGoogleHostsTest(unittest.TestCase):
1364
1365 def testWarnOnAssignedLiterals(self):
1366 input_api = MockInputApi()
1367 input_api.files = [
1368 MockFile('content/file.cc',
1369 ['char* host = "https://www.google.com";']),
1370 MockFile('content/file.cc',
1371 ['char* host = "https://www.googleapis.com";']),
1372 MockFile('content/file.cc',
1373 ['char* host = "https://clients1.google.com";']),
1374 ]
1375
1376 warnings = PRESUBMIT._CheckHardcodedGoogleHostsInLowerLayers(
1377 input_api, MockOutputApi())
1378 self.assertEqual(1, len(warnings))
1379 self.assertEqual(3, len(warnings[0].items))
1380
1381 def testAllowInComment(self):
1382 input_api = MockInputApi()
1383 input_api.files = [
1384 MockFile('content/file.cc',
1385 ['char* host = "https://www.aol.com"; // google.com'])
1386 ]
1387
1388 warnings = PRESUBMIT._CheckHardcodedGoogleHostsInLowerLayers(
1389 input_api, MockOutputApi())
1390 self.assertEqual(0, len(warnings))
1391
dgn4401aa52015-04-29 16:26:171392
jbriance9e12f162016-11-25 07:57:501393class ForwardDeclarationTest(unittest.TestCase):
jbriance2c51e821a2016-12-12 08:24:311394 def testCheckHeadersOnlyOutsideThirdParty(self):
jbriance9e12f162016-11-25 07:57:501395 mock_input_api = MockInputApi()
1396 mock_input_api.files = [
1397 MockAffectedFile('somewhere/file.cc', [
1398 'class DummyClass;'
jbriance2c51e821a2016-12-12 08:24:311399 ]),
1400 MockAffectedFile('third_party/header.h', [
1401 'class DummyClass;'
jbriance9e12f162016-11-25 07:57:501402 ])
1403 ]
1404 warnings = PRESUBMIT._CheckUselessForwardDeclarations(mock_input_api,
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:391405 MockOutputApi())
jbriance9e12f162016-11-25 07:57:501406 self.assertEqual(0, len(warnings))
1407
1408 def testNoNestedDeclaration(self):
1409 mock_input_api = MockInputApi()
1410 mock_input_api.files = [
1411 MockAffectedFile('somewhere/header.h', [
jbriance2c51e821a2016-12-12 08:24:311412 'class SomeClass {',
1413 ' protected:',
1414 ' class NotAMatch;',
jbriance9e12f162016-11-25 07:57:501415 '};'
1416 ])
1417 ]
1418 warnings = PRESUBMIT._CheckUselessForwardDeclarations(mock_input_api,
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:391419 MockOutputApi())
jbriance9e12f162016-11-25 07:57:501420 self.assertEqual(0, len(warnings))
1421
1422 def testSubStrings(self):
1423 mock_input_api = MockInputApi()
1424 mock_input_api.files = [
1425 MockAffectedFile('somewhere/header.h', [
1426 'class NotUsefulClass;',
1427 'struct SomeStruct;',
1428 'UsefulClass *p1;',
1429 'SomeStructPtr *p2;'
1430 ])
1431 ]
1432 warnings = PRESUBMIT._CheckUselessForwardDeclarations(mock_input_api,
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:391433 MockOutputApi())
jbriance9e12f162016-11-25 07:57:501434 self.assertEqual(2, len(warnings))
1435
1436 def testUselessForwardDeclaration(self):
1437 mock_input_api = MockInputApi()
1438 mock_input_api.files = [
1439 MockAffectedFile('somewhere/header.h', [
1440 'class DummyClass;',
1441 'struct DummyStruct;',
1442 'class UsefulClass;',
1443 'std::unique_ptr<UsefulClass> p;'
jbriance2c51e821a2016-12-12 08:24:311444 ])
jbriance9e12f162016-11-25 07:57:501445 ]
1446 warnings = PRESUBMIT._CheckUselessForwardDeclarations(mock_input_api,
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:391447 MockOutputApi())
jbriance9e12f162016-11-25 07:57:501448 self.assertEqual(2, len(warnings))
1449
jbriance2c51e821a2016-12-12 08:24:311450 def testBlinkHeaders(self):
1451 mock_input_api = MockInputApi()
1452 mock_input_api.files = [
Kent Tamura32dbbcb2018-11-30 12:28:491453 MockAffectedFile('third_party/blink/header.h', [
jbriance2c51e821a2016-12-12 08:24:311454 'class DummyClass;',
1455 'struct DummyStruct;',
1456 ]),
Kent Tamura32dbbcb2018-11-30 12:28:491457 MockAffectedFile('third_party\\blink\\header.h', [
jbriance2c51e821a2016-12-12 08:24:311458 'class DummyClass;',
1459 'struct DummyStruct;',
1460 ])
1461 ]
1462 warnings = PRESUBMIT._CheckUselessForwardDeclarations(mock_input_api,
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:391463 MockOutputApi())
jbriance2c51e821a2016-12-12 08:24:311464 self.assertEqual(4, len(warnings))
1465
jbriance9e12f162016-11-25 07:57:501466
rlanday6802cf632017-05-30 17:48:361467class RelativeIncludesTest(unittest.TestCase):
1468 def testThirdPartyNotWebKitIgnored(self):
1469 mock_input_api = MockInputApi()
1470 mock_input_api.files = [
1471 MockAffectedFile('third_party/test.cpp', '#include "../header.h"'),
1472 MockAffectedFile('third_party/test/test.cpp', '#include "../header.h"'),
1473 ]
1474
1475 mock_output_api = MockOutputApi()
1476
1477 errors = PRESUBMIT._CheckForRelativeIncludes(
1478 mock_input_api, mock_output_api)
1479 self.assertEqual(0, len(errors))
1480
1481 def testNonCppFileIgnored(self):
1482 mock_input_api = MockInputApi()
1483 mock_input_api.files = [
1484 MockAffectedFile('test.py', '#include "../header.h"'),
1485 ]
1486
1487 mock_output_api = MockOutputApi()
1488
1489 errors = PRESUBMIT._CheckForRelativeIncludes(
1490 mock_input_api, mock_output_api)
1491 self.assertEqual(0, len(errors))
1492
1493 def testInnocuousChangesAllowed(self):
1494 mock_input_api = MockInputApi()
1495 mock_input_api.files = [
1496 MockAffectedFile('test.cpp', '#include "header.h"'),
1497 MockAffectedFile('test2.cpp', '../'),
1498 ]
1499
1500 mock_output_api = MockOutputApi()
1501
1502 errors = PRESUBMIT._CheckForRelativeIncludes(
1503 mock_input_api, mock_output_api)
1504 self.assertEqual(0, len(errors))
1505
1506 def testRelativeIncludeNonWebKitProducesError(self):
1507 mock_input_api = MockInputApi()
1508 mock_input_api.files = [
1509 MockAffectedFile('test.cpp', ['#include "../header.h"']),
1510 ]
1511
1512 mock_output_api = MockOutputApi()
1513
1514 errors = PRESUBMIT._CheckForRelativeIncludes(
1515 mock_input_api, mock_output_api)
1516 self.assertEqual(1, len(errors))
1517
1518 def testRelativeIncludeWebKitProducesError(self):
1519 mock_input_api = MockInputApi()
1520 mock_input_api.files = [
Kent Tamura32dbbcb2018-11-30 12:28:491521 MockAffectedFile('third_party/blink/test.cpp',
rlanday6802cf632017-05-30 17:48:361522 ['#include "../header.h']),
1523 ]
1524
1525 mock_output_api = MockOutputApi()
1526
1527 errors = PRESUBMIT._CheckForRelativeIncludes(
1528 mock_input_api, mock_output_api)
1529 self.assertEqual(1, len(errors))
dbeam1ec68ac2016-12-15 05:22:241530
Daniel Cheng13ca61a882017-08-25 15:11:251531
Daniel Bratell65b033262019-04-23 08:17:061532class CCIncludeTest(unittest.TestCase):
1533 def testThirdPartyNotBlinkIgnored(self):
1534 mock_input_api = MockInputApi()
1535 mock_input_api.files = [
1536 MockAffectedFile('third_party/test.cpp', '#include "file.cc"'),
1537 ]
1538
1539 mock_output_api = MockOutputApi()
1540
1541 errors = PRESUBMIT._CheckForCcIncludes(
1542 mock_input_api, mock_output_api)
1543 self.assertEqual(0, len(errors))
1544
1545 def testPythonFileIgnored(self):
1546 mock_input_api = MockInputApi()
1547 mock_input_api.files = [
1548 MockAffectedFile('test.py', '#include "file.cc"'),
1549 ]
1550
1551 mock_output_api = MockOutputApi()
1552
1553 errors = PRESUBMIT._CheckForCcIncludes(
1554 mock_input_api, mock_output_api)
1555 self.assertEqual(0, len(errors))
1556
1557 def testIncFilesAccepted(self):
1558 mock_input_api = MockInputApi()
1559 mock_input_api.files = [
1560 MockAffectedFile('test.py', '#include "file.inc"'),
1561 ]
1562
1563 mock_output_api = MockOutputApi()
1564
1565 errors = PRESUBMIT._CheckForCcIncludes(
1566 mock_input_api, mock_output_api)
1567 self.assertEqual(0, len(errors))
1568
1569 def testInnocuousChangesAllowed(self):
1570 mock_input_api = MockInputApi()
1571 mock_input_api.files = [
1572 MockAffectedFile('test.cpp', '#include "header.h"'),
1573 MockAffectedFile('test2.cpp', 'Something "file.cc"'),
1574 ]
1575
1576 mock_output_api = MockOutputApi()
1577
1578 errors = PRESUBMIT._CheckForCcIncludes(
1579 mock_input_api, mock_output_api)
1580 self.assertEqual(0, len(errors))
1581
1582 def testCcIncludeNonBlinkProducesError(self):
1583 mock_input_api = MockInputApi()
1584 mock_input_api.files = [
1585 MockAffectedFile('test.cpp', ['#include "file.cc"']),
1586 ]
1587
1588 mock_output_api = MockOutputApi()
1589
1590 errors = PRESUBMIT._CheckForCcIncludes(
1591 mock_input_api, mock_output_api)
1592 self.assertEqual(1, len(errors))
1593
1594 def testCppIncludeBlinkProducesError(self):
1595 mock_input_api = MockInputApi()
1596 mock_input_api.files = [
1597 MockAffectedFile('third_party/blink/test.cpp',
1598 ['#include "foo/file.cpp"']),
1599 ]
1600
1601 mock_output_api = MockOutputApi()
1602
1603 errors = PRESUBMIT._CheckForCcIncludes(
1604 mock_input_api, mock_output_api)
1605 self.assertEqual(1, len(errors))
1606
1607
Wei-Yin Chen (陳威尹)c0624d002018-07-30 18:22:191608class NewHeaderWithoutGnChangeTest(unittest.TestCase):
1609 def testAddHeaderWithoutGn(self):
1610 mock_input_api = MockInputApi()
1611 mock_input_api.files = [
1612 MockAffectedFile('base/stuff.h', ''),
1613 ]
1614 warnings = PRESUBMIT._CheckNewHeaderWithoutGnChange(
1615 mock_input_api, MockOutputApi())
1616 self.assertEqual(1, len(warnings))
1617 self.assertTrue('base/stuff.h' in warnings[0].items)
1618
1619 def testModifyHeader(self):
1620 mock_input_api = MockInputApi()
1621 mock_input_api.files = [
1622 MockAffectedFile('base/stuff.h', '', action='M'),
1623 ]
1624 warnings = PRESUBMIT._CheckNewHeaderWithoutGnChange(
1625 mock_input_api, MockOutputApi())
1626 self.assertEqual(0, len(warnings))
1627
1628 def testDeleteHeader(self):
1629 mock_input_api = MockInputApi()
1630 mock_input_api.files = [
1631 MockAffectedFile('base/stuff.h', '', action='D'),
1632 ]
1633 warnings = PRESUBMIT._CheckNewHeaderWithoutGnChange(
1634 mock_input_api, MockOutputApi())
1635 self.assertEqual(0, len(warnings))
1636
1637 def testAddHeaderWithGn(self):
1638 mock_input_api = MockInputApi()
1639 mock_input_api.files = [
1640 MockAffectedFile('base/stuff.h', ''),
1641 MockAffectedFile('base/BUILD.gn', 'stuff.h'),
1642 ]
1643 warnings = PRESUBMIT._CheckNewHeaderWithoutGnChange(
1644 mock_input_api, MockOutputApi())
1645 self.assertEqual(0, len(warnings))
1646
1647 def testAddHeaderWithGni(self):
1648 mock_input_api = MockInputApi()
1649 mock_input_api.files = [
1650 MockAffectedFile('base/stuff.h', ''),
1651 MockAffectedFile('base/files.gni', 'stuff.h'),
1652 ]
1653 warnings = PRESUBMIT._CheckNewHeaderWithoutGnChange(
1654 mock_input_api, MockOutputApi())
1655 self.assertEqual(0, len(warnings))
1656
1657 def testAddHeaderWithOther(self):
1658 mock_input_api = MockInputApi()
1659 mock_input_api.files = [
1660 MockAffectedFile('base/stuff.h', ''),
1661 MockAffectedFile('base/stuff.cc', 'stuff.h'),
1662 ]
1663 warnings = PRESUBMIT._CheckNewHeaderWithoutGnChange(
1664 mock_input_api, MockOutputApi())
1665 self.assertEqual(1, len(warnings))
1666
1667 def testAddHeaderWithWrongGn(self):
1668 mock_input_api = MockInputApi()
1669 mock_input_api.files = [
1670 MockAffectedFile('base/stuff.h', ''),
1671 MockAffectedFile('base/BUILD.gn', 'stuff_h'),
1672 ]
1673 warnings = PRESUBMIT._CheckNewHeaderWithoutGnChange(
1674 mock_input_api, MockOutputApi())
1675 self.assertEqual(1, len(warnings))
1676
1677 def testAddHeadersWithGn(self):
1678 mock_input_api = MockInputApi()
1679 mock_input_api.files = [
1680 MockAffectedFile('base/stuff.h', ''),
1681 MockAffectedFile('base/another.h', ''),
1682 MockAffectedFile('base/BUILD.gn', 'another.h\nstuff.h'),
1683 ]
1684 warnings = PRESUBMIT._CheckNewHeaderWithoutGnChange(
1685 mock_input_api, MockOutputApi())
1686 self.assertEqual(0, len(warnings))
1687
1688 def testAddHeadersWithWrongGn(self):
1689 mock_input_api = MockInputApi()
1690 mock_input_api.files = [
1691 MockAffectedFile('base/stuff.h', ''),
1692 MockAffectedFile('base/another.h', ''),
1693 MockAffectedFile('base/BUILD.gn', 'another_h\nstuff.h'),
1694 ]
1695 warnings = PRESUBMIT._CheckNewHeaderWithoutGnChange(
1696 mock_input_api, MockOutputApi())
1697 self.assertEqual(1, len(warnings))
1698 self.assertFalse('base/stuff.h' in warnings[0].items)
1699 self.assertTrue('base/another.h' in warnings[0].items)
1700
1701 def testAddHeadersWithWrongGn2(self):
1702 mock_input_api = MockInputApi()
1703 mock_input_api.files = [
1704 MockAffectedFile('base/stuff.h', ''),
1705 MockAffectedFile('base/another.h', ''),
1706 MockAffectedFile('base/BUILD.gn', 'another_h\nstuff_h'),
1707 ]
1708 warnings = PRESUBMIT._CheckNewHeaderWithoutGnChange(
1709 mock_input_api, MockOutputApi())
1710 self.assertEqual(1, len(warnings))
1711 self.assertTrue('base/stuff.h' in warnings[0].items)
1712 self.assertTrue('base/another.h' in warnings[0].items)
1713
1714
Michael Giuffridad3bc8672018-10-25 22:48:021715class CorrectProductNameInMessagesTest(unittest.TestCase):
1716 def testProductNameInDesc(self):
1717 mock_input_api = MockInputApi()
1718 mock_input_api.files = [
1719 MockAffectedFile('chrome/app/google_chrome_strings.grd', [
1720 '<message name="Foo" desc="Welcome to Chrome">',
1721 ' Welcome to Chrome!',
1722 '</message>',
1723 ]),
1724 MockAffectedFile('chrome/app/chromium_strings.grd', [
1725 '<message name="Bar" desc="Welcome to Chrome">',
1726 ' Welcome to Chromium!',
1727 '</message>',
1728 ]),
1729 ]
1730 warnings = PRESUBMIT._CheckCorrectProductNameInMessages(
1731 mock_input_api, MockOutputApi())
1732 self.assertEqual(0, len(warnings))
1733
1734 def testChromeInChromium(self):
1735 mock_input_api = MockInputApi()
1736 mock_input_api.files = [
1737 MockAffectedFile('chrome/app/google_chrome_strings.grd', [
1738 '<message name="Foo" desc="Welcome to Chrome">',
1739 ' Welcome to Chrome!',
1740 '</message>',
1741 ]),
1742 MockAffectedFile('chrome/app/chromium_strings.grd', [
1743 '<message name="Bar" desc="Welcome to Chrome">',
1744 ' Welcome to Chrome!',
1745 '</message>',
1746 ]),
1747 ]
1748 warnings = PRESUBMIT._CheckCorrectProductNameInMessages(
1749 mock_input_api, MockOutputApi())
1750 self.assertEqual(1, len(warnings))
1751 self.assertTrue('chrome/app/chromium_strings.grd' in warnings[0].items[0])
1752
1753 def testChromiumInChrome(self):
1754 mock_input_api = MockInputApi()
1755 mock_input_api.files = [
1756 MockAffectedFile('chrome/app/google_chrome_strings.grd', [
1757 '<message name="Foo" desc="Welcome to Chrome">',
1758 ' Welcome to Chromium!',
1759 '</message>',
1760 ]),
1761 MockAffectedFile('chrome/app/chromium_strings.grd', [
1762 '<message name="Bar" desc="Welcome to Chrome">',
1763 ' Welcome to Chromium!',
1764 '</message>',
1765 ]),
1766 ]
1767 warnings = PRESUBMIT._CheckCorrectProductNameInMessages(
1768 mock_input_api, MockOutputApi())
1769 self.assertEqual(1, len(warnings))
1770 self.assertTrue(
1771 'chrome/app/google_chrome_strings.grd:2' in warnings[0].items[0])
1772
1773 def testMultipleInstances(self):
1774 mock_input_api = MockInputApi()
1775 mock_input_api.files = [
1776 MockAffectedFile('chrome/app/chromium_strings.grd', [
1777 '<message name="Bar" desc="Welcome to Chrome">',
1778 ' Welcome to Chrome!',
1779 '</message>',
1780 '<message name="Baz" desc="A correct message">',
1781 ' Chromium is the software you are using.',
1782 '</message>',
1783 '<message name="Bat" desc="An incorrect message">',
1784 ' Google Chrome is the software you are using.',
1785 '</message>',
1786 ]),
1787 ]
1788 warnings = PRESUBMIT._CheckCorrectProductNameInMessages(
1789 mock_input_api, MockOutputApi())
1790 self.assertEqual(1, len(warnings))
1791 self.assertTrue(
1792 'chrome/app/chromium_strings.grd:2' in warnings[0].items[0])
1793 self.assertTrue(
1794 'chrome/app/chromium_strings.grd:8' in warnings[0].items[1])
1795
1796 def testMultipleWarnings(self):
1797 mock_input_api = MockInputApi()
1798 mock_input_api.files = [
1799 MockAffectedFile('chrome/app/chromium_strings.grd', [
1800 '<message name="Bar" desc="Welcome to Chrome">',
1801 ' Welcome to Chrome!',
1802 '</message>',
1803 '<message name="Baz" desc="A correct message">',
1804 ' Chromium is the software you are using.',
1805 '</message>',
1806 '<message name="Bat" desc="An incorrect message">',
1807 ' Google Chrome is the software you are using.',
1808 '</message>',
1809 ]),
1810 MockAffectedFile('components/components_google_chrome_strings.grd', [
1811 '<message name="Bar" desc="Welcome to Chrome">',
1812 ' Welcome to Chrome!',
1813 '</message>',
1814 '<message name="Baz" desc="A correct message">',
1815 ' Chromium is the software you are using.',
1816 '</message>',
1817 '<message name="Bat" desc="An incorrect message">',
1818 ' Google Chrome is the software you are using.',
1819 '</message>',
1820 ]),
1821 ]
1822 warnings = PRESUBMIT._CheckCorrectProductNameInMessages(
1823 mock_input_api, MockOutputApi())
1824 self.assertEqual(2, len(warnings))
1825 self.assertTrue(
1826 'components/components_google_chrome_strings.grd:5'
1827 in warnings[0].items[0])
1828 self.assertTrue(
1829 'chrome/app/chromium_strings.grd:2' in warnings[1].items[0])
1830 self.assertTrue(
1831 'chrome/app/chromium_strings.grd:8' in warnings[1].items[1])
1832
1833
Ken Rockot9f668262018-12-21 18:56:361834class ServiceManifestOwnerTest(unittest.TestCase):
1835 def testServiceManifestJsonChangeNeedsSecurityOwner(self):
Daniel Cheng13ca61a882017-08-25 15:11:251836 mock_input_api = MockInputApi()
1837 mock_input_api.files = [
1838 MockAffectedFile('services/goat/manifest.json',
1839 [
1840 '{',
1841 ' "name": "teleporter",',
1842 ' "display_name": "Goat Teleporter",'
1843 ' "interface_provider_specs": {',
1844 ' }',
1845 '}',
1846 ])
1847 ]
1848 mock_output_api = MockOutputApi()
1849 errors = PRESUBMIT._CheckIpcOwners(
1850 mock_input_api, mock_output_api)
1851 self.assertEqual(1, len(errors))
1852 self.assertEqual(
1853 'Found OWNERS files that need to be updated for IPC security review ' +
1854 'coverage.\nPlease update the OWNERS files below:', errors[0].message)
1855
1856 # No warning if already covered by an OWNERS rule.
1857
Ken Rockot9f668262018-12-21 18:56:361858 def testNonManifestJsonChangesDoNotRequireSecurityOwner(self):
Daniel Cheng13ca61a882017-08-25 15:11:251859 mock_input_api = MockInputApi()
1860 mock_input_api.files = [
1861 MockAffectedFile('services/goat/species.json',
1862 [
1863 '[',
1864 ' "anglo-nubian",',
1865 ' "angora"',
1866 ']',
1867 ])
1868 ]
1869 mock_output_api = MockOutputApi()
1870 errors = PRESUBMIT._CheckIpcOwners(
1871 mock_input_api, mock_output_api)
1872 self.assertEqual([], errors)
1873
Ken Rockot9f668262018-12-21 18:56:361874 def testServiceManifestChangeNeedsSecurityOwner(self):
1875 mock_input_api = MockInputApi()
1876 mock_input_api.files = [
1877 MockAffectedFile('services/goat/public/cpp/manifest.cc',
1878 [
1879 '#include "services/goat/public/cpp/manifest.h"',
1880 'const service_manager::Manifest& GetManifest() {}',
1881 ])]
1882 mock_output_api = MockOutputApi()
1883 errors = PRESUBMIT._CheckIpcOwners(
1884 mock_input_api, mock_output_api)
1885 self.assertEqual(1, len(errors))
1886 self.assertEqual(
1887 'Found OWNERS files that need to be updated for IPC security review ' +
1888 'coverage.\nPlease update the OWNERS files below:', errors[0].message)
1889
1890 def testNonServiceManifestSourceChangesDoNotRequireSecurityOwner(self):
1891 mock_input_api = MockInputApi()
1892 mock_input_api.files = [
1893 MockAffectedFile('some/non/service/thing/foo_manifest.cc',
1894 [
1895 'const char kNoEnforcement[] = "not a manifest!";',
1896 ])]
1897 mock_output_api = MockOutputApi()
1898 errors = PRESUBMIT._CheckIpcOwners(
1899 mock_input_api, mock_output_api)
1900 self.assertEqual([], errors)
1901
Daniel Cheng13ca61a882017-08-25 15:11:251902
Sylvain Defresnea8b73d252018-02-28 15:45:541903class BannedFunctionCheckTest(unittest.TestCase):
1904
1905 def testBannedIosObcjFunctions(self):
1906 input_api = MockInputApi()
1907 input_api.files = [
1908 MockFile('some/ios/file.mm',
1909 ['TEST(SomeClassTest, SomeInteraction) {',
1910 '}']),
1911 MockFile('some/mac/file.mm',
1912 ['TEST(SomeClassTest, SomeInteraction) {',
1913 '}']),
1914 MockFile('another/ios_file.mm',
1915 ['class SomeTest : public testing::Test {};']),
1916 ]
1917
1918 errors = PRESUBMIT._CheckNoBannedFunctions(input_api, MockOutputApi())
1919 self.assertEqual(1, len(errors))
1920 self.assertTrue('some/ios/file.mm' in errors[0].message)
1921 self.assertTrue('another/ios_file.mm' in errors[0].message)
1922 self.assertTrue('some/mac/file.mm' not in errors[0].message)
1923
Carlos Knippschildab192b8c2019-04-08 20:02:381924 def testBannedMojoFunctions(self):
1925 input_api = MockInputApi()
1926 input_api.files = [
1927 MockFile('some/cpp/problematic/file.cc',
1928 ['mojo::DataPipe();']),
1929 MockFile('some/cpp/ok/file.cc',
1930 ['CreateDataPipe();']),
Kinuko Yasuda376c2ce12019-04-16 01:20:371931 MockFile('some/cpp/ok/file2.cc',
1932 ['mojo::DataPipeDrainer();']),
Carlos Knippschildab192b8c2019-04-08 20:02:381933 ]
1934
1935 errors = PRESUBMIT._CheckNoBannedFunctions(input_api, MockOutputApi())
1936 self.assertEqual(1, len(errors))
1937 self.assertTrue('some/cpp/problematic/file.cc' in errors[0].message)
1938 self.assertTrue('some/cpp/ok/file.cc' not in errors[0].message)
Kinuko Yasuda376c2ce12019-04-16 01:20:371939 self.assertTrue('some/cpp/ok/file2.cc' not in errors[0].message)
Carlos Knippschildab192b8c2019-04-08 20:02:381940
Sylvain Defresnea8b73d252018-02-28 15:45:541941
Wei-Yin Chen (陳威尹)032f1ac2018-07-27 21:21:271942class NoProductionCodeUsingTestOnlyFunctionsTest(unittest.TestCase):
Vaclav Brozekf01ed502018-03-16 19:38:241943 def testTruePositives(self):
1944 mock_input_api = MockInputApi()
1945 mock_input_api.files = [
1946 MockFile('some/path/foo.cc', ['foo_for_testing();']),
1947 MockFile('some/path/foo.mm', ['FooForTesting();']),
1948 MockFile('some/path/foo.cxx', ['FooForTests();']),
1949 MockFile('some/path/foo.cpp', ['foo_for_test();']),
1950 ]
1951
1952 results = PRESUBMIT._CheckNoProductionCodeUsingTestOnlyFunctions(
1953 mock_input_api, MockOutputApi())
1954 self.assertEqual(1, len(results))
1955 self.assertEqual(4, len(results[0].items))
1956 self.assertTrue('foo.cc' in results[0].items[0])
1957 self.assertTrue('foo.mm' in results[0].items[1])
1958 self.assertTrue('foo.cxx' in results[0].items[2])
1959 self.assertTrue('foo.cpp' in results[0].items[3])
1960
1961 def testFalsePositives(self):
1962 mock_input_api = MockInputApi()
1963 mock_input_api.files = [
1964 MockFile('some/path/foo.h', ['foo_for_testing();']),
1965 MockFile('some/path/foo.mm', ['FooForTesting() {']),
1966 MockFile('some/path/foo.cc', ['::FooForTests();']),
1967 MockFile('some/path/foo.cpp', ['// foo_for_test();']),
1968 ]
1969
1970 results = PRESUBMIT._CheckNoProductionCodeUsingTestOnlyFunctions(
1971 mock_input_api, MockOutputApi())
1972 self.assertEqual(0, len(results))
1973
1974
Wei-Yin Chen (陳威尹)032f1ac2018-07-27 21:21:271975class NoProductionJavaCodeUsingTestOnlyFunctionsTest(unittest.TestCase):
Vaclav Brozek7dbc28c2018-03-27 08:35:231976 def testTruePositives(self):
1977 mock_input_api = MockInputApi()
1978 mock_input_api.files = [
1979 MockFile('dir/java/src/foo.java', ['FooForTesting();']),
1980 MockFile('dir/java/src/bar.java', ['FooForTests(x);']),
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:391981 MockFile('dir/java/src/baz.java', ['FooForTest(', 'y', ');']),
Vaclav Brozek7dbc28c2018-03-27 08:35:231982 MockFile('dir/java/src/mult.java', [
1983 'int x = SomethingLongHere()',
1984 ' * SomethingLongHereForTesting();'
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:391985 ])
Vaclav Brozek7dbc28c2018-03-27 08:35:231986 ]
1987
1988 results = PRESUBMIT._CheckNoProductionCodeUsingTestOnlyFunctionsJava(
1989 mock_input_api, MockOutputApi())
1990 self.assertEqual(1, len(results))
1991 self.assertEqual(4, len(results[0].items))
1992 self.assertTrue('foo.java' in results[0].items[0])
1993 self.assertTrue('bar.java' in results[0].items[1])
1994 self.assertTrue('baz.java' in results[0].items[2])
1995 self.assertTrue('mult.java' in results[0].items[3])
1996
1997 def testFalsePositives(self):
1998 mock_input_api = MockInputApi()
1999 mock_input_api.files = [
2000 MockFile('dir/java/src/foo.xml', ['FooForTesting();']),
2001 MockFile('dir/java/src/foo.java', ['FooForTests() {']),
2002 MockFile('dir/java/src/bar.java', ['// FooForTest();']),
2003 MockFile('dir/java/src/bar2.java', ['x = 1; // FooForTest();']),
Wei-Yin Chen (陳威尹)54086c212018-07-27 21:41:392004 MockFile('dir/javatests/src/baz.java', ['FooForTest(', 'y', ');']),
2005 MockFile('dir/junit/src/baz.java', ['FooForTest(', 'y', ');']),
Vaclav Brozek7dbc28c2018-03-27 08:35:232006 MockFile('dir/junit/src/javadoc.java', [
2007 '/** Use FooForTest(); to obtain foo in tests.'
2008 ' */'
2009 ]),
2010 MockFile('dir/junit/src/javadoc2.java', [
2011 '/** ',
2012 ' * Use FooForTest(); to obtain foo in tests.'
2013 ' */'
2014 ]),
2015 ]
2016
2017 results = PRESUBMIT._CheckNoProductionCodeUsingTestOnlyFunctionsJava(
2018 mock_input_api, MockOutputApi())
2019 self.assertEqual(0, len(results))
2020
2021
Wei-Yin Chen (陳威尹)032f1ac2018-07-27 21:21:272022class CheckUniquePtrTest(unittest.TestCase):
Vaclav Brozek851d9602018-04-04 16:13:052023 def testTruePositivesNullptr(self):
2024 mock_input_api = MockInputApi()
2025 mock_input_api.files = [
Vaclav Brozekc2fecf42018-04-06 16:40:162026 MockFile('dir/baz.cc', ['std::unique_ptr<T>()']),
2027 MockFile('dir/baz-p.cc', ['std::unique_ptr<T<P>>()']),
Vaclav Brozek851d9602018-04-04 16:13:052028 ]
2029
2030 results = PRESUBMIT._CheckUniquePtr(mock_input_api, MockOutputApi())
2031 self.assertEqual(1, len(results))
Vaclav Brozekc2fecf42018-04-06 16:40:162032 self.assertTrue('nullptr' in results[0].message)
Vaclav Brozek851d9602018-04-04 16:13:052033 self.assertEqual(2, len(results[0].items))
2034 self.assertTrue('baz.cc' in results[0].items[0])
2035 self.assertTrue('baz-p.cc' in results[0].items[1])
2036
2037 def testTruePositivesConstructor(self):
Vaclav Brozek52e18bf2018-04-03 07:05:242038 mock_input_api = MockInputApi()
2039 mock_input_api.files = [
Vaclav Brozekc2fecf42018-04-06 16:40:162040 MockFile('dir/foo.cc', ['return std::unique_ptr<T>(foo);']),
2041 MockFile('dir/bar.mm', ['bar = std::unique_ptr<T>(foo)']),
2042 MockFile('dir/mult.cc', [
Vaclav Brozek95face62018-04-04 14:15:112043 'return',
2044 ' std::unique_ptr<T>(barVeryVeryLongFooSoThatItWouldNotFitAbove);'
2045 ]),
Vaclav Brozekc2fecf42018-04-06 16:40:162046 MockFile('dir/mult2.cc', [
Vaclav Brozek95face62018-04-04 14:15:112047 'barVeryVeryLongLongBaaaaaarSoThatTheLineLimitIsAlmostReached =',
2048 ' std::unique_ptr<T>(foo);'
2049 ]),
Vaclav Brozekc2fecf42018-04-06 16:40:162050 MockFile('dir/mult3.cc', [
Vaclav Brozek95face62018-04-04 14:15:112051 'bar = std::unique_ptr<T>(',
2052 ' fooVeryVeryVeryLongStillGoingWellThisWillTakeAWhileFinallyThere);'
2053 ]),
Vaclav Brozekb7fadb692018-08-30 06:39:532054 MockFile('dir/multi_arg.cc', [
2055 'auto p = std::unique_ptr<std::pair<T, D>>(new std::pair(T, D));']),
Vaclav Brozek52e18bf2018-04-03 07:05:242056 ]
2057
2058 results = PRESUBMIT._CheckUniquePtr(mock_input_api, MockOutputApi())
Vaclav Brozek851d9602018-04-04 16:13:052059 self.assertEqual(1, len(results))
Vaclav Brozekc2fecf42018-04-06 16:40:162060 self.assertTrue('std::make_unique' in results[0].message)
Vaclav Brozekb7fadb692018-08-30 06:39:532061 self.assertEqual(6, len(results[0].items))
Vaclav Brozek851d9602018-04-04 16:13:052062 self.assertTrue('foo.cc' in results[0].items[0])
2063 self.assertTrue('bar.mm' in results[0].items[1])
2064 self.assertTrue('mult.cc' in results[0].items[2])
2065 self.assertTrue('mult2.cc' in results[0].items[3])
2066 self.assertTrue('mult3.cc' in results[0].items[4])
Vaclav Brozekb7fadb692018-08-30 06:39:532067 self.assertTrue('multi_arg.cc' in results[0].items[5])
Vaclav Brozek52e18bf2018-04-03 07:05:242068
2069 def testFalsePositives(self):
2070 mock_input_api = MockInputApi()
2071 mock_input_api.files = [
Vaclav Brozekc2fecf42018-04-06 16:40:162072 MockFile('dir/foo.cc', ['return std::unique_ptr<T[]>(foo);']),
2073 MockFile('dir/bar.mm', ['bar = std::unique_ptr<T[]>(foo)']),
2074 MockFile('dir/file.cc', ['std::unique_ptr<T> p = Foo();']),
2075 MockFile('dir/baz.cc', [
Vaclav Brozek52e18bf2018-04-03 07:05:242076 'std::unique_ptr<T> result = std::make_unique<T>();'
2077 ]),
Vaclav Brozeka54c528b2018-04-06 19:23:552078 MockFile('dir/baz2.cc', [
2079 'std::unique_ptr<T> result = std::make_unique<T>('
2080 ]),
2081 MockFile('dir/nested.cc', ['set<std::unique_ptr<T>>();']),
2082 MockFile('dir/nested2.cc', ['map<U, std::unique_ptr<T>>();']),
Vaclav Brozekb7fadb692018-08-30 06:39:532083
2084 # Two-argument invocation of std::unique_ptr is exempt because there is
2085 # no equivalent using std::make_unique.
2086 MockFile('dir/multi_arg.cc', [
2087 'auto p = std::unique_ptr<T, D>(new T(), D());']),
Vaclav Brozek52e18bf2018-04-03 07:05:242088 ]
2089
2090 results = PRESUBMIT._CheckUniquePtr(mock_input_api, MockOutputApi())
2091 self.assertEqual(0, len(results))
2092
Danil Chapovalov3518f362018-08-11 16:13:432093class CheckNoDirectIncludesHeadersWhichRedefineStrCat(unittest.TestCase):
2094 def testBlocksDirectIncludes(self):
2095 mock_input_api = MockInputApi()
2096 mock_input_api.files = [
2097 MockFile('dir/foo_win.cc', ['#include "shlwapi.h"']),
2098 MockFile('dir/bar.h', ['#include <propvarutil.h>']),
2099 MockFile('dir/baz.h', ['#include <atlbase.h>']),
2100 MockFile('dir/jumbo.h', ['#include "sphelper.h"']),
2101 ]
2102 results = PRESUBMIT._CheckNoStrCatRedefines(mock_input_api, MockOutputApi())
2103 self.assertEquals(1, len(results))
2104 self.assertEquals(4, len(results[0].items))
2105 self.assertTrue('StrCat' in results[0].message)
2106 self.assertTrue('foo_win.cc' in results[0].items[0])
2107 self.assertTrue('bar.h' in results[0].items[1])
2108 self.assertTrue('baz.h' in results[0].items[2])
2109 self.assertTrue('jumbo.h' in results[0].items[3])
2110
2111 def testAllowsToIncludeWrapper(self):
2112 mock_input_api = MockInputApi()
2113 mock_input_api.files = [
2114 MockFile('dir/baz_win.cc', ['#include "base/win/shlwapi.h"']),
2115 MockFile('dir/baz-win.h', ['#include "base/win/atl.h"']),
2116 ]
2117 results = PRESUBMIT._CheckNoStrCatRedefines(mock_input_api, MockOutputApi())
2118 self.assertEquals(0, len(results))
2119
2120 def testAllowsToCreateWrapper(self):
2121 mock_input_api = MockInputApi()
2122 mock_input_api.files = [
2123 MockFile('base/win/shlwapi.h', [
2124 '#include <shlwapi.h>',
2125 '#include "base/win/windows_defines.inc"']),
2126 ]
2127 results = PRESUBMIT._CheckNoStrCatRedefines(mock_input_api, MockOutputApi())
2128 self.assertEquals(0, len(results))
Vaclav Brozek52e18bf2018-04-03 07:05:242129
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142130class TranslationScreenshotsTest(unittest.TestCase):
2131 # An empty grd file.
2132 OLD_GRD_CONTENTS = """<?xml version="1.0" encoding="UTF-8"?>
2133 <grit latest_public_release="1" current_release="1">
2134 <release seq="1">
2135 <messages></messages>
2136 </release>
2137 </grit>
2138 """.splitlines()
2139 # A grd file with a single message.
2140 NEW_GRD_CONTENTS1 = """<?xml version="1.0" encoding="UTF-8"?>
2141 <grit latest_public_release="1" current_release="1">
2142 <release seq="1">
2143 <messages>
2144 <message name="IDS_TEST1">
2145 Test string 1
2146 </message>
2147 </messages>
2148 </release>
2149 </grit>
2150 """.splitlines()
2151 # A grd file with two messages.
2152 NEW_GRD_CONTENTS2 = """<?xml version="1.0" encoding="UTF-8"?>
2153 <grit latest_public_release="1" current_release="1">
2154 <release seq="1">
2155 <messages>
2156 <message name="IDS_TEST1">
2157 Test string 1
2158 </message>
2159 <message name="IDS_TEST2">
2160 Test string 2
2161 </message>
2162 </messages>
2163 </release>
2164 </grit>
2165 """.splitlines()
2166
Mustafa Emre Acerc8a012d2018-07-31 00:00:392167 DO_NOT_UPLOAD_PNG_MESSAGE = ('Do not include actual screenshots in the '
2168 'changelist. Run '
2169 'tools/translate/upload_screenshots.py to '
2170 'upload them instead:')
2171 GENERATE_SIGNATURES_MESSAGE = ('You are adding or modifying UI strings.\n'
2172 'To ensure the best translations, take '
2173 'screenshots of the relevant UI '
2174 '(https://g.co/chrome/translation) and add '
2175 'these files to your changelist:')
2176 REMOVE_SIGNATURES_MESSAGE = ('You removed strings associated with these '
2177 'files. Remove:')
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142178
2179 def makeInputApi(self, files):
2180 input_api = MockInputApi()
2181 input_api.files = files
2182 return input_api
2183
2184 def testNoScreenshots(self):
2185 # CL modified and added messages, but didn't add any screenshots.
2186 input_api = self.makeInputApi([
2187 MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS2,
2188 self.OLD_GRD_CONTENTS, action='M')])
2189 warnings = PRESUBMIT._CheckTranslationScreenshots(input_api,
2190 MockOutputApi())
2191 self.assertEqual(1, len(warnings))
2192 self.assertEqual(self.GENERATE_SIGNATURES_MESSAGE, warnings[0].message)
Mustafa Emre Acerea3e57a2018-12-17 23:51:012193 self.assertEqual([
2194 os.path.join('test_grd', 'IDS_TEST1.png.sha1'),
2195 os.path.join('test_grd', 'IDS_TEST2.png.sha1')
2196 ], warnings[0].items)
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142197
2198 input_api = self.makeInputApi([
2199 MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS2,
2200 self.NEW_GRD_CONTENTS1, action='M')])
2201 warnings = PRESUBMIT._CheckTranslationScreenshots(input_api,
2202 MockOutputApi())
2203 self.assertEqual(1, len(warnings))
2204 self.assertEqual(self.GENERATE_SIGNATURES_MESSAGE, warnings[0].message)
Mustafa Emre Acerea3e57a2018-12-17 23:51:012205 self.assertEqual([os.path.join('test_grd', 'IDS_TEST2.png.sha1')],
2206 warnings[0].items)
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142207
2208
2209 def testUnnecessaryScreenshots(self):
2210 # CL added a single message and added the png file, but not the sha1 file.
2211 input_api = self.makeInputApi([
Mustafa Emre Acerea3e57a2018-12-17 23:51:012212 MockAffectedFile(
2213 'test.grd',
2214 self.NEW_GRD_CONTENTS1,
2215 self.OLD_GRD_CONTENTS,
2216 action='M'),
2217 MockAffectedFile(
2218 os.path.join('test_grd', 'IDS_TEST1.png'), 'binary', action='A')
2219 ])
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142220 warnings = PRESUBMIT._CheckTranslationScreenshots(input_api,
2221 MockOutputApi())
2222 self.assertEqual(2, len(warnings))
2223 self.assertEqual(self.DO_NOT_UPLOAD_PNG_MESSAGE, warnings[0].message)
Mustafa Emre Acerea3e57a2018-12-17 23:51:012224 self.assertEqual([os.path.join('test_grd', 'IDS_TEST1.png')],
2225 warnings[0].items)
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142226 self.assertEqual(self.GENERATE_SIGNATURES_MESSAGE, warnings[1].message)
Mustafa Emre Acerea3e57a2018-12-17 23:51:012227 self.assertEqual([os.path.join('test_grd', 'IDS_TEST1.png.sha1')],
2228 warnings[1].items)
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142229
2230 # CL added two messages, one has a png. Expect two messages:
2231 # - One for the unnecessary png.
2232 # - Another one for missing .sha1 files.
2233 input_api = self.makeInputApi([
Mustafa Emre Acerea3e57a2018-12-17 23:51:012234 MockAffectedFile(
2235 'test.grd',
2236 self.NEW_GRD_CONTENTS2,
2237 self.OLD_GRD_CONTENTS,
2238 action='M'),
2239 MockAffectedFile(
2240 os.path.join('test_grd', 'IDS_TEST1.png'), 'binary', action='A')
2241 ])
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142242 warnings = PRESUBMIT._CheckTranslationScreenshots(input_api,
2243 MockOutputApi())
2244 self.assertEqual(2, len(warnings))
2245 self.assertEqual(self.DO_NOT_UPLOAD_PNG_MESSAGE, warnings[0].message)
Mustafa Emre Acerea3e57a2018-12-17 23:51:012246 self.assertEqual([os.path.join('test_grd', 'IDS_TEST1.png')],
2247 warnings[0].items)
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142248 self.assertEqual(self.GENERATE_SIGNATURES_MESSAGE, warnings[1].message)
Mustafa Emre Acerea3e57a2018-12-17 23:51:012249 self.assertEqual([
2250 os.path.join('test_grd', 'IDS_TEST1.png.sha1'),
2251 os.path.join('test_grd', 'IDS_TEST2.png.sha1')
2252 ], warnings[1].items)
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142253
2254 def testScreenshotsWithSha1(self):
2255 # CL added two messages and their corresponding .sha1 files. No warnings.
2256 input_api = self.makeInputApi([
Mustafa Emre Acerea3e57a2018-12-17 23:51:012257 MockAffectedFile(
2258 'test.grd',
2259 self.NEW_GRD_CONTENTS2,
2260 self.OLD_GRD_CONTENTS,
2261 action='M'),
2262 MockFile(
2263 os.path.join('test_grd', 'IDS_TEST1.png.sha1'),
2264 'binary',
2265 action='A'),
2266 MockFile(
2267 os.path.join('test_grd', 'IDS_TEST2.png.sha1'),
2268 'binary',
2269 action='A')
2270 ])
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142271 warnings = PRESUBMIT._CheckTranslationScreenshots(input_api,
2272 MockOutputApi())
2273 self.assertEqual([], warnings)
2274
2275 def testScreenshotsRemovedWithSha1(self):
2276 # Swap old contents with new contents, remove IDS_TEST1 and IDS_TEST2. The
2277 # sha1 files associated with the messages should also be removed by the CL.
2278 input_api = self.makeInputApi([
Mustafa Emre Acerea3e57a2018-12-17 23:51:012279 MockAffectedFile(
2280 'test.grd',
2281 self.OLD_GRD_CONTENTS,
2282 self.NEW_GRD_CONTENTS2,
2283 action='M'),
2284 MockFile(os.path.join('test_grd', 'IDS_TEST1.png.sha1'), 'binary', ""),
2285 MockFile(os.path.join('test_grd', 'IDS_TEST2.png.sha1'), 'binary', "")
2286 ])
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142287 warnings = PRESUBMIT._CheckTranslationScreenshots(input_api,
2288 MockOutputApi())
2289 self.assertEqual(1, len(warnings))
2290 self.assertEqual(self.REMOVE_SIGNATURES_MESSAGE, warnings[0].message)
Mustafa Emre Acerea3e57a2018-12-17 23:51:012291 self.assertEqual([
2292 os.path.join('test_grd', 'IDS_TEST1.png.sha1'),
2293 os.path.join('test_grd', 'IDS_TEST2.png.sha1')
2294 ], warnings[0].items)
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142295
2296 # Same as above, but this time one of the .sha1 files is removed.
2297 input_api = self.makeInputApi([
Mustafa Emre Acerea3e57a2018-12-17 23:51:012298 MockAffectedFile(
2299 'test.grd',
2300 self.OLD_GRD_CONTENTS,
2301 self.NEW_GRD_CONTENTS2,
2302 action='M'),
2303 MockFile(os.path.join('test_grd', 'IDS_TEST1.png.sha1'), 'binary', ''),
2304 MockAffectedFile(
2305 os.path.join('test_grd', 'IDS_TEST2.png.sha1'),
2306 '',
2307 'old_contents',
2308 action='D')
2309 ])
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142310 warnings = PRESUBMIT._CheckTranslationScreenshots(input_api,
2311 MockOutputApi())
2312 self.assertEqual(1, len(warnings))
2313 self.assertEqual(self.REMOVE_SIGNATURES_MESSAGE, warnings[0].message)
Mustafa Emre Acerea3e57a2018-12-17 23:51:012314 self.assertEqual([os.path.join('test_grd', 'IDS_TEST1.png.sha1')],
2315 warnings[0].items)
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142316
2317 # Remove both sha1 files. No presubmit warnings.
2318 input_api = self.makeInputApi([
Mustafa Emre Acerea3e57a2018-12-17 23:51:012319 MockAffectedFile(
2320 'test.grd',
2321 self.OLD_GRD_CONTENTS,
2322 self.NEW_GRD_CONTENTS2,
2323 action='M'),
2324 MockFile(
2325 os.path.join('test_grd', 'IDS_TEST1.png.sha1'),
2326 'binary',
2327 action='D'),
2328 MockFile(
2329 os.path.join('test_grd', 'IDS_TEST2.png.sha1'),
2330 'binary',
2331 action='D')
2332 ])
Mustafa Emre Acer29bf6ac92018-07-30 21:42:142333 warnings = PRESUBMIT._CheckTranslationScreenshots(input_api,
2334 MockOutputApi())
2335 self.assertEqual([], warnings)
2336
2337
Dominic Battre033531052018-09-24 15:45:342338class DISABLETypoInTest(unittest.TestCase):
2339
2340 def testPositive(self):
2341 # Verify the typo "DISABLE_" instead of "DISABLED_" in various contexts
2342 # where the desire is to disable a test.
2343 tests = [
2344 # Disabled on one platform:
2345 '#if defined(OS_WIN)\n'
2346 '#define MAYBE_FoobarTest DISABLE_FoobarTest\n'
2347 '#else\n'
2348 '#define MAYBE_FoobarTest FoobarTest\n'
2349 '#endif\n',
2350 # Disabled on one platform spread cross lines:
2351 '#if defined(OS_WIN)\n'
2352 '#define MAYBE_FoobarTest \\\n'
2353 ' DISABLE_FoobarTest\n'
2354 '#else\n'
2355 '#define MAYBE_FoobarTest FoobarTest\n'
2356 '#endif\n',
2357 # Disabled on all platforms:
2358 ' TEST_F(FoobarTest, DISABLE_Foo)\n{\n}',
2359 # Disabled on all platforms but multiple lines
2360 ' TEST_F(FoobarTest,\n DISABLE_foo){\n}\n',
2361 ]
2362
2363 for test in tests:
2364 mock_input_api = MockInputApi()
2365 mock_input_api.files = [
2366 MockFile('some/path/foo_unittest.cc', test.splitlines()),
2367 ]
2368
2369 results = PRESUBMIT._CheckNoDISABLETypoInTests(mock_input_api,
2370 MockOutputApi())
2371 self.assertEqual(
2372 1,
2373 len(results),
2374 msg=('expected len(results) == 1 but got %d in test: %s' %
2375 (len(results), test)))
2376 self.assertTrue(
2377 'foo_unittest.cc' in results[0].message,
2378 msg=('expected foo_unittest.cc in message but got %s in test %s' %
2379 (results[0].message, test)))
2380
2381 def testIngoreNotTestFiles(self):
2382 mock_input_api = MockInputApi()
2383 mock_input_api.files = [
2384 MockFile('some/path/foo.cc', 'TEST_F(FoobarTest, DISABLE_Foo)'),
2385 ]
2386
2387 results = PRESUBMIT._CheckNoDISABLETypoInTests(mock_input_api,
2388 MockOutputApi())
2389 self.assertEqual(0, len(results))
2390
Katie Df13948e2018-09-25 07:33:442391 def testIngoreDeletedFiles(self):
2392 mock_input_api = MockInputApi()
2393 mock_input_api.files = [
2394 MockFile('some/path/foo.cc', 'TEST_F(FoobarTest, Foo)', action='D'),
2395 ]
2396
2397 results = PRESUBMIT._CheckNoDISABLETypoInTests(mock_input_api,
2398 MockOutputApi())
2399 self.assertEqual(0, len(results))
Dominic Battre033531052018-09-24 15:45:342400
Dirk Pranke3c18a382019-03-15 01:07:512401
2402class BuildtoolsRevisionsAreInSyncTest(unittest.TestCase):
2403 # TODO(crbug.com/941824): We need to make sure the entries in
2404 # //buildtools/DEPS are kept in sync with the entries in //DEPS
2405 # so that users of //buildtools in other projects get the same tooling
2406 # Chromium gets. If we ever fix the referenced bug and add 'includedeps'
2407 # support to gclient, we can eliminate the duplication and delete
2408 # these tests for the corresponding presubmit check.
2409
2410 def _check(self, files):
2411 mock_input_api = MockInputApi()
2412 mock_input_api.files = []
2413 for fname, contents in files.items():
2414 mock_input_api.files.append(MockFile(fname, contents.splitlines()))
2415 return PRESUBMIT._CheckBuildtoolsRevisionsAreInSync(mock_input_api,
2416 MockOutputApi())
2417
2418 def testOneFileChangedButNotTheOther(self):
2419 results = self._check({
2420 "DEPS": "'libunwind_revision': 'onerev'",
2421 })
2422 self.assertNotEqual(results, [])
2423
2424 def testNeitherFileChanged(self):
2425 results = self._check({
2426 "OWNERS": "[email protected]",
2427 })
2428 self.assertEqual(results, [])
2429
2430 def testBothFilesChangedAndMatch(self):
2431 results = self._check({
2432 "DEPS": "'libunwind_revision': 'onerev'",
2433 "buildtools/DEPS": "'libunwind_revision': 'onerev'",
2434 })
2435 self.assertEqual(results, [])
2436
2437 def testBothFilesWereChangedAndDontMatch(self):
2438 results = self._check({
2439 "DEPS": "'libunwind_revision': 'onerev'",
2440 "buildtools/DEPS": "'libunwind_revision': 'anotherrev'",
2441 })
2442 self.assertNotEqual(results, [])
2443
2444
[email protected]2299dcf2012-11-15 19:56:242445if __name__ == '__main__':
2446 unittest.main()