Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: PRESUBMIT_test.py

Issue 239283008: Add global presubmit that JSON and IDL files can be parsed. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « PRESUBMIT.py ('k') | chrome/common/extensions/api/PRESUBMIT.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 import glob
7 import json
6 import os 8 import os
7 import re 9 import re
10 import subprocess
11 import sys
8 import unittest 12 import unittest
9 13
10 import PRESUBMIT 14 import PRESUBMIT
11 15
12 16
17 _TEST_DATA_DIR = 'base/test/data/presubmit'
18
19
13 class MockInputApi(object): 20 class MockInputApi(object):
14 def __init__(self): 21 def __init__(self):
22 self.json = json
15 self.re = re 23 self.re = re
16 self.os_path = os.path 24 self.os_path = os.path
25 self.python_executable = sys.executable
26 self.subprocess = subprocess
17 self.files = [] 27 self.files = []
18 self.is_committing = False 28 self.is_committing = False
19 29
20 def AffectedFiles(self): 30 def AffectedFiles(self):
21 return self.files 31 return self.files
22 32
33 def PresubmitLocalPath(self):
34 return os.path.dirname(__file__)
35
36 def ReadFile(self, filename, mode='rU'):
37 for file_ in self.files:
38 if file_.LocalPath() == filename:
39 return '\n'.join(file_.NewContents())
40 # Otherwise, file is not in our mock API.
41 raise IOError, "No such file or directory: '%s'" % filename
42
23 43
24 class MockOutputApi(object): 44 class MockOutputApi(object):
25 class PresubmitResult(object): 45 class PresubmitResult(object):
26 def __init__(self, message, items=None, long_text=''): 46 def __init__(self, message, items=None, long_text=''):
27 self.message = message 47 self.message = message
28 self.items = items 48 self.items = items
29 self.long_text = long_text 49 self.long_text = long_text
30 50
31 class PresubmitError(PresubmitResult): 51 class PresubmitError(PresubmitResult):
32 def __init__(self, message, items, long_text=''): 52 def __init__(self, message, items, long_text=''):
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 'components/nacl/common/DEPS', 444 'components/nacl/common/DEPS',
425 'content/public/browser/render_process_host.h', 445 'content/public/browser/render_process_host.h',
426 'policy/DEPS', 446 'policy/DEPS',
427 'sandbox/DEPS', 447 'sandbox/DEPS',
428 'tools/memory_watcher/DEPS', 448 'tools/memory_watcher/DEPS',
429 'third_party/lss/linux_syscall_support.h', 449 'third_party/lss/linux_syscall_support.h',
430 ]) 450 ])
431 self.assertEqual(expected, files_to_check); 451 self.assertEqual(expected, files_to_check);
432 452
433 453
454 class JSONParsingTest(unittest.TestCase):
455 def testSuccess(self):
456 input_api = MockInputApi()
457 filename = 'valid_json.json'
458 contents = ['// This is a comment.',
459 '{',
460 ' "key1": ["value1", "value2"],',
461 ' "key2": 3 // This is an inline comment.',
462 '}'
463 ]
464 input_api.files = [MockFile(filename, contents)]
465 self.assertEqual(None,
466 PRESUBMIT._GetJSONParseError(input_api, filename))
467
468 def testFailure(self):
469 input_api = MockInputApi()
470 test_data = [
471 ('invalid_json_1.json',
472 ['{ x }'],
473 'Expecting property name: line 1 column 2 (char 2)'),
474 ('invalid_json_2.json',
475 ['// Hello world!',
476 '{ "hello": "world }'],
477 'Unterminated string starting at: line 2 column 12 (char 12)'),
478 ('invalid_json_3.json',
479 ['{ "a": "b", "c": "d", }'],
480 'Expecting property name: line 1 column 22 (char 22)'),
481 ('invalid_json_4.json',
482 ['{ "a": "b" "c": "d" }'],
483 'Expecting , delimiter: line 1 column 11 (char 11)'),
484 ]
485
486 input_api.files = [MockFile(filename, contents)
487 for (filename, contents, _) in test_data]
488
489 for (filename, _, expected_error) in test_data:
490 actual_error = PRESUBMIT._GetJSONParseError(input_api, filename)
491 self.assertEqual(expected_error, str(actual_error))
492
493 def testNoEatComments(self):
494 input_api = MockInputApi()
495 file_with_comments = 'file_with_comments.json'
496 contents_with_comments = ['// This is a comment.',
497 '{',
498 ' "key1": ["value1", "value2"],',
499 ' "key2": 3 // This is an inline comment.',
500 '}'
501 ]
502 file_without_comments = 'file_without_comments.json'
503 contents_without_comments = ['{',
504 ' "key1": ["value1", "value2"],',
505 ' "key2": 3',
506 '}'
507 ]
508 input_api.files = [MockFile(file_with_comments, contents_with_comments),
509 MockFile(file_without_comments,
510 contents_without_comments)]
511
512 self.assertEqual('No JSON object could be decoded',
513 str(PRESUBMIT._GetJSONParseError(input_api,
514 file_with_comments,
515 eat_comments=False)))
516 self.assertEqual(None,
517 PRESUBMIT._GetJSONParseError(input_api,
518 file_without_comments,
519 eat_comments=False))
520
521
522 class IDLParsingTest(unittest.TestCase):
523 def testSuccess(self):
524 input_api = MockInputApi()
525 filename = 'valid_idl_basics.idl'
526 contents = ['// Tests a valid IDL file.',
527 'namespace idl_basics {',
528 ' enum EnumType {',
529 ' name1,',
530 ' name2',
531 ' };',
532 '',
533 ' dictionary MyType1 {',
534 ' DOMString a;',
535 ' };',
536 '',
537 ' callback Callback1 = void();',
538 ' callback Callback2 = void(long x);',
539 ' callback Callback3 = void(MyType1 arg);',
540 ' callback Callback4 = void(EnumType type);',
541 '',
542 ' interface Functions {',
543 ' static void function1();',
544 ' static void function2(long x);',
545 ' static void function3(MyType1 arg);',
546 ' static void function4(Callback1 cb);',
547 ' static void function5(Callback2 cb);',
548 ' static void function6(Callback3 cb);',
549 ' static void function7(Callback4 cb);',
550 ' };',
551 '',
552 ' interface Events {',
553 ' static void onFoo1();',
554 ' static void onFoo2(long x);',
555 ' static void onFoo2(MyType1 arg);',
556 ' static void onFoo3(EnumType type);',
557 ' };',
558 '};'
559 ]
560 input_api.files = [MockFile(filename, contents)]
561 self.assertEqual(None,
562 PRESUBMIT._GetIDLParseError(input_api, filename))
563
564 def testFailure(self):
565 input_api = MockInputApi()
566 test_data = [
567 ('invalid_idl_1.idl',
568 ['//',
569 'namespace test {',
570 ' dictionary {',
571 ' DOMString s;',
572 ' };',
573 '};'],
574 'Unexpected "{" after keyword "dictionary".\n'),
575 # TODO(yoz): Disabled because it causes the IDL parser to hang.
576 # See crbug.com/363830.
577 # ('invalid_idl_2.idl',
578 # (['namespace test {',
579 # ' dictionary MissingSemicolon {',
580 # ' DOMString a',
581 # ' DOMString b;',
582 # ' };',
583 # '};'],
584 # 'Unexpected symbol DOMString after symbol a.'),
585 ('invalid_idl_3.idl',
586 ['//',
587 'namespace test {',
588 ' enum MissingComma {',
589 ' name1',
590 ' name2',
591 ' };',
592 '};'],
593 'Unexpected symbol name2 after symbol name1.'),
594 ('invalid_idl_4.idl',
595 ['//',
596 'namespace test {',
597 ' enum TrailingComma {',
598 ' name1,',
599 ' name2,',
600 ' };',
601 '};'],
602 'Trailing comma in block.'),
603 ('invalid_idl_5.idl',
604 ['//',
605 'namespace test {',
606 ' callback Callback1 = void(;',
607 '};'],
608 'Unexpected ";" after "(".'),
609 ('invalid_idl_6.idl',
610 ['//',
611 'namespace test {',
612 ' callback Callback1 = void(long );',
613 '};'],
614 'Unexpected ")" after symbol long.'),
615 ('invalid_idl_7.idl',
616 ['//',
617 'namespace test {',
618 ' interace Events {',
619 ' static void onFoo1();',
620 ' };',
621 '};'],
622 'Unexpected symbol Events after symbol interace.'),
623 ('invalid_idl_8.idl',
624 ['//',
625 'namespace test {',
626 ' interface NotEvent {',
627 ' static void onFoo1();',
628 ' };',
629 '};'],
630 'Did not process Interface Interface(NotEvent)'),
631 ('invalid_idl_9.idl',
632 ['//',
633 'namespace test {',
634 ' interface {',
635 ' static void function1();',
636 ' };',
637 '};'],
638 'Interface missing name.'),
639 ]
640
641 input_api.files = [MockFile(filename, contents)
642 for (filename, contents, _) in test_data]
643
644 for (filename, _, expected_error) in test_data:
645 actual_error = PRESUBMIT._GetIDLParseError(input_api, filename)
646 self.assertTrue(expected_error in str(actual_error),
647 "'%s' not found in '%s'" % (expected_error, actual_error))
648
649
434 if __name__ == '__main__': 650 if __name__ == '__main__':
435 unittest.main() 651 unittest.main()
OLDNEW
« no previous file with comments | « PRESUBMIT.py ('k') | chrome/common/extensions/api/PRESUBMIT.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698