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.
15 from PRESUBMIT_test_mocks
import MockChange
, MockFile
, MockAffectedFile
16 from PRESUBMIT_test_mocks
import MockInputApi
, MockOutputApi
18 _TEST_DATA_DIR
= 'base/test/data/presubmit'
20 class IncludeOrderTest(unittest
.TestCase
):
21 def testSystemHeaderOrder(self
):
22 scope
= [(1, '#include <csystem.h>'),
23 (2, '#include <cppsystem>'),
24 (3, '#include "acustom.h"')]
25 all_linenums
= [linenum
for (linenum
, _
) in scope
]
26 mock_input_api
= MockInputApi()
27 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
29 self
.assertEqual(0, len(warnings
))
31 def testSystemHeaderOrderMismatch1(self
):
32 scope
= [(10, '#include <cppsystem>'),
33 (20, '#include <csystem.h>'),
34 (30, '#include "acustom.h"')]
35 all_linenums
= [linenum
for (linenum
, _
) in scope
]
36 mock_input_api
= MockInputApi()
37 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
39 self
.assertEqual(1, len(warnings
))
40 self
.assertTrue('20' in warnings
[0])
42 def testSystemHeaderOrderMismatch2(self
):
43 scope
= [(10, '#include <cppsystem>'),
44 (20, '#include "acustom.h"'),
45 (30, '#include <csystem.h>')]
46 all_linenums
= [linenum
for (linenum
, _
) in scope
]
47 mock_input_api
= MockInputApi()
48 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
50 self
.assertEqual(1, len(warnings
))
51 self
.assertTrue('30' in warnings
[0])
53 def testSystemHeaderOrderMismatch3(self
):
54 scope
= [(10, '#include "acustom.h"'),
55 (20, '#include <csystem.h>'),
56 (30, '#include <cppsystem>')]
57 all_linenums
= [linenum
for (linenum
, _
) in scope
]
58 mock_input_api
= MockInputApi()
59 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
61 self
.assertEqual(2, len(warnings
))
62 self
.assertTrue('20' in warnings
[0])
63 self
.assertTrue('30' in warnings
[1])
65 def testAlphabeticalOrderMismatch(self
):
66 scope
= [(10, '#include <csystem.h>'),
67 (15, '#include <bsystem.h>'),
68 (20, '#include <cppsystem>'),
69 (25, '#include <bppsystem>'),
70 (30, '#include "bcustom.h"'),
71 (35, '#include "acustom.h"')]
72 all_linenums
= [linenum
for (linenum
, _
) in scope
]
73 mock_input_api
= MockInputApi()
74 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
76 self
.assertEqual(3, len(warnings
))
77 self
.assertTrue('15' in warnings
[0])
78 self
.assertTrue('25' in warnings
[1])
79 self
.assertTrue('35' in warnings
[2])
81 def testSpecialFirstInclude1(self
):
82 mock_input_api
= MockInputApi()
83 contents
= ['#include "some/path/foo.h"',
84 '#include "a/header.h"']
85 mock_file
= MockFile('some/path/foo.cc', contents
)
86 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
87 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
88 self
.assertEqual(0, len(warnings
))
90 def testSpecialFirstInclude2(self
):
91 mock_input_api
= MockInputApi()
92 contents
= ['#include "some/other/path/foo.h"',
93 '#include "a/header.h"']
94 mock_file
= MockFile('some/path/foo.cc', contents
)
95 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
96 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
97 self
.assertEqual(0, len(warnings
))
99 def testSpecialFirstInclude3(self
):
100 mock_input_api
= MockInputApi()
101 contents
= ['#include "some/path/foo.h"',
102 '#include "a/header.h"']
103 mock_file
= MockFile('some/path/foo_platform.cc', contents
)
104 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
105 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
106 self
.assertEqual(0, len(warnings
))
108 def testSpecialFirstInclude4(self
):
109 mock_input_api
= MockInputApi()
110 contents
= ['#include "some/path/bar.h"',
111 '#include "a/header.h"']
112 mock_file
= MockFile('some/path/foo_platform.cc', contents
)
113 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
114 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
115 self
.assertEqual(1, len(warnings
))
116 self
.assertTrue('2' in warnings
[0])
118 def testSpecialFirstInclude5(self
):
119 mock_input_api
= MockInputApi()
120 contents
= ['#include "some/other/path/foo.h"',
121 '#include "a/header.h"']
122 mock_file
= MockFile('some/path/foo-suffix.h', contents
)
123 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
124 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
125 self
.assertEqual(0, len(warnings
))
127 def testSpecialFirstInclude6(self
):
128 mock_input_api
= MockInputApi()
129 contents
= ['#include "some/other/path/foo_win.h"',
131 '#include "a/header.h"']
132 mock_file
= MockFile('some/path/foo_unittest_win.h', contents
)
133 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
134 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
135 self
.assertEqual(0, len(warnings
))
137 def testOrderAlreadyWrong(self
):
138 scope
= [(1, '#include "b.h"'),
139 (2, '#include "a.h"'),
140 (3, '#include "c.h"')]
141 mock_input_api
= MockInputApi()
142 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
144 self
.assertEqual(0, len(warnings
))
146 def testConflictAdded1(self
):
147 scope
= [(1, '#include "a.h"'),
148 (2, '#include "c.h"'),
149 (3, '#include "b.h"')]
150 mock_input_api
= MockInputApi()
151 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
153 self
.assertEqual(1, len(warnings
))
154 self
.assertTrue('3' in warnings
[0])
156 def testConflictAdded2(self
):
157 scope
= [(1, '#include "c.h"'),
158 (2, '#include "b.h"'),
159 (3, '#include "d.h"')]
160 mock_input_api
= MockInputApi()
161 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
163 self
.assertEqual(1, len(warnings
))
164 self
.assertTrue('2' in warnings
[0])
166 def testIfElifElseEndif(self
):
167 mock_input_api
= MockInputApi()
168 contents
= ['#include "e.h"',
181 mock_file
= MockFile('', contents
)
182 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
183 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
184 self
.assertEqual(0, len(warnings
))
186 def testExcludedIncludes(self
):
187 # #include <sys/...>'s can appear in any order.
188 mock_input_api
= MockInputApi()
189 contents
= ['#include <sys/b.h>',
190 '#include <sys/a.h>']
191 mock_file
= MockFile('', contents
)
192 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
193 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
194 self
.assertEqual(0, len(warnings
))
196 contents
= ['#include <atlbase.h>',
198 mock_file
= MockFile('', contents
)
199 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
200 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
201 self
.assertEqual(0, len(warnings
))
203 contents
= ['#include "build/build_config.h"',
205 mock_file
= MockFile('', contents
)
206 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
207 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
208 self
.assertEqual(0, len(warnings
))
210 def testCheckOnlyCFiles(self
):
211 mock_input_api
= MockInputApi()
212 mock_output_api
= MockOutputApi()
213 contents
= ['#include <b.h>',
215 mock_file_cc
= MockFile('something.cc', contents
)
216 mock_file_h
= MockFile('something.h', contents
)
217 mock_file_other
= MockFile('something.py', contents
)
218 mock_input_api
.files
= [mock_file_cc
, mock_file_h
, mock_file_other
]
219 warnings
= PRESUBMIT
._CheckIncludeOrder
(mock_input_api
, mock_output_api
)
220 self
.assertEqual(1, len(warnings
))
221 self
.assertEqual(2, len(warnings
[0].items
))
222 self
.assertEqual('promptOrNotify', warnings
[0].type)
224 def testUncheckableIncludes(self
):
225 mock_input_api
= MockInputApi()
226 contents
= ['#include <windows.h>',
229 mock_file
= MockFile('', contents
)
230 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
231 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
232 self
.assertEqual(1, len(warnings
))
234 contents
= ['#include "gpu/command_buffer/gles_autogen.h"',
237 mock_file
= MockFile('', contents
)
238 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
239 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
240 self
.assertEqual(1, len(warnings
))
242 contents
= ['#include "gl_mock_autogen.h"',
245 mock_file
= MockFile('', contents
)
246 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
247 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
248 self
.assertEqual(1, len(warnings
))
250 contents
= ['#include "ipc/some_macros.h"',
253 mock_file
= MockFile('', contents
)
254 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
255 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
256 self
.assertEqual(1, len(warnings
))
259 class VersionControlConflictsTest(unittest
.TestCase
):
260 def testTypicalConflict(self
):
261 lines
= ['<<<<<<< HEAD',
262 ' base::ScopedTempDir temp_dir_;',
264 ' ScopedTempDir temp_dir_;',
266 errors
= PRESUBMIT
._CheckForVersionControlConflictsInFile
(
267 MockInputApi(), MockFile('some/path/foo_platform.cc', lines
))
268 self
.assertEqual(3, len(errors
))
269 self
.assertTrue('1' in errors
[0])
270 self
.assertTrue('3' in errors
[1])
271 self
.assertTrue('5' in errors
[2])
273 class UmaHistogramChangeMatchedOrNotTest(unittest
.TestCase
):
274 def testTypicalCorrectlyMatchedChange(self
):
275 diff_cc
= ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
276 diff_xml
= ['<histogram name="Bla.Foo.Dummy"> </histogram>']
277 mock_input_api
= MockInputApi()
278 mock_input_api
.files
= [
279 MockFile('some/path/foo.cc', diff_cc
),
280 MockFile('tools/metrics/histograms/histograms.xml', diff_xml
),
282 warnings
= PRESUBMIT
._CheckUmaHistogramChanges
(mock_input_api
,
284 self
.assertEqual(0, len(warnings
))
286 def testTypicalNotMatchedChange(self
):
287 diff_cc
= ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
288 mock_input_api
= MockInputApi()
289 mock_input_api
.files
= [MockFile('some/path/foo.cc', diff_cc
)]
290 warnings
= PRESUBMIT
._CheckUmaHistogramChanges
(mock_input_api
,
292 self
.assertEqual(1, len(warnings
))
293 self
.assertEqual('warning', warnings
[0].type)
295 def testTypicalNotMatchedChangeViaSuffixes(self
):
296 diff_cc
= ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
297 diff_xml
= ['<histogram_suffixes name="SuperHistogram">',
298 ' <suffix name="Dummy"/>',
299 ' <affected-histogram name="Snafu.Dummy"/>',
301 mock_input_api
= MockInputApi()
302 mock_input_api
.files
= [
303 MockFile('some/path/foo.cc', diff_cc
),
304 MockFile('tools/metrics/histograms/histograms.xml', diff_xml
),
306 warnings
= PRESUBMIT
._CheckUmaHistogramChanges
(mock_input_api
,
308 self
.assertEqual(1, len(warnings
))
309 self
.assertEqual('warning', warnings
[0].type)
311 def testTypicalCorrectlyMatchedChangeViaSuffixes(self
):
312 diff_cc
= ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
313 diff_xml
= ['<histogram_suffixes name="SuperHistogram">',
314 ' <suffix name="Dummy"/>',
315 ' <affected-histogram name="Bla.Foo"/>',
317 mock_input_api
= MockInputApi()
318 mock_input_api
.files
= [
319 MockFile('some/path/foo.cc', diff_cc
),
320 MockFile('tools/metrics/histograms/histograms.xml', diff_xml
),
322 warnings
= PRESUBMIT
._CheckUmaHistogramChanges
(mock_input_api
,
324 self
.assertEqual(0, len(warnings
))
326 def testTypicalCorrectlyMatchedChangeViaSuffixesWithSeparator(self
):
327 diff_cc
= ['UMA_HISTOGRAM_BOOL("Snafu_Dummy", true)']
328 diff_xml
= ['<histogram_suffixes name="SuperHistogram" separator="_">',
329 ' <suffix name="Dummy"/>',
330 ' <affected-histogram name="Snafu"/>',
332 mock_input_api
= MockInputApi()
333 mock_input_api
.files
= [
334 MockFile('some/path/foo.cc', diff_cc
),
335 MockFile('tools/metrics/histograms/histograms.xml', diff_xml
),
337 warnings
= PRESUBMIT
._CheckUmaHistogramChanges
(mock_input_api
,
339 self
.assertEqual(0, len(warnings
))
341 class BadExtensionsTest(unittest
.TestCase
):
342 def testBadRejFile(self
):
343 mock_input_api
= MockInputApi()
344 mock_input_api
.files
= [
345 MockFile('some/path/foo.cc', ''),
346 MockFile('some/path/foo.cc.rej', ''),
347 MockFile('some/path2/bar.h.rej', ''),
350 results
= PRESUBMIT
._CheckPatchFiles
(mock_input_api
, MockOutputApi())
351 self
.assertEqual(1, len(results
))
352 self
.assertEqual(2, len(results
[0].items
))
353 self
.assertTrue('foo.cc.rej' in results
[0].items
[0])
354 self
.assertTrue('bar.h.rej' in results
[0].items
[1])
356 def testBadOrigFile(self
):
357 mock_input_api
= MockInputApi()
358 mock_input_api
.files
= [
359 MockFile('other/path/qux.h.orig', ''),
360 MockFile('other/path/qux.h', ''),
361 MockFile('other/path/qux.cc', ''),
364 results
= PRESUBMIT
._CheckPatchFiles
(mock_input_api
, MockOutputApi())
365 self
.assertEqual(1, len(results
))
366 self
.assertEqual(1, len(results
[0].items
))
367 self
.assertTrue('qux.h.orig' in results
[0].items
[0])
369 def testGoodFiles(self
):
370 mock_input_api
= MockInputApi()
371 mock_input_api
.files
= [
372 MockFile('other/path/qux.h', ''),
373 MockFile('other/path/qux.cc', ''),
375 results
= PRESUBMIT
._CheckPatchFiles
(mock_input_api
, MockOutputApi())
376 self
.assertEqual(0, len(results
))
379 class CheckSingletonInHeadersTest(unittest
.TestCase
):
380 def testSingletonInArbitraryHeader(self
):
381 diff_singleton_h
= ['base::subtle::AtomicWord '
382 'Singleton<Type, Traits, DifferentiatingType>::']
383 diff_foo_h
= ['// Singleton<Foo> in comment.',
384 'friend class Singleton<Foo>']
385 diff_bad_h
= ['Foo* foo = Singleton<Foo>::get();']
386 mock_input_api
= MockInputApi()
387 mock_input_api
.files
= [MockAffectedFile('base/memory/singleton.h',
389 MockAffectedFile('foo.h', diff_foo_h
),
390 MockAffectedFile('bad.h', diff_bad_h
)]
391 warnings
= PRESUBMIT
._CheckSingletonInHeaders
(mock_input_api
,
393 self
.assertEqual(1, len(warnings
))
394 self
.assertEqual('error', warnings
[0].type)
395 self
.assertTrue('Found Singleton<T>' in warnings
[0].message
)
397 def testSingletonInCC(self
):
398 diff_cc
= ['Foo* foo = Singleton<Foo>::get();']
399 mock_input_api
= MockInputApi()
400 mock_input_api
.files
= [MockAffectedFile('some/path/foo.cc', diff_cc
)]
401 warnings
= PRESUBMIT
._CheckSingletonInHeaders
(mock_input_api
,
403 self
.assertEqual(0, len(warnings
))
406 class InvalidOSMacroNamesTest(unittest
.TestCase
):
407 def testInvalidOSMacroNames(self
):
408 lines
= ['#if defined(OS_WINDOWS)',
409 ' #elif defined(OS_WINDOW)',
410 ' # if defined(OS_MACOSX) || defined(OS_CHROME)',
411 '# else // defined(OS_MAC)',
412 '#endif // defined(OS_MACOS)']
413 errors
= PRESUBMIT
._CheckForInvalidOSMacrosInFile
(
414 MockInputApi(), MockFile('some/path/foo_platform.cc', lines
))
415 self
.assertEqual(len(lines
), len(errors
))
416 self
.assertTrue(':1 OS_WINDOWS' in errors
[0])
417 self
.assertTrue('(did you mean OS_WIN?)' in errors
[0])
419 def testValidOSMacroNames(self
):
420 lines
= ['#if defined(%s)' % m
for m
in PRESUBMIT
._VALID
_OS
_MACROS
]
421 errors
= PRESUBMIT
._CheckForInvalidOSMacrosInFile
(
422 MockInputApi(), MockFile('some/path/foo_platform.cc', lines
))
423 self
.assertEqual(0, len(errors
))
426 class InvalidIfDefinedMacroNamesTest(unittest
.TestCase
):
427 def testInvalidIfDefinedMacroNames(self
):
428 lines
= ['#if defined(TARGET_IPHONE_SIMULATOR)',
429 '#if !defined(TARGET_IPHONE_SIMULATOR)',
430 '#elif defined(TARGET_IPHONE_SIMULATOR)',
431 '#ifdef TARGET_IPHONE_SIMULATOR',
432 ' # ifdef TARGET_IPHONE_SIMULATOR',
433 '# if defined(VALID) || defined(TARGET_IPHONE_SIMULATOR)',
434 '# else // defined(TARGET_IPHONE_SIMULATOR)',
435 '#endif // defined(TARGET_IPHONE_SIMULATOR)',]
436 errors
= PRESUBMIT
._CheckForInvalidIfDefinedMacrosInFile
(
437 MockInputApi(), MockFile('some/path/source.mm', lines
))
438 self
.assertEqual(len(lines
), len(errors
))
440 def testValidIfDefinedMacroNames(self
):
441 lines
= ['#if defined(FOO)',
443 errors
= PRESUBMIT
._CheckForInvalidIfDefinedMacrosInFile
(
444 MockInputApi(), MockFile('some/path/source.cc', lines
))
445 self
.assertEqual(0, len(errors
))
448 class CheckAddedDepsHaveTetsApprovalsTest(unittest
.TestCase
):
449 def testFilesToCheckForIncomingDeps(self
):
452 '"+chrome/installer",',
453 '"+chrome/plugin/chrome_content_plugin_client.h",',
454 '"+chrome/utility/chrome_content_utility_client.h",',
455 '"+chromeos/chromeos_paths.h",',
456 '"+components/crash",',
457 '"+components/nacl/common",',
458 '"+content/public/browser/render_process_host.h",',
460 '"+grit", # For generated headers',
461 '"+grit/generated_resources.h",',
463 '"+policy", # For generated headers and source',
465 '"+tools/memory_watcher",',
466 '"+third_party/lss/linux_syscall_support.h",',
468 files_to_check
= PRESUBMIT
._FilesToCheckForIncomingDeps
(re
, changed_lines
)
471 'chrome/installer/DEPS',
472 'chrome/plugin/chrome_content_plugin_client.h',
473 'chrome/utility/chrome_content_utility_client.h',
474 'chromeos/chromeos_paths.h',
475 'components/crash/DEPS',
476 'components/nacl/common/DEPS',
477 'content/public/browser/render_process_host.h',
480 'tools/memory_watcher/DEPS',
481 'third_party/lss/linux_syscall_support.h',
483 self
.assertEqual(expected
, files_to_check
);
486 class JSONParsingTest(unittest
.TestCase
):
487 def testSuccess(self
):
488 input_api
= MockInputApi()
489 filename
= 'valid_json.json'
490 contents
= ['// This is a comment.',
492 ' "key1": ["value1", "value2"],',
493 ' "key2": 3 // This is an inline comment.',
496 input_api
.files
= [MockFile(filename
, contents
)]
497 self
.assertEqual(None,
498 PRESUBMIT
._GetJSONParseError
(input_api
, filename
))
500 def testFailure(self
):
501 input_api
= MockInputApi()
503 ('invalid_json_1.json',
505 'Expecting property name:'),
506 ('invalid_json_2.json',
508 '{ "hello": "world }'],
509 'Unterminated string starting at:'),
510 ('invalid_json_3.json',
511 ['{ "a": "b", "c": "d", }'],
512 'Expecting property name:'),
513 ('invalid_json_4.json',
514 ['{ "a": "b" "c": "d" }'],
515 'Expecting , delimiter:'),
518 input_api
.files
= [MockFile(filename
, contents
)
519 for (filename
, contents
, _
) in test_data
]
521 for (filename
, _
, expected_error
) in test_data
:
522 actual_error
= PRESUBMIT
._GetJSONParseError
(input_api
, filename
)
523 self
.assertTrue(expected_error
in str(actual_error
),
524 "'%s' not found in '%s'" % (expected_error
, actual_error
))
526 def testNoEatComments(self
):
527 input_api
= MockInputApi()
528 file_with_comments
= 'file_with_comments.json'
529 contents_with_comments
= ['// This is a comment.',
531 ' "key1": ["value1", "value2"],',
532 ' "key2": 3 // This is an inline comment.',
535 file_without_comments
= 'file_without_comments.json'
536 contents_without_comments
= ['{',
537 ' "key1": ["value1", "value2"],',
541 input_api
.files
= [MockFile(file_with_comments
, contents_with_comments
),
542 MockFile(file_without_comments
,
543 contents_without_comments
)]
545 self
.assertEqual('No JSON object could be decoded',
546 str(PRESUBMIT
._GetJSONParseError
(input_api
,
548 eat_comments
=False)))
549 self
.assertEqual(None,
550 PRESUBMIT
._GetJSONParseError
(input_api
,
551 file_without_comments
,
555 class IDLParsingTest(unittest
.TestCase
):
556 def testSuccess(self
):
557 input_api
= MockInputApi()
558 filename
= 'valid_idl_basics.idl'
559 contents
= ['// Tests a valid IDL file.',
560 'namespace idl_basics {',
566 ' dictionary MyType1 {',
570 ' callback Callback1 = void();',
571 ' callback Callback2 = void(long x);',
572 ' callback Callback3 = void(MyType1 arg);',
573 ' callback Callback4 = void(EnumType type);',
575 ' interface Functions {',
576 ' static void function1();',
577 ' static void function2(long x);',
578 ' static void function3(MyType1 arg);',
579 ' static void function4(Callback1 cb);',
580 ' static void function5(Callback2 cb);',
581 ' static void function6(Callback3 cb);',
582 ' static void function7(Callback4 cb);',
585 ' interface Events {',
586 ' static void onFoo1();',
587 ' static void onFoo2(long x);',
588 ' static void onFoo2(MyType1 arg);',
589 ' static void onFoo3(EnumType type);',
593 input_api
.files
= [MockFile(filename
, contents
)]
594 self
.assertEqual(None,
595 PRESUBMIT
._GetIDLParseError
(input_api
, filename
))
597 def testFailure(self
):
598 input_api
= MockInputApi()
600 ('invalid_idl_1.idl',
607 'Unexpected "{" after keyword "dictionary".\n'),
608 # TODO(yoz): Disabled because it causes the IDL parser to hang.
609 # See crbug.com/363830.
610 # ('invalid_idl_2.idl',
611 # (['namespace test {',
612 # ' dictionary MissingSemicolon {',
617 # 'Unexpected symbol DOMString after symbol a.'),
618 ('invalid_idl_3.idl',
621 ' enum MissingComma {',
626 'Unexpected symbol name2 after symbol name1.'),
627 ('invalid_idl_4.idl',
630 ' enum TrailingComma {',
635 'Trailing comma in block.'),
636 ('invalid_idl_5.idl',
639 ' callback Callback1 = void(;',
641 'Unexpected ";" after "(".'),
642 ('invalid_idl_6.idl',
645 ' callback Callback1 = void(long );',
647 'Unexpected ")" after symbol long.'),
648 ('invalid_idl_7.idl',
651 ' interace Events {',
652 ' static void onFoo1();',
655 'Unexpected symbol Events after symbol interace.'),
656 ('invalid_idl_8.idl',
659 ' interface NotEvent {',
660 ' static void onFoo1();',
663 'Did not process Interface Interface(NotEvent)'),
664 ('invalid_idl_9.idl',
668 ' static void function1();',
671 'Interface missing name.'),
674 input_api
.files
= [MockFile(filename
, contents
)
675 for (filename
, contents
, _
) in test_data
]
677 for (filename
, _
, expected_error
) in test_data
:
678 actual_error
= PRESUBMIT
._GetIDLParseError
(input_api
, filename
)
679 self
.assertTrue(expected_error
in str(actual_error
),
680 "'%s' not found in '%s'" % (expected_error
, actual_error
))
683 class TryServerMasterTest(unittest
.TestCase
):
684 def testTryServerMasters(self
):
686 'tryserver.chromium.mac': [
689 'ios_rel_device_ninja',
692 'mac_chromium_compile_dbg',
693 'mac_chromium_compile_rel',
697 'mac_nacl_sdk_build',
703 'tryserver.chromium.linux': [
705 'android_chromium_gn_compile_dbg',
706 'android_chromium_gn_compile_rel',
709 'android_dbg_recipe',
710 'android_dbg_triggered_tests',
711 'android_dbg_triggered_tests_recipe',
713 'android_fyi_dbg_triggered_tests',
715 'android_rel_triggered_tests',
717 'blink_android_compile_dbg',
718 'blink_android_compile_rel',
720 'chromium_presubmit',
721 'linux_arm_cross_compile',
723 'linux_chromeos_asan',
724 'linux_chromeos_browser_asan',
725 'linux_chromeos_valgrind',
726 'linux_chromium_chromeos_dbg',
727 'linux_chromium_chromeos_rel',
728 'linux_chromium_compile_dbg',
729 'linux_chromium_compile_rel',
730 'linux_chromium_dbg',
731 'linux_chromium_gn_dbg',
732 'linux_chromium_gn_rel',
733 'linux_chromium_rel',
734 'linux_chromium_trusty32_dbg',
735 'linux_chromium_trusty32_rel',
736 'linux_chromium_trusty_dbg',
737 'linux_chromium_trusty_rel',
743 'linux_layout_rel_32',
745 'linux_nacl_sdk_bionic',
746 'linux_nacl_sdk_bionic_build',
747 'linux_nacl_sdk_build',
749 'linux_rel_naclmore',
750 'linux_rel_precise32',
752 'tools_build_presubmit',
754 'tryserver.chromium.win': [
758 'win_chromium_compile_dbg',
759 'win_chromium_compile_rel',
763 'win_chromium_x64_dbg',
764 'win_chromium_x64_rel',
767 'win_nacl_sdk_build',
771 for master
, bots
in bots
.iteritems():
773 self
.assertEqual(master
, PRESUBMIT
.GetTryServerMasterForBot(bot
),
774 'bot=%s: expected %s, computed %s' % (
775 bot
, master
, PRESUBMIT
.GetTryServerMasterForBot(bot
)))
778 class UserMetricsActionTest(unittest
.TestCase
):
779 def testUserMetricsActionInActions(self
):
780 input_api
= MockInputApi()
781 file_with_user_action
= 'file_with_user_action.cc'
782 contents_with_user_action
= [
783 'base::UserMetricsAction("AboutChrome")'
786 input_api
.files
= [MockFile(file_with_user_action
,
787 contents_with_user_action
)]
790 [], PRESUBMIT
._CheckUserActionUpdate
(input_api
, MockOutputApi()))
793 def testUserMetricsActionNotAddedToActions(self
):
794 input_api
= MockInputApi()
795 file_with_user_action
= 'file_with_user_action.cc'
796 contents_with_user_action
= [
797 'base::UserMetricsAction("NotInActionsXml")'
800 input_api
.files
= [MockFile(file_with_user_action
,
801 contents_with_user_action
)]
803 output
= PRESUBMIT
._CheckUserActionUpdate
(input_api
, MockOutputApi())
805 ('File %s line %d: %s is missing in '
806 'tools/metrics/actions/actions.xml. Please run '
807 'tools/metrics/actions/extract_actions.py to update.'
808 % (file_with_user_action
, 1, 'NotInActionsXml')),
812 class LogUsageTest(unittest
.TestCase
):
814 def testCheckNoNewUtilLogUsage(self
):
815 mock_input_api
= MockInputApi()
816 mock_output_api
= MockOutputApi()
818 mock_input_api
.files
= [
819 MockAffectedFile('RandomStuff.java', [
822 MockAffectedFile('HasCrLog.java', [
823 'import org.chromium.base.Log;',
825 'Log.d("TAG", "foo");',
827 MockAffectedFile('HasAndroidLog.java', [
828 'import android.util.Log;',
830 'Log.d("TAG", "foo");',
832 MockAffectedFile('HasExplicitLog.java', [
834 'android.util.Log.d("TAG", "foo");',
836 MockAffectedFile('HasBothLog.java', [
837 'import org.chromium.base.Log;',
839 'Log.d("TAG", "foo");',
840 'android.util.Log.d("TAG", "foo");',
844 warnings
= PRESUBMIT
._CheckNoNewUtilLogUsage
(
845 mock_input_api
, mock_output_api
)
847 self
.assertEqual(1, len(warnings
))
848 self
.assertEqual(2, len(warnings
[0].items
))
849 self
.assertTrue('HasAndroidLog.java' in warnings
[0].items
[0])
850 self
.assertTrue('HasExplicitLog.java' in warnings
[0].items
[1])
853 if __name__
== '__main__':