| 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 |