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 | 18 |
19 # Access to a protected member XX of a client class | 19 # Access to a protected member XX of a client class |
20 # pylint: disable=W0212 | 20 # pylint: disable=W0212 |
21 | 21 |
22 | 22 |
| 23 def _api(files): |
| 24 """Mock a rietveld api request.""" |
| 25 return rietveld.json.dumps({'files': files}) |
| 26 |
| 27 |
| 28 def _file( |
| 29 status, is_binary=False, num_chunks=1, chunk_id=789, property_changes=''): |
| 30 """Mock a file in a rietveld api request.""" |
| 31 return { |
| 32 'status': status, |
| 33 'is_binary': is_binary, |
| 34 'num_chunks': num_chunks, |
| 35 'id': chunk_id, |
| 36 'property_changes': property_changes, |
| 37 } |
| 38 |
| 39 |
23 class RietveldTest(unittest.TestCase): | 40 class RietveldTest(unittest.TestCase): |
| 41 def setUp(self): |
| 42 self.rietveld = rietveld.Rietveld('url', 'email', 'password') |
| 43 self.rietveld._send = self._rietveld_send |
| 44 self.requests = [] |
| 45 |
| 46 def tearDown(self): |
| 47 self.assertEquals([], self.requests) |
| 48 |
| 49 def _rietveld_send(self, url, *args, **kwargs): |
| 50 self.assertTrue(self.requests, url) |
| 51 request = self.requests.pop(0) |
| 52 self.assertEquals(2, len(request)) |
| 53 self.assertEquals(url, request[0]) |
| 54 return request[1] |
| 55 |
24 def test_get_patch_empty(self): | 56 def test_get_patch_empty(self): |
25 r = rietveld.Rietveld('url', 'email', 'password') | 57 self.requests = [('/api/123/456', '{}')] |
26 r._send = lambda *args, **kwargs: '{}' | 58 patches = self.rietveld.get_patch(123, 456) |
27 patches = r.get_patch(123, 456) | |
28 self.assertTrue(isinstance(patches, patch.PatchSet)) | 59 self.assertTrue(isinstance(patches, patch.PatchSet)) |
29 self.assertEquals([], patches.patches) | 60 self.assertEquals([], patches.patches) |
30 | 61 |
| 62 def _check_patch(self, |
| 63 p, |
| 64 filename, |
| 65 diff, |
| 66 is_binary=False, |
| 67 is_delete=False, |
| 68 is_git_diff=False, |
| 69 is_new=False, |
| 70 patchlevel=0, |
| 71 svn_properties=None): |
| 72 svn_properties = svn_properties or [] |
| 73 self.assertEquals(p.filename, filename) |
| 74 self.assertEquals(p.is_binary, is_binary) |
| 75 self.assertEquals(p.is_delete, is_delete) |
| 76 if hasattr(p, 'is_git_diff'): |
| 77 self.assertEquals(p.is_git_diff, is_git_diff) |
| 78 self.assertEquals(p.is_new, is_new) |
| 79 if hasattr(p, 'patchlevel'): |
| 80 self.assertEquals(p.patchlevel, patchlevel) |
| 81 if diff: |
| 82 self.assertEquals(p.get(), diff) |
| 83 if hasattr(p, 'svn_properties'): |
| 84 self.assertEquals(p.svn_properties, svn_properties) |
| 85 |
31 def test_get_patch_no_status(self): | 86 def test_get_patch_no_status(self): |
32 r = rietveld.Rietveld('url', 'email', 'password') | 87 self.requests = [('/api/123/456', _api({'file_a': {}}))] |
33 r._send = lambda *args, **kwargs: ( | |
34 '{' | |
35 ' "files":' | |
36 ' {' | |
37 ' "file_a":' | |
38 ' {' | |
39 ' }' | |
40 ' }' | |
41 '}') | |
42 try: | 88 try: |
43 r.get_patch(123, 456) | 89 self.rietveld.get_patch(123, 456) |
44 self.fail() | 90 self.fail() |
45 except patch.UnsupportedPatchFormat, e: | 91 except patch.UnsupportedPatchFormat, e: |
46 self.assertEquals('file_a', e.filename) | 92 self.assertEquals('file_a', e.filename) |
47 | 93 |
48 def test_get_patch_two_files(self): | 94 def test_get_patch_2_files(self): |
49 output = ( | 95 diff1 = ( |
50 '{' | 96 '--- /dev/null\n' |
51 ' "files":' | 97 '+++ file_a\n' |
52 ' {' | 98 '@@ -0,0 +1 @@\n' |
53 ' "file_a":' | 99 '+bar\n') |
54 ' {' | 100 diff2 = ( |
55 ' "status": "A",' | 101 '--- file_b\n' |
56 ' "is_binary": false,' | 102 '+++ file_b\n' |
57 ' "num_chunks": 1,' | 103 '@@ -0,0 +1,1 @@\n' |
58 ' "id": 789' | 104 '+bar\n') |
59 ' }' | 105 self.requests = [ |
60 ' }' | 106 ('/api/123/456', |
61 '}') | 107 _api({'file_a': _file('A'), 'file_b': _file('M', chunk_id=790)})), |
62 r = rietveld.Rietveld('url', 'email', 'password') | 108 ('/download/issue123_456_789.diff', diff1), |
63 r._send = lambda *args, **kwargs: output | 109 ('/download/issue123_456_790.diff', diff2), |
64 patches = r.get_patch(123, 456) | 110 ] |
65 self.assertTrue(isinstance(patches, patch.PatchSet)) | 111 patches = self.rietveld.get_patch(123, 456) |
| 112 self.assertEquals(2, len(patches.patches)) |
| 113 self._check_patch(patches.patches[0], 'file_a', diff1, is_new=True) |
| 114 self._check_patch(patches.patches[1], 'file_b', diff2) |
| 115 |
| 116 def test_get_patch_add(self): |
| 117 diff = ( |
| 118 '--- /dev/null\n' |
| 119 '+++ file_a\n' |
| 120 '@@ -0,0 +1 @@\n' |
| 121 '+bar\n') |
| 122 self.requests = [ |
| 123 ('/api/123/456', _api({'file_a': _file('A')})), |
| 124 ('/download/issue123_456_789.diff', diff), |
| 125 ] |
| 126 patches = self.rietveld.get_patch(123, 456) |
66 self.assertEquals(1, len(patches.patches)) | 127 self.assertEquals(1, len(patches.patches)) |
67 obj = patches.patches[0] | 128 self._check_patch(patches.patches[0], 'file_a', diff, is_new=True) |
68 self.assertEquals(patch.FilePatchDiff, obj.__class__) | |
69 self.assertEquals('file_a', obj.filename) | |
70 self.assertEquals([], obj.svn_properties) | |
71 self.assertEquals(False, obj.is_git_diff) | |
72 self.assertEquals(0, obj.patchlevel) | |
73 # This is because Rietveld._send() always returns the same buffer. | |
74 self.assertEquals(output, obj.get()) | |
75 | 129 |
76 def testSvnProperties(self): | 130 def test_invalid_status(self): |
| 131 self.requests = [ |
| 132 ('/api/123/456', _api({'file_a': _file('B')})), |
| 133 ] |
| 134 try: |
| 135 self.rietveld.get_patch(123, 456) |
| 136 self.fail() |
| 137 except patch.UnsupportedPatchFormat, e: |
| 138 self.assertEquals('file_a', e.filename) |
| 139 |
| 140 def test_add_plus(self): |
| 141 properties = ( |
| 142 '\nAdded: svn:mergeinfo\n' |
| 143 ' Merged /branches/funky/file_b:r69-2775\n') |
| 144 self.requests = [ |
| 145 ('/api/123/456', |
| 146 _api({'file_a': _file('A+', property_changes=properties)})), |
| 147 ] |
| 148 try: |
| 149 self.rietveld.get_patch(123, 456) |
| 150 self.fail() |
| 151 except patch.UnsupportedPatchFormat, e: |
| 152 self.assertEquals('file_a', e.filename) |
| 153 |
| 154 def test_delete(self): |
| 155 self.requests = [ |
| 156 ('/api/123/456', _api({'file_a': _file('D')})), |
| 157 ] |
| 158 patches = self.rietveld.get_patch(123, 456) |
| 159 self.assertEquals(1, len(patches.patches)) |
| 160 self._check_patch(patches.patches[0], 'file_a', None, is_delete=True) |
| 161 |
| 162 def test_m_plus(self): |
| 163 properties = '\nAdded: svn:eol-style\n + LF\n' |
| 164 self.requests = [ |
| 165 ('/api/123/456', |
| 166 _api({'file_a': _file('M+', property_changes=properties)})), |
| 167 ] |
| 168 try: |
| 169 self.rietveld.get_patch(123, 456) |
| 170 self.fail() |
| 171 except patch.UnsupportedPatchFormat, e: |
| 172 self.assertEquals('file_a', e.filename) |
| 173 |
| 174 def test_svn_properties(self): |
77 # Line too long (N/80) | 175 # Line too long (N/80) |
78 # pylint: disable=C0301 | 176 # pylint: disable=C0301 |
79 | 177 |
80 # To test one of these, run something like | 178 # To test one of these, run something like |
81 # import json, pprint, urllib | 179 # import json, pprint, urllib |
82 # url = 'http://codereview.chromium.org/api/202046/1' | 180 # url = 'http://codereview.chromium.org/api/202046/1' |
83 # pprint.pprint(json.load(urllib.urlopen(url))['files']) | 181 # pprint.pprint(json.load(urllib.urlopen(url))['files']) |
84 | 182 |
85 # svn:mergeinfo across branches: | 183 # svn:mergeinfo across branches: |
86 # http://codereview.chromium.org/202046/diff/1/third_party/libxml/xmlcatalog
_dummy.cc | 184 # http://codereview.chromium.org/202046/diff/1/third_party/libxml/xmlcatalog
_dummy.cc |
(...skipping 21 matching lines...) Expand all Loading... |
108 self.fail() | 206 self.fail() |
109 except rietveld.patch.UnsupportedPatchFormat, e: | 207 except rietveld.patch.UnsupportedPatchFormat, e: |
110 self.assertEquals('foo', e.filename) | 208 self.assertEquals('foo', e.filename) |
111 # TODO(maruel): Change with no diff, only svn property change: | 209 # TODO(maruel): Change with no diff, only svn property change: |
112 # http://codereview.chromium.org/6462019/ | 210 # http://codereview.chromium.org/6462019/ |
113 | 211 |
114 | 212 |
115 if __name__ == '__main__': | 213 if __name__ == '__main__': |
116 logging.basicConfig(level=logging.ERROR) | 214 logging.basicConfig(level=logging.ERROR) |
117 unittest.main() | 215 unittest.main() |
OLD | NEW |