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 |