OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2006-2009 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 """Unit tests for presubmit_support.py and presubmit_canned_checks.py.""" | 6 """Unit tests for presubmit_support.py and presubmit_canned_checks.py.""" |
7 | 7 |
8 import os | 8 import os |
9 import StringIO | 9 import StringIO |
10 import sys | 10 import sys |
11 import unittest | 11 import unittest |
| 12 import warnings |
12 | 13 |
13 # Local imports | 14 # Local imports |
14 import gcl | 15 import gcl |
15 import gclient | 16 import gclient |
16 import presubmit_support as presubmit | 17 import presubmit_support as presubmit |
17 import presubmit_canned_checks | 18 import presubmit_canned_checks |
18 | 19 |
19 | 20 |
20 class PresubmitTestsBase(unittest.TestCase): | 21 class PresubmitTestsBase(unittest.TestCase): |
21 """Setups and tear downs the mocks but doesn't test anything as-is.""" | 22 """Setups and tear downs the mocks but doesn't test anything as-is.""" |
22 def setUp(self): | 23 def setUp(self): |
| 24 self._warnings_stack = warnings.catch_warnings() |
| 25 warnings.simplefilter("ignore", DeprecationWarning) |
23 self.original_IsFile = os.path.isfile | 26 self.original_IsFile = os.path.isfile |
24 def MockIsFile(f): | 27 def MockIsFile(f): |
25 dir = os.path.dirname(f) | 28 dir = os.path.dirname(f) |
26 return dir.endswith('haspresubmit') or dir == '' | 29 return dir.endswith('haspresubmit') or dir == '' |
27 os.path.isfile = MockIsFile | 30 os.path.isfile = MockIsFile |
28 | 31 |
29 self.original_CaptureSVNInfo = gclient.CaptureSVNInfo | 32 self.original_CaptureSVNInfo = gclient.CaptureSVNInfo |
30 def MockCaptureSVNInfo(path): | 33 def MockCaptureSVNInfo(path): |
31 if path.count('notfound'): | 34 if path.count('notfound'): |
32 return {} | 35 return {} |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 self._sys_stdout = sys.stdout | 88 self._sys_stdout = sys.stdout |
86 sys.stdout = StringIO.StringIO() | 89 sys.stdout = StringIO.StringIO() |
87 | 90 |
88 def tearDown(self): | 91 def tearDown(self): |
89 os.path.isfile = self.original_IsFile | 92 os.path.isfile = self.original_IsFile |
90 gclient.CaptureSVNInfo = self.original_CaptureSVNInfo | 93 gclient.CaptureSVNInfo = self.original_CaptureSVNInfo |
91 gcl.GetSVNFileProperty = self.original_GetSVNFileProperty | 94 gcl.GetSVNFileProperty = self.original_GetSVNFileProperty |
92 gcl.ReadFile = self.original_ReadFile | 95 gcl.ReadFile = self.original_ReadFile |
93 gcl.GetRepositoryRoot = self.original_GetRepositoryRoot | 96 gcl.GetRepositoryRoot = self.original_GetRepositoryRoot |
94 sys.stdout = self._sys_stdout | 97 sys.stdout = self._sys_stdout |
| 98 self._warnings_stack = None |
95 | 99 |
96 @staticmethod | 100 @staticmethod |
97 def MakeBasicChange(name, description): | 101 def MakeBasicChange(name, description): |
98 ci = gcl.ChangeInfo(name=name, | 102 ci = gcl.ChangeInfo(name=name, |
99 description=description, | 103 description=description, |
100 files=[]) | 104 files=[]) |
101 change = presubmit.GclChange(ci) | 105 change = presubmit.GclChange(ci) |
102 return change | 106 return change |
103 | 107 |
104 def compareMembers(self, object, members): | 108 def compareMembers(self, object, members): |
105 """If you add a member, be sure to add the relevant test!""" | 109 """If you add a member, be sure to add the relevant test!""" |
106 # Skip over members starting with '_' since they are usually not meant to | 110 # Skip over members starting with '_' since they are usually not meant to |
107 # be for public use. | 111 # be for public use. |
108 actual_members = [x for x in sorted(dir(object)) | 112 actual_members = [x for x in sorted(dir(object)) |
109 if not x.startswith('_')] | 113 if not x.startswith('_')] |
110 self.assertEqual(actual_members, sorted(members)) | 114 self.assertEqual(actual_members, sorted(members)) |
111 | 115 |
112 | 116 |
113 class PresubmitUnittest(PresubmitTestsBase): | 117 class PresubmitUnittest(PresubmitTestsBase): |
114 """General presubmit_support.py tests (excluding InputApi and OutputApi).""" | 118 """General presubmit_support.py tests (excluding InputApi and OutputApi).""" |
115 def testMembersChanged(self): | 119 def testMembersChanged(self): |
116 members = [ | 120 members = [ |
117 'AffectedFile', 'DoPresubmitChecks', 'GclChange', 'InputApi', | 121 'AffectedFile', 'DoPresubmitChecks', 'GclChange', 'InputApi', |
118 'ListRelevantPresubmitFiles', 'Main', 'NotImplementedException', | 122 'ListRelevantPresubmitFiles', 'Main', 'NotImplementedException', |
119 'OutputApi', 'ParseFiles', 'PresubmitExecuter', | 123 'OutputApi', 'ParseFiles', 'PresubmitExecuter', |
120 'ScanSubDirs', 'SvnAffectedFile', 'cPickle', 'cStringIO', 'exceptions', | 124 'ScanSubDirs', 'SvnAffectedFile', |
| 125 'cPickle', 'cStringIO', 'deprecated', 'exceptions', |
121 'fnmatch', 'gcl', 'gclient', 'glob', 'marshal', 'normpath', 'optparse', | 126 'fnmatch', 'gcl', 'gclient', 'glob', 'marshal', 'normpath', 'optparse', |
122 'os', 'pickle', 'presubmit_canned_checks', 're', 'subprocess', 'sys', | 127 'os', 'pickle', 'presubmit_canned_checks', 're', 'subprocess', 'sys', |
123 'tempfile', 'types', 'urllib2', | 128 'tempfile', 'types', 'urllib2', 'warnings', |
124 ] | 129 ] |
125 # If this test fails, you should add the relevant test. | 130 # If this test fails, you should add the relevant test. |
126 self.compareMembers(presubmit, members) | 131 self.compareMembers(presubmit, members) |
127 | 132 |
128 def testListRelevantPresubmitFiles(self): | 133 def testListRelevantPresubmitFiles(self): |
129 presubmit_files = presubmit.ListRelevantPresubmitFiles([ | 134 presubmit_files = presubmit.ListRelevantPresubmitFiles([ |
130 'blat.cc', | 135 'blat.cc', |
131 'foo/haspresubmit/yodle/smart.h', | 136 'foo/haspresubmit/yodle/smart.h', |
132 'moo/mat/gat/yo.h', | 137 'moo/mat/gat/yo.h', |
133 'foo/luck.h']) | 138 'foo/luck.h']) |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 'DepotToLocalPath', 'FilterTextFiles', 'LocalPaths', 'LocalToDepotPath', | 447 'DepotToLocalPath', 'FilterTextFiles', 'LocalPaths', 'LocalToDepotPath', |
443 'PresubmitLocalPath', 'RightHandSideLines', 'ServerPaths', | 448 'PresubmitLocalPath', 'RightHandSideLines', 'ServerPaths', |
444 'basename', 'cPickle', 'cStringIO', 'canned_checks', 'change', | 449 'basename', 'cPickle', 'cStringIO', 'canned_checks', 'change', |
445 'marshal', 'os_path', 'pickle', 'platform', | 450 'marshal', 'os_path', 'pickle', 'platform', |
446 're', 'subprocess', 'tempfile', 'urllib2', 'version', | 451 're', 'subprocess', 'tempfile', 'urllib2', 'version', |
447 ] | 452 ] |
448 # If this test fails, you should add the relevant test. | 453 # If this test fails, you should add the relevant test. |
449 self.compareMembers(presubmit.InputApi(None, './.'), members) | 454 self.compareMembers(presubmit.InputApi(None, './.'), members) |
450 | 455 |
451 def testDepotToLocalPath(self): | 456 def testDepotToLocalPath(self): |
452 path = presubmit.InputApi.DepotToLocalPath('svn:/foo/smurf') | 457 path = presubmit.InputApi(None, './p').DepotToLocalPath('svn:/foo/smurf') |
453 self.failUnless(path == 'smurf') | 458 self.failUnless(path == 'smurf') |
454 path = presubmit.InputApi.DepotToLocalPath('svn:/foo/notfound/burp') | 459 path = presubmit.InputApi(None, './p').DepotToLocalPath( |
| 460 'svn:/foo/notfound/burp') |
455 self.failUnless(path == None) | 461 self.failUnless(path == None) |
456 | 462 |
457 def testLocalToDepotPath(self): | 463 def testLocalToDepotPath(self): |
458 path = presubmit.InputApi.LocalToDepotPath('smurf') | 464 path = presubmit.InputApi(None, './p').LocalToDepotPath('smurf') |
459 self.failUnless(path == 'svn:/foo/smurf') | 465 self.failUnless(path == 'svn:/foo/smurf') |
460 path = presubmit.InputApi.LocalToDepotPath('notfound-food') | 466 path = presubmit.InputApi(None, './p').LocalToDepotPath('notfound-food') |
461 self.failUnless(path == None) | 467 self.failUnless(path == None) |
462 | 468 |
463 def testInputApiConstruction(self): | 469 def testInputApiConstruction(self): |
464 # Fudge the change object, it's not used during construction anyway | 470 # Fudge the change object, it's not used during construction anyway |
465 api = presubmit.InputApi(change=42, presubmit_path='foo/path/PRESUBMIT.py') | 471 api = presubmit.InputApi(change=42, presubmit_path='foo/path/PRESUBMIT.py') |
466 self.failUnless(api.PresubmitLocalPath() == 'foo/path') | 472 self.failUnless(api.PresubmitLocalPath() == 'foo/path') |
467 self.failUnless(api.change == 42) | 473 self.failUnless(api.change == 42) |
468 | 474 |
469 def testFilterTextFiles(self): | 475 def testFilterTextFiles(self): |
470 class MockAffectedFile(object): | 476 class MockAffectedFile(object): |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 presubmit.normpath('foo/blat.cc')) | 523 presubmit.normpath('foo/blat.cc')) |
518 self.assertEquals(affected_files[1].LocalPath(), | 524 self.assertEquals(affected_files[1].LocalPath(), |
519 presubmit.normpath('foo/blat/binary.dll')) | 525 presubmit.normpath('foo/blat/binary.dll')) |
520 self.assertEquals(affected_files[2].LocalPath(), | 526 self.assertEquals(affected_files[2].LocalPath(), |
521 presubmit.normpath('foo/mat/beingdeleted.txt')) | 527 presubmit.normpath('foo/mat/beingdeleted.txt')) |
522 | 528 |
523 rhs_lines = [] | 529 rhs_lines = [] |
524 for line in api.RightHandSideLines(): | 530 for line in api.RightHandSideLines(): |
525 rhs_lines.append(line) | 531 rhs_lines.append(line) |
526 self.failUnless(len(rhs_lines) == 2) | 532 self.failUnless(len(rhs_lines) == 2) |
527 self.failUnless(rhs_lines[0][0].LocalPath() == | 533 self.assertEqual(rhs_lines[0][0].LocalPath(), |
528 presubmit.normpath('foo/blat.cc')) | 534 presubmit.normpath('foo/blat.cc')) |
529 | 535 |
530 def testGetAbsoluteLocalPath(self): | 536 def testGetAbsoluteLocalPath(self): |
531 # Regression test for bug of presubmit stuff that relies on invoking | 537 # Regression test for bug of presubmit stuff that relies on invoking |
532 # SVN (e.g. to get mime type of file) not working unless gcl invoked | 538 # SVN (e.g. to get mime type of file) not working unless gcl invoked |
533 # from the client root (e.g. if you were at 'src' and did 'cd base' before | 539 # from the client root (e.g. if you were at 'src' and did 'cd base' before |
534 # invoking 'gcl upload' it would fail because svn wouldn't find the files | 540 # invoking 'gcl upload' it would fail because svn wouldn't find the files |
535 # the presubmit script was asking about). | 541 # the presubmit script was asking about). |
536 files = [ | 542 files = [ |
537 ['A', 'isdir'], | 543 ['A', 'isdir'], |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 output = StringIO.StringIO() | 622 output = StringIO.StringIO() |
617 input = StringIO.StringIO('\n') | 623 input = StringIO.StringIO('\n') |
618 warning = presubmit.OutputApi.PresubmitPromptWarning('???') | 624 warning = presubmit.OutputApi.PresubmitPromptWarning('???') |
619 self.failIf(warning._Handle(output, input)) | 625 self.failIf(warning._Handle(output, input)) |
620 self.failUnless(output.getvalue().count('???')) | 626 self.failUnless(output.getvalue().count('???')) |
621 | 627 |
622 | 628 |
623 class AffectedFileUnittest(PresubmitTestsBase): | 629 class AffectedFileUnittest(PresubmitTestsBase): |
624 def testMembersChanged(self): | 630 def testMembersChanged(self): |
625 members = [ | 631 members = [ |
626 'AbsoluteLocalPath', 'Action', 'IsDirectory', 'LocalPath', 'NewContents', | 632 'AbsoluteLocalPath', 'Action', 'IsDirectory', 'IsTextFile', |
| 633 'LocalPath', 'NewContents', |
627 'OldContents', 'OldFileTempPath', 'Property', 'ServerPath', 'action', | 634 'OldContents', 'OldFileTempPath', 'Property', 'ServerPath', 'action', |
628 'is_directory', 'path', 'properties', 'repository_root', 'server_path', | 635 'is_directory', 'path', 'properties', 'repository_root', 'server_path', |
629 ] | 636 ] |
630 # If this test fails, you should add the relevant test. | 637 # If this test fails, you should add the relevant test. |
631 self.compareMembers(presubmit.AffectedFile('a', 'b'), members) | 638 self.compareMembers(presubmit.AffectedFile('a', 'b'), members) |
632 self.compareMembers(presubmit.SvnAffectedFile('a', 'b'), members) | 639 self.compareMembers(presubmit.SvnAffectedFile('a', 'b'), members) |
633 | 640 |
634 def testAffectedFile(self): | 641 def testAffectedFile(self): |
635 af = presubmit.SvnAffectedFile('foo/blat.cc', 'M') | 642 af = presubmit.SvnAffectedFile('foo/blat.cc', 'M') |
636 self.failUnless(af.ServerPath() == 'svn:/foo/foo/blat.cc') | 643 self.failUnless(af.ServerPath() == 'svn:/foo/foo/blat.cc') |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 # TODO(maruel): Add real tests. | 790 # TODO(maruel): Add real tests. |
784 self.failIf(presubmit_canned_checks.RunPythonUnitTests( | 791 self.failIf(presubmit_canned_checks.RunPythonUnitTests( |
785 self.MockInputApi(), | 792 self.MockInputApi(), |
786 presubmit.OutputApi, [])) | 793 presubmit.OutputApi, [])) |
787 self.failUnless(presubmit_canned_checks.RunPythonUnitTests( | 794 self.failUnless(presubmit_canned_checks.RunPythonUnitTests( |
788 self.MockInputApi(), | 795 self.MockInputApi(), |
789 presubmit.OutputApi, ['non_existent_module'])) | 796 presubmit.OutputApi, ['non_existent_module'])) |
790 | 797 |
791 if __name__ == '__main__': | 798 if __name__ == '__main__': |
792 unittest.main() | 799 unittest.main() |
OLD | NEW |