| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 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 rietveld.py.""" | 6 """Unit tests for rietveld.py.""" |
| 7 | 7 |
| 8 import logging | 8 import logging |
| 9 import os | 9 import os |
| 10 import sys | 10 import sys |
| 11 import unittest | 11 import unittest |
| 12 | 12 |
| 13 ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) | 13 ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) |
| 14 sys.path.insert(0, os.path.join(ROOT_DIR, '..')) | 14 sys.path.insert(0, os.path.join(ROOT_DIR, '..')) |
| 15 | 15 |
| 16 import patch | 16 import patch |
| 17 import rietveld | 17 import rietveld |
| 18 from tests.patches_data import GIT, RAW |
| 18 | 19 |
| 19 # Access to a protected member XX of a client class | 20 # Access to a protected member XX of a client class |
| 20 # pylint: disable=W0212 | 21 # pylint: disable=W0212 |
| 21 GIT_COPY_FULL = ( | |
| 22 'diff --git a/PRESUBMIT.py b/file_a\n' | |
| 23 'similarity index 100%\n' | |
| 24 'copy from PRESUBMIT.py\n' | |
| 25 'copy to file_a\n') | |
| 26 | |
| 27 | |
| 28 NORMAL_DIFF = ( | |
| 29 '--- file_a\n' | |
| 30 '+++ file_a\n' | |
| 31 '@@ -80,10 +80,13 @@\n' | |
| 32 ' // Foo\n' | |
| 33 ' // Bar\n' | |
| 34 ' void foo() {\n' | |
| 35 '- return bar;\n' | |
| 36 '+ return foo;\n' | |
| 37 ' }\n' | |
| 38 ' \n' | |
| 39 ' \n') | |
| 40 | 22 |
| 41 | 23 |
| 42 def _api(files): | 24 def _api(files): |
| 43 """Mock a rietveld api request.""" | 25 """Mock a rietveld api request.""" |
| 44 return rietveld.json.dumps({'files': files}) | 26 return rietveld.json.dumps({'files': files}) |
| 45 | 27 |
| 46 | 28 |
| 47 def _file( | 29 def _file( |
| 48 status, is_binary=False, num_chunks=1, chunk_id=789, property_changes=''): | 30 status, is_binary=False, num_chunks=1, chunk_id=789, property_changes=''): |
| 49 """Mock a file in a rietveld api request.""" | 31 """Mock a file in a rietveld api request.""" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 75 def test_get_patch_empty(self): | 57 def test_get_patch_empty(self): |
| 76 self.requests = [('/api/123/456', '{}')] | 58 self.requests = [('/api/123/456', '{}')] |
| 77 patches = self.rietveld.get_patch(123, 456) | 59 patches = self.rietveld.get_patch(123, 456) |
| 78 self.assertTrue(isinstance(patches, patch.PatchSet)) | 60 self.assertTrue(isinstance(patches, patch.PatchSet)) |
| 79 self.assertEquals([], patches.patches) | 61 self.assertEquals([], patches.patches) |
| 80 | 62 |
| 81 def _check_patch(self, | 63 def _check_patch(self, |
| 82 p, | 64 p, |
| 83 filename, | 65 filename, |
| 84 diff, | 66 diff, |
| 67 source_filename=None, |
| 85 is_binary=False, | 68 is_binary=False, |
| 86 is_delete=False, | 69 is_delete=False, |
| 87 is_git_diff=False, | 70 is_git_diff=False, |
| 88 is_new=False, | 71 is_new=False, |
| 89 patchlevel=0, | 72 patchlevel=0, |
| 90 svn_properties=None): | 73 svn_properties=None): |
| 91 svn_properties = svn_properties or [] | 74 svn_properties = svn_properties or [] |
| 92 self.assertEquals(p.filename, filename) | 75 self.assertEquals(p.filename, filename) |
| 76 self.assertEquals(p.source_filename, source_filename) |
| 93 self.assertEquals(p.is_binary, is_binary) | 77 self.assertEquals(p.is_binary, is_binary) |
| 94 self.assertEquals(p.is_delete, is_delete) | 78 self.assertEquals(p.is_delete, is_delete) |
| 95 if hasattr(p, 'is_git_diff'): | 79 if hasattr(p, 'is_git_diff'): |
| 96 self.assertEquals(p.is_git_diff, is_git_diff) | 80 self.assertEquals(p.is_git_diff, is_git_diff) |
| 97 self.assertEquals(p.is_new, is_new) | 81 self.assertEquals(p.is_new, is_new) |
| 98 if hasattr(p, 'patchlevel'): | 82 if hasattr(p, 'patchlevel'): |
| 99 self.assertEquals(p.patchlevel, patchlevel) | 83 self.assertEquals(p.patchlevel, patchlevel) |
| 100 if diff: | 84 if diff: |
| 101 self.assertEquals(p.get(), diff) | 85 self.assertEquals(p.get(), diff) |
| 102 if hasattr(p, 'svn_properties'): | 86 if hasattr(p, 'svn_properties'): |
| 103 self.assertEquals(p.svn_properties, svn_properties) | 87 self.assertEquals(p.svn_properties, svn_properties) |
| 104 | 88 |
| 105 def test_get_patch_no_status(self): | 89 def test_get_patch_no_status(self): |
| 106 self.requests = [('/api/123/456', _api({'file_a': {}}))] | 90 self.requests = [('/api/123/456', _api({'file_a': {}}))] |
| 107 try: | 91 try: |
| 108 self.rietveld.get_patch(123, 456) | 92 self.rietveld.get_patch(123, 456) |
| 109 self.fail() | 93 self.fail() |
| 110 except patch.UnsupportedPatchFormat, e: | 94 except patch.UnsupportedPatchFormat, e: |
| 111 self.assertEquals('file_a', e.filename) | 95 self.assertEquals('file_a', e.filename) |
| 112 | 96 |
| 113 def test_get_patch_2_files(self): | 97 def test_get_patch_2_files(self): |
| 114 diff1 = ( | |
| 115 '--- /dev/null\n' | |
| 116 '+++ file_a\n' | |
| 117 '@@ -0,0 +1 @@\n' | |
| 118 '+bar\n') | |
| 119 diff2 = ( | |
| 120 '--- file_b\n' | |
| 121 '+++ file_b\n' | |
| 122 '@@ -0,0 +1,1 @@\n' | |
| 123 '+bar\n') | |
| 124 self.requests = [ | 98 self.requests = [ |
| 125 ('/api/123/456', | 99 ('/api/123/456', |
| 126 _api({'file_a': _file('A'), 'file_b': _file('M', chunk_id=790)})), | 100 _api({'foo': _file('A '), 'file_a': _file('M ', chunk_id=790)})), |
| 127 ('/download/issue123_456_789.diff', diff1), | 101 ('/download/issue123_456_789.diff', RAW.NEW), |
| 128 ('/download/issue123_456_790.diff', diff2), | 102 ('/download/issue123_456_790.diff', RAW.NEW_NOT_NULL), |
| 129 ] | 103 ] |
| 130 patches = self.rietveld.get_patch(123, 456) | 104 patches = self.rietveld.get_patch(123, 456) |
| 131 self.assertEquals(2, len(patches.patches)) | 105 self.assertEquals(2, len(patches.patches)) |
| 132 self._check_patch(patches.patches[0], 'file_a', diff1, is_new=True) | 106 self._check_patch(patches.patches[0], 'foo', RAW.NEW, is_new=True) |
| 133 self._check_patch(patches.patches[1], 'file_b', diff2) | 107 # TODO(maruel): svn sucks. |
| 108 self._check_patch(patches.patches[1], 'file_a', RAW.NEW_NOT_NULL) |
| 134 | 109 |
| 135 def test_get_patch_add(self): | 110 def test_get_patch_add(self): |
| 136 diff = ( | |
| 137 '--- /dev/null\n' | |
| 138 '+++ file_a\n' | |
| 139 '@@ -0,0 +1 @@\n' | |
| 140 '+bar\n') | |
| 141 self.requests = [ | 111 self.requests = [ |
| 142 ('/api/123/456', _api({'file_a': _file('A')})), | 112 ('/api/123/456', _api({'foo': _file('A ')})), |
| 143 ('/download/issue123_456_789.diff', diff), | 113 ('/download/issue123_456_789.diff', RAW.NEW), |
| 144 ] | 114 ] |
| 145 patches = self.rietveld.get_patch(123, 456) | 115 patches = self.rietveld.get_patch(123, 456) |
| 146 self.assertEquals(1, len(patches.patches)) | 116 self.assertEquals(1, len(patches.patches)) |
| 147 self._check_patch(patches.patches[0], 'file_a', diff, is_new=True) | 117 self._check_patch(patches.patches[0], 'foo', RAW.NEW, is_new=True) |
| 148 | 118 |
| 149 def test_invalid_status(self): | 119 def test_invalid_status(self): |
| 150 self.requests = [ | 120 self.requests = [ |
| 151 ('/api/123/456', _api({'file_a': _file('B')})), | 121 ('/api/123/456', _api({'file_a': _file('B')})), |
| 152 ] | 122 ] |
| 153 try: | 123 try: |
| 154 self.rietveld.get_patch(123, 456) | 124 self.rietveld.get_patch(123, 456) |
| 155 self.fail() | 125 self.fail() |
| 156 except patch.UnsupportedPatchFormat, e: | 126 except patch.UnsupportedPatchFormat, e: |
| 157 self.assertEquals('file_a', e.filename) | 127 self.assertEquals('file_a', e.filename) |
| 158 | 128 |
| 159 def test_add_plus_merge(self): | 129 def test_add_plus_merge(self): |
| 160 # svn:mergeinfo is dropped. | 130 # svn:mergeinfo is dropped. |
| 161 diff = GIT_COPY_FULL | |
| 162 properties = ( | 131 properties = ( |
| 163 '\nAdded: svn:mergeinfo\n' | 132 '\nAdded: svn:mergeinfo\n' |
| 164 ' Merged /branches/funky/file_b:r69-2775\n') | 133 ' Merged /branches/funky/file_b:r69-2775\n') |
| 165 self.requests = [ | 134 self.requests = [ |
| 166 ('/api/123/456', | 135 ('/api/123/456', |
| 167 _api({'file_a': _file('A+', property_changes=properties)})), | 136 _api({'pp': _file('A+', property_changes=properties)})), |
| 168 ('/download/issue123_456_789.diff', diff), | 137 ('/download/issue123_456_789.diff', GIT.COPY), |
| 169 ] | 138 ] |
| 170 patches = self.rietveld.get_patch(123, 456) | 139 patches = self.rietveld.get_patch(123, 456) |
| 171 self.assertEquals(1, len(patches.patches)) | 140 self.assertEquals(1, len(patches.patches)) |
| 172 self._check_patch( | 141 self._check_patch( |
| 173 patches.patches[0], | 142 patches.patches[0], |
| 174 'file_a', | 143 'pp', |
| 175 diff, | 144 GIT.COPY, |
| 176 is_git_diff=True, | 145 is_git_diff=True, |
| 177 is_new=True, | 146 is_new=True, |
| 178 patchlevel=1) | 147 patchlevel=1, |
| 148 source_filename='PRESUBMIT.py') |
| 179 | 149 |
| 180 def test_add_plus_eol_style(self): | 150 def test_add_plus_eol_style(self): |
| 181 diff = GIT_COPY_FULL | |
| 182 properties = '\nAdded: svn:eol-style\n + LF\n' | 151 properties = '\nAdded: svn:eol-style\n + LF\n' |
| 183 self.requests = [ | 152 self.requests = [ |
| 184 ('/api/123/456', | 153 ('/api/123/456', |
| 185 _api({'file_a': _file('A+', property_changes=properties)})), | 154 _api({'pp': _file('A+', property_changes=properties)})), |
| 186 ('/download/issue123_456_789.diff', diff), | 155 ('/download/issue123_456_789.diff', GIT.COPY), |
| 187 ] | 156 ] |
| 188 patches = self.rietveld.get_patch(123, 456) | 157 patches = self.rietveld.get_patch(123, 456) |
| 189 self.assertEquals(1, len(patches.patches)) | 158 self.assertEquals(1, len(patches.patches)) |
| 190 self._check_patch( | 159 self._check_patch( |
| 191 patches.patches[0], | 160 patches.patches[0], |
| 192 'file_a', | 161 'pp', |
| 193 diff, | 162 GIT.COPY, |
| 194 is_git_diff=True, | 163 is_git_diff=True, |
| 195 is_new=True, | 164 is_new=True, |
| 196 patchlevel=1, | 165 patchlevel=1, |
| 166 source_filename='PRESUBMIT.py', |
| 197 svn_properties=[('svn:eol-style', 'LF')]) | 167 svn_properties=[('svn:eol-style', 'LF')]) |
| 198 | 168 |
| 199 def test_add_empty(self): | 169 def test_add_empty(self): |
| 200 # http://codereview.chromium.org/api/7530007/5001 | |
| 201 # http://codereview.chromium.org/download/issue7530007_5001_4011.diff | |
| 202 diff = ( | |
| 203 'Index: scripts/master/factory/skia/__init__.py\n' | |
| 204 '===================================================================\n') | |
| 205 self.requests = [ | 170 self.requests = [ |
| 206 ('/api/123/456', _api({'__init__.py': _file('A ', num_chunks=0)})), | 171 ('/api/123/456', _api({'__init__.py': _file('A ', num_chunks=0)})), |
| 207 ('/download/issue123_456_789.diff', diff), | 172 ('/download/issue123_456_789.diff', RAW.CRAP_ONLY), |
| 208 ] | 173 ] |
| 209 patches = self.rietveld.get_patch(123, 456) | 174 patches = self.rietveld.get_patch(123, 456) |
| 210 self.assertEquals(1, len(patches.patches)) | 175 self.assertEquals(1, len(patches.patches)) |
| 211 self._check_patch( | 176 self._check_patch( |
| 212 patches.patches[0], | 177 patches.patches[0], |
| 213 '__init__.py', | 178 '__init__.py', |
| 214 diff, | 179 RAW.CRAP_ONLY, |
| 215 is_new=True) | 180 is_new=True) |
| 216 | 181 |
| 217 def test_delete(self): | 182 def test_delete(self): |
| 218 self.requests = [ | 183 self.requests = [ |
| 219 ('/api/123/456', _api({'file_a': _file('D')})), | 184 ('/api/123/456', _api({'file_a': _file('D')})), |
| 220 ] | 185 ] |
| 221 patches = self.rietveld.get_patch(123, 456) | 186 patches = self.rietveld.get_patch(123, 456) |
| 222 self.assertEquals(1, len(patches.patches)) | 187 self.assertEquals(1, len(patches.patches)) |
| 223 self._check_patch(patches.patches[0], 'file_a', None, is_delete=True) | 188 self._check_patch(patches.patches[0], 'file_a', None, is_delete=True) |
| 224 | 189 |
| 225 def test_m_plus(self): | 190 def test_m_plus(self): |
| 226 diff = NORMAL_DIFF | |
| 227 properties = '\nAdded: svn:eol-style\n + LF\n' | 191 properties = '\nAdded: svn:eol-style\n + LF\n' |
| 228 self.requests = [ | 192 self.requests = [ |
| 229 ('/api/123/456', | 193 ('/api/123/456', |
| 230 _api({'file_a': _file('M+', property_changes=properties)})), | 194 _api({'chrome/file.cc': _file('M+', property_changes=properties)})), |
| 231 ('/download/issue123_456_789.diff', diff), | 195 ('/download/issue123_456_789.diff', RAW.PATCH), |
| 232 ] | 196 ] |
| 233 patches = self.rietveld.get_patch(123, 456) | 197 patches = self.rietveld.get_patch(123, 456) |
| 234 self.assertEquals(1, len(patches.patches)) | 198 self.assertEquals(1, len(patches.patches)) |
| 235 self._check_patch( | 199 self._check_patch( |
| 236 patches.patches[0], | 200 patches.patches[0], |
| 237 'file_a', | 201 'chrome/file.cc', |
| 238 diff, | 202 RAW.PATCH, |
| 239 svn_properties=[('svn:eol-style', 'LF')]) | 203 svn_properties=[('svn:eol-style', 'LF')]) |
| 240 | 204 |
| 241 def test_m_plus_unknown_prop(self): | 205 def test_m_plus_unknown_prop(self): |
| 242 properties = '\nAdded: svn:foobar\n + stuff\n' | 206 properties = '\nAdded: svn:foobar\n + stuff\n' |
| 243 self.requests = [ | 207 self.requests = [ |
| 244 ('/api/123/456', | 208 ('/api/123/456', |
| 245 _api({'file_a': _file('M+', property_changes=properties)})), | 209 _api({'file_a': _file('M+', property_changes=properties)})), |
| 246 ] | 210 ] |
| 247 try: | 211 try: |
| 248 self.rietveld.get_patch(123, 456) | 212 self.rietveld.get_patch(123, 456) |
| 249 self.fail() | 213 self.fail() |
| 250 except patch.UnsupportedPatchFormat, e: | 214 except patch.UnsupportedPatchFormat, e: |
| 251 self.assertEquals('file_a', e.filename) | 215 self.assertEquals('file_a', e.filename) |
| 252 | 216 |
| 217 def test_get_patch_moved(self): |
| 218 self.requests = [ |
| 219 ('/api/123/456', _api({'file_b': _file('A+')})), |
| 220 ('/download/issue123_456_789.diff', RAW.MINIMAL_RENAME), |
| 221 ] |
| 222 patches = self.rietveld.get_patch(123, 456) |
| 223 self.assertEquals(1, len(patches.patches)) |
| 224 self._check_patch( |
| 225 patches.patches[0], |
| 226 'file_b', |
| 227 RAW.MINIMAL_RENAME, |
| 228 source_filename='file_a', |
| 229 is_new=True) |
| 230 |
| 253 def test_svn_properties(self): | 231 def test_svn_properties(self): |
| 254 # Line too long (N/80) | 232 # Line too long (N/80) |
| 255 # pylint: disable=C0301 | 233 # pylint: disable=C0301 |
| 256 | 234 |
| 257 # To test one of these, run something like | 235 # To test one of these, run something like |
| 258 # import json, pprint, urllib | 236 # import json, pprint, urllib |
| 259 # url = 'http://codereview.chromium.org/api/202046/1' | 237 # url = 'http://codereview.chromium.org/api/202046/1' |
| 260 # pprint.pprint(json.load(urllib.urlopen(url))['files']) | 238 # pprint.pprint(json.load(urllib.urlopen(url))['files']) |
| 261 | 239 |
| 262 # svn:mergeinfo across branches: | 240 # svn:mergeinfo across branches: |
| (...skipping 18 matching lines...) Expand all Loading... |
| 281 rietveld.Rietveld.parse_svn_properties(u'', 'foo')) | 259 rietveld.Rietveld.parse_svn_properties(u'', 'foo')) |
| 282 | 260 |
| 283 try: | 261 try: |
| 284 rietveld.Rietveld.parse_svn_properties(u'\n', 'foo') | 262 rietveld.Rietveld.parse_svn_properties(u'\n', 'foo') |
| 285 self.fail() | 263 self.fail() |
| 286 except rietveld.patch.UnsupportedPatchFormat, e: | 264 except rietveld.patch.UnsupportedPatchFormat, e: |
| 287 self.assertEquals('foo', e.filename) | 265 self.assertEquals('foo', e.filename) |
| 288 # TODO(maruel): Change with no diff, only svn property change: | 266 # TODO(maruel): Change with no diff, only svn property change: |
| 289 # http://codereview.chromium.org/6462019/ | 267 # http://codereview.chromium.org/6462019/ |
| 290 | 268 |
| 291 def test_get_patch_moved(self): | |
| 292 output = ( | |
| 293 '{\n' | |
| 294 ' "files":\n' | |
| 295 ' {\n' | |
| 296 ' "file_a":\n' | |
| 297 ' {\n' | |
| 298 ' "status": "A+",\n' | |
| 299 ' "is_binary": false,\n' | |
| 300 ' "num_chunks": 1,\n' | |
| 301 ' "id": 789\n' | |
| 302 ' }\n' | |
| 303 ' }\n' | |
| 304 '}\n') | |
| 305 diff = ( | |
| 306 '--- /dev/null\n' | |
| 307 '+++ file_a\n' | |
| 308 '@@ -0,0 +1 @@\n' | |
| 309 '+foo\n') | |
| 310 r = rietveld.Rietveld('url', 'email', 'password') | |
| 311 def _send(args, **kwargs): | |
| 312 if args == '/api/123/456': | |
| 313 return output | |
| 314 elif args == '/download/issue123_456_789.diff': | |
| 315 return diff | |
| 316 else: | |
| 317 self.fail() | |
| 318 r._send = _send | |
| 319 patches = r.get_patch(123, 456) | |
| 320 self.assertEquals(diff, patches.patches[0].get()) | |
| 321 self.assertEquals([], patches.patches[0].svn_properties) | |
| 322 | |
| 323 | 269 |
| 324 if __name__ == '__main__': | 270 if __name__ == '__main__': |
| 325 logging.basicConfig(level=logging.ERROR) | 271 logging.basicConfig(level=logging.ERROR) |
| 326 unittest.main() | 272 unittest.main() |
| OLD | NEW |