Mercurial > genshi > mirror
comparison examples/trac/trac/versioncontrol/tests/svn_fs.py @ 39:93b4dcbafd7b trunk
Copy Trac to main branch.
author | cmlenz |
---|---|
date | Mon, 03 Jul 2006 18:53:27 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
38:ee669cb9cccc | 39:93b4dcbafd7b |
---|---|
1 # -*- coding: utf-8 -*- | |
2 # | |
3 # Copyright (C) 2005 Edgewall Software | |
4 # Copyright (C) 2005 Christopher Lenz <cmlenz@gmx.de> | |
5 # All rights reserved. | |
6 # | |
7 # This software is licensed as described in the file COPYING, which | |
8 # you should have received as part of this distribution. The terms | |
9 # are also available at http://trac.edgewall.com/license.html. | |
10 # | |
11 # This software consists of voluntary contributions made by many | |
12 # individuals. For the exact contribution history, see the revision | |
13 # history and logs, available at http://projects.edgewall.com/trac/. | |
14 # | |
15 # Author: Christopher Lenz <cmlenz@gmx.de> | |
16 | |
17 import os.path | |
18 import stat | |
19 import shutil | |
20 import sys | |
21 import tempfile | |
22 import unittest | |
23 | |
24 from StringIO import StringIO | |
25 | |
26 try: | |
27 from svn import core, repos | |
28 has_svn = True | |
29 except: | |
30 has_svn = False | |
31 | |
32 from trac.log import logger_factory | |
33 from trac.test import TestSetup | |
34 from trac.core import TracError | |
35 from trac.versioncontrol import Changeset, Node | |
36 from trac.versioncontrol.svn_fs import SubversionRepository | |
37 | |
38 REPOS_PATH = os.path.join(tempfile.gettempdir(), 'trac-svnrepos') | |
39 | |
40 | |
41 class SubversionRepositoryTestSetup(TestSetup): | |
42 | |
43 def setUp(self): | |
44 dumpfile = open(os.path.join(os.path.split(__file__)[0], | |
45 'svnrepos.dump')) | |
46 | |
47 core.apr_initialize() | |
48 pool = core.svn_pool_create(None) | |
49 dumpstream = None | |
50 try: | |
51 r = repos.svn_repos_create(REPOS_PATH, '', '', None, None, pool) | |
52 if hasattr(repos, 'svn_repos_load_fs2'): | |
53 repos.svn_repos_load_fs2(r, dumpfile, StringIO(), | |
54 repos.svn_repos_load_uuid_default, '', | |
55 0, 0, None, pool) | |
56 else: | |
57 dumpstream = core.svn_stream_from_aprfile(dumpfile, pool) | |
58 repos.svn_repos_load_fs(r, dumpstream, None, | |
59 repos.svn_repos_load_uuid_default, '', | |
60 None, None, pool) | |
61 finally: | |
62 if dumpstream: | |
63 core.svn_stream_close(dumpstream) | |
64 core.svn_pool_destroy(pool) | |
65 core.apr_terminate() | |
66 | |
67 def tearDown(self): | |
68 if os.name == 'nt': | |
69 # The Windows version of 'shutil.rmtree' doesn't override the | |
70 # permissions of read-only files, so we have to do it ourselves: | |
71 format_file = os.path.join(REPOS_PATH, 'db', 'format') | |
72 if os.path.isfile(format_file): | |
73 os.chmod(format_file, stat.S_IRWXU) | |
74 os.chmod(os.path.join(REPOS_PATH, 'format'), stat.S_IRWXU) | |
75 shutil.rmtree(REPOS_PATH) | |
76 | |
77 | |
78 class SubversionRepositoryTestCase(unittest.TestCase): | |
79 | |
80 def setUp(self): | |
81 self.repos = SubversionRepository(REPOS_PATH, None, | |
82 logger_factory('test')) | |
83 | |
84 def tearDown(self): | |
85 self.repos = None | |
86 | |
87 def test_repos_normalize_path(self): | |
88 self.assertEqual('/', self.repos.normalize_path('/')) | |
89 self.assertEqual('/', self.repos.normalize_path('')) | |
90 self.assertEqual('/', self.repos.normalize_path(None)) | |
91 self.assertEqual('trunk', self.repos.normalize_path('trunk')) | |
92 self.assertEqual('trunk', self.repos.normalize_path('/trunk')) | |
93 self.assertEqual('trunk', self.repos.normalize_path('trunk/')) | |
94 self.assertEqual('trunk', self.repos.normalize_path('/trunk/')) | |
95 | |
96 def test_repos_normalize_rev(self): | |
97 self.assertEqual(17, self.repos.normalize_rev('latest')) | |
98 self.assertEqual(17, self.repos.normalize_rev('head')) | |
99 self.assertEqual(17, self.repos.normalize_rev('')) | |
100 self.assertEqual(17, self.repos.normalize_rev(None)) | |
101 self.assertEqual(11, self.repos.normalize_rev('11')) | |
102 self.assertEqual(11, self.repos.normalize_rev(11)) | |
103 | |
104 def test_rev_navigation(self): | |
105 self.assertEqual(1, self.repos.oldest_rev) | |
106 self.assertEqual(None, self.repos.previous_rev(0)) | |
107 self.assertEqual(None, self.repos.previous_rev(1)) | |
108 self.assertEqual(17, self.repos.youngest_rev) | |
109 self.assertEqual(6, self.repos.next_rev(5)) | |
110 self.assertEqual(7, self.repos.next_rev(6)) | |
111 # ... | |
112 self.assertEqual(None, self.repos.next_rev(17)) | |
113 | |
114 def test_rev_path_navigation(self): | |
115 self.assertEqual(1, self.repos.oldest_rev) | |
116 self.assertEqual(None, self.repos.previous_rev(0, 'trunk')) | |
117 self.assertEqual(None, self.repos.previous_rev(1, 'trunk')) | |
118 self.assertEqual(17, self.repos.youngest_rev) | |
119 self.assertEqual(6, self.repos.next_rev(5, 'trunk')) | |
120 self.assertEqual(13, self.repos.next_rev(6, 'trunk')) | |
121 # ... | |
122 self.assertEqual(None, self.repos.next_rev(17, 'trunk')) | |
123 # test accentuated characters | |
124 self.assertEqual(None, self.repos.previous_rev(17, u'trunk/R\xe9sum\xe9.txt')) | |
125 self.assertEqual(17, self.repos.next_rev(16, u'trunk/R\xe9sum\xe9.txt')) | |
126 | |
127 def test_has_node(self): | |
128 self.assertEqual(False, self.repos.has_node('/trunk/dir1', 3)) | |
129 self.assertEqual(True, self.repos.has_node('/trunk/dir1', 4)) | |
130 | |
131 def test_get_node(self): | |
132 node = self.repos.get_node('/trunk') | |
133 self.assertEqual('trunk', node.name) | |
134 self.assertEqual('/trunk', node.path) | |
135 self.assertEqual(Node.DIRECTORY, node.kind) | |
136 self.assertEqual(17, node.rev) | |
137 self.assertEqual(1143808225L, node.last_modified) | |
138 node = self.repos.get_node('/trunk/README.txt') | |
139 self.assertEqual('README.txt', node.name) | |
140 self.assertEqual('/trunk/README.txt', node.path) | |
141 self.assertEqual(Node.FILE, node.kind) | |
142 self.assertEqual(3, node.rev) | |
143 self.assertEqual(1112361898, node.last_modified) | |
144 | |
145 def test_get_node_specific_rev(self): | |
146 node = self.repos.get_node('/trunk', 1) | |
147 self.assertEqual('trunk', node.name) | |
148 self.assertEqual('/trunk', node.path) | |
149 self.assertEqual(Node.DIRECTORY, node.kind) | |
150 self.assertEqual(1, node.rev) | |
151 self.assertEqual(1112349652, node.last_modified) | |
152 node = self.repos.get_node('/trunk/README.txt', 2) | |
153 self.assertEqual('README.txt', node.name) | |
154 self.assertEqual('/trunk/README.txt', node.path) | |
155 self.assertEqual(Node.FILE, node.kind) | |
156 self.assertEqual(2, node.rev) | |
157 self.assertEqual(1112361138, node.last_modified) | |
158 | |
159 def test_get_dir_entries(self): | |
160 node = self.repos.get_node('/trunk') | |
161 entries = node.get_entries() | |
162 self.assertEqual(u'R\xe9sum\xe9.txt', entries.next().name) | |
163 self.assertEqual('dir1', entries.next().name) | |
164 self.assertEqual('README3.txt', entries.next().name) | |
165 self.assertEqual('README.txt', entries.next().name) | |
166 self.assertRaises(StopIteration, entries.next) | |
167 | |
168 def test_get_file_entries(self): | |
169 node = self.repos.get_node('/trunk/README.txt') | |
170 entries = node.get_entries() | |
171 self.assertRaises(StopIteration, entries.next) | |
172 | |
173 def test_get_dir_content(self): | |
174 node = self.repos.get_node('/trunk') | |
175 self.assertEqual(None, node.content_length) | |
176 self.assertEqual(None, node.content_type) | |
177 self.assertEqual(None, node.get_content()) | |
178 | |
179 def test_get_file_content(self): | |
180 node = self.repos.get_node('/trunk/README.txt') | |
181 self.assertEqual(8, node.content_length) | |
182 self.assertEqual('text/plain', node.content_type) | |
183 self.assertEqual('A test.\n', node.get_content().read()) | |
184 | |
185 def test_get_dir_properties(self): | |
186 f = self.repos.get_node('/trunk') | |
187 props = f.get_properties() | |
188 self.assertEqual(1, len(props)) | |
189 | |
190 def test_get_file_properties(self): | |
191 f = self.repos.get_node('/trunk/README.txt') | |
192 props = f.get_properties() | |
193 self.assertEqual('native', props['svn:eol-style']) | |
194 self.assertEqual('text/plain', props['svn:mime-type']) | |
195 | |
196 def test_created_path_rev(self): | |
197 node = self.repos.get_node('/trunk/README3.txt', 15) | |
198 self.assertEqual(14, node.rev) | |
199 self.assertEqual('/trunk/README3.txt', node.path) | |
200 self.assertEqual(14, node.created_rev) | |
201 self.assertEqual('trunk/README3.txt', node.created_path) | |
202 | |
203 def test_created_path_rev_parent_copy(self): | |
204 node = self.repos.get_node('/tags/v1/README.txt', 15) | |
205 self.assertEqual(3, node.rev) | |
206 self.assertEqual('/tags/v1/README.txt', node.path) | |
207 self.assertEqual(3, node.created_rev) | |
208 self.assertEqual('trunk/README.txt', node.created_path) | |
209 | |
210 # Revision Log / node history | |
211 | |
212 def test_get_node_history(self): | |
213 node = self.repos.get_node('/trunk/README3.txt') | |
214 history = node.get_history() | |
215 self.assertEqual(('trunk/README3.txt', 14, 'copy'), history.next()) | |
216 self.assertEqual(('trunk/README2.txt', 6, 'copy'), history.next()) | |
217 self.assertEqual(('trunk/README.txt', 3, 'edit'), history.next()) | |
218 self.assertEqual(('trunk/README.txt', 2, 'add'), history.next()) | |
219 self.assertRaises(StopIteration, history.next) | |
220 | |
221 def test_get_node_history_follow_copy(self): | |
222 node = self.repos.get_node('/tags/v1/README.txt') | |
223 history = node.get_history() | |
224 self.assertEqual(('tags/v1/README.txt', 7, 'copy'), history.next()) | |
225 self.assertEqual(('trunk/README.txt', 3, 'edit'), history.next()) | |
226 self.assertEqual(('trunk/README.txt', 2, 'add'), history.next()) | |
227 self.assertRaises(StopIteration, history.next) | |
228 | |
229 # Revision Log / path history | |
230 | |
231 def test_get_path_history(self): | |
232 history = self.repos.get_path_history('/trunk/README2.txt', None) | |
233 self.assertEqual(('trunk/README2.txt', 14, 'delete'), history.next()) | |
234 self.assertEqual(('trunk/README2.txt', 6, 'copy'), history.next()) | |
235 self.assertEqual(('trunk/README.txt', 3, 'unknown'), history.next()) | |
236 self.assertRaises(StopIteration, history.next) | |
237 | |
238 def test_get_path_history_copied_file(self): | |
239 history = self.repos.get_path_history('/tags/v1/README.txt', None) | |
240 self.assertEqual(('tags/v1/README.txt', 7, 'copy'), history.next()) | |
241 self.assertEqual(('trunk/README.txt', 3, 'unknown'), history.next()) | |
242 self.assertRaises(StopIteration, history.next) | |
243 | |
244 def test_get_path_history_copied_dir(self): | |
245 history = self.repos.get_path_history('/branches/v1x', None) | |
246 self.assertEqual(('branches/v1x', 12, 'copy'), history.next()) | |
247 self.assertEqual(('tags/v1.1', 10, 'unknown'), history.next()) | |
248 self.assertEqual(('branches/v1x', 11, 'delete'), history.next()) | |
249 self.assertEqual(('branches/v1x', 9, 'edit'), history.next()) | |
250 self.assertEqual(('branches/v1x', 8, 'copy'), history.next()) | |
251 self.assertEqual(('tags/v1', 7, 'unknown'), history.next()) | |
252 self.assertRaises(StopIteration, history.next) | |
253 | |
254 # Diffs | |
255 | |
256 def _cmp_diff(self, expected, got): | |
257 if expected[0]: | |
258 old = self.repos.get_node(*expected[0]) | |
259 self.assertEqual((old.path, old.rev), (got[0].path, got[0].rev)) | |
260 if expected[1]: | |
261 new = self.repos.get_node(*expected[1]) | |
262 self.assertEqual((new.path, new.rev), (got[1].path, got[1].rev)) | |
263 self.assertEqual(expected[2], (got[2], got[3])) | |
264 | |
265 def test_diff_file_different_revs(self): | |
266 diffs = self.repos.get_changes('trunk/README.txt', 2, 'trunk/README.txt', 3) | |
267 self._cmp_diff((('trunk/README.txt', 2), | |
268 ('trunk/README.txt', 3), | |
269 (Node.FILE, Changeset.EDIT)), diffs.next()) | |
270 self.assertRaises(StopIteration, diffs.next) | |
271 | |
272 def test_diff_file_different_files(self): | |
273 diffs = self.repos.get_changes('branches/v1x/README.txt', 12, | |
274 'branches/v1x/README2.txt', 12) | |
275 self._cmp_diff((('branches/v1x/README.txt', 12), | |
276 ('branches/v1x/README2.txt', 12), | |
277 (Node.FILE, Changeset.EDIT)), diffs.next()) | |
278 self.assertRaises(StopIteration, diffs.next) | |
279 | |
280 def test_diff_file_no_change(self): | |
281 diffs = self.repos.get_changes('trunk/README.txt', 7, | |
282 'tags/v1/README.txt', 7) | |
283 self.assertRaises(StopIteration, diffs.next) | |
284 | |
285 def test_diff_dir_different_revs(self): | |
286 diffs = self.repos.get_changes('trunk', 4, 'trunk', 8) | |
287 self._cmp_diff((None, ('trunk/dir1/dir2', 8), | |
288 (Node.DIRECTORY, Changeset.ADD)), diffs.next()) | |
289 self._cmp_diff((None, ('trunk/dir1/dir3', 8), | |
290 (Node.DIRECTORY, Changeset.ADD)), diffs.next()) | |
291 self._cmp_diff((None, ('trunk/README2.txt', 6), | |
292 (Node.FILE, Changeset.ADD)), diffs.next()) | |
293 self._cmp_diff((('trunk/dir2', 4), None, | |
294 (Node.DIRECTORY, Changeset.DELETE)), diffs.next()) | |
295 self._cmp_diff((('trunk/dir3', 4), None, | |
296 (Node.DIRECTORY, Changeset.DELETE)), diffs.next()) | |
297 self.assertRaises(StopIteration, diffs.next) | |
298 | |
299 def test_diff_dir_different_dirs(self): | |
300 diffs = self.repos.get_changes('trunk', 1, 'branches/v1x', 12) | |
301 self._cmp_diff((None, ('branches/v1x/dir1', 12), | |
302 (Node.DIRECTORY, Changeset.ADD)), diffs.next()) | |
303 self._cmp_diff((None, ('branches/v1x/dir1/dir2', 12), | |
304 (Node.DIRECTORY, Changeset.ADD)), diffs.next()) | |
305 self._cmp_diff((None, ('branches/v1x/dir1/dir3', 12), | |
306 (Node.DIRECTORY, Changeset.ADD)), diffs.next()) | |
307 self._cmp_diff((None, ('branches/v1x/README.txt', 12), | |
308 (Node.FILE, Changeset.ADD)), diffs.next()) | |
309 self._cmp_diff((None, ('branches/v1x/README2.txt', 12), | |
310 (Node.FILE, Changeset.ADD)), diffs.next()) | |
311 self.assertRaises(StopIteration, diffs.next) | |
312 | |
313 def test_diff_dir_no_change(self): | |
314 diffs = self.repos.get_changes('trunk', 7, | |
315 'tags/v1', 7) | |
316 self.assertRaises(StopIteration, diffs.next) | |
317 | |
318 # Changesets | |
319 | |
320 def test_changeset_repos_creation(self): | |
321 chgset = self.repos.get_changeset(0) | |
322 self.assertEqual(0, chgset.rev) | |
323 self.assertEqual(None, chgset.message) | |
324 self.assertEqual(None, chgset.author) | |
325 self.assertEqual(1112349461, chgset.date) | |
326 self.assertRaises(StopIteration, chgset.get_changes().next) | |
327 | |
328 def test_changeset_added_dirs(self): | |
329 chgset = self.repos.get_changeset(1) | |
330 self.assertEqual(1, chgset.rev) | |
331 self.assertEqual('Initial directory layout.', chgset.message) | |
332 self.assertEqual('john', chgset.author) | |
333 self.assertEqual(1112349652, chgset.date) | |
334 | |
335 changes = chgset.get_changes() | |
336 self.assertEqual(('branches', Node.DIRECTORY, Changeset.ADD, None, -1), | |
337 changes.next()) | |
338 self.assertEqual(('tags', Node.DIRECTORY, Changeset.ADD, None, -1), | |
339 changes.next()) | |
340 self.assertEqual(('trunk', Node.DIRECTORY, Changeset.ADD, None, -1), | |
341 changes.next()) | |
342 self.assertRaises(StopIteration, changes.next) | |
343 | |
344 def test_changeset_file_edit(self): | |
345 chgset = self.repos.get_changeset(3) | |
346 self.assertEqual(3, chgset.rev) | |
347 self.assertEqual('Fixed README.\n', chgset.message) | |
348 self.assertEqual('kate', chgset.author) | |
349 self.assertEqual(1112361898, chgset.date) | |
350 | |
351 changes = chgset.get_changes() | |
352 self.assertEqual(('trunk/README.txt', Node.FILE, Changeset.EDIT, | |
353 'trunk/README.txt', 2), changes.next()) | |
354 self.assertRaises(StopIteration, changes.next) | |
355 | |
356 def test_changeset_dir_moves(self): | |
357 chgset = self.repos.get_changeset(5) | |
358 self.assertEqual(5, chgset.rev) | |
359 self.assertEqual('Moved directories.', chgset.message) | |
360 self.assertEqual('kate', chgset.author) | |
361 self.assertEqual(1112372739, chgset.date) | |
362 | |
363 changes = chgset.get_changes() | |
364 self.assertEqual(('trunk/dir1/dir2', Node.DIRECTORY, Changeset.MOVE, | |
365 'trunk/dir2', 4), changes.next()) | |
366 self.assertEqual(('trunk/dir1/dir3', Node.DIRECTORY, Changeset.MOVE, | |
367 'trunk/dir3', 4), changes.next()) | |
368 self.assertRaises(StopIteration, changes.next) | |
369 | |
370 def test_changeset_file_copy(self): | |
371 chgset = self.repos.get_changeset(6) | |
372 self.assertEqual(6, chgset.rev) | |
373 self.assertEqual('More things to read', chgset.message) | |
374 self.assertEqual('john', chgset.author) | |
375 self.assertEqual(1112381806, chgset.date) | |
376 | |
377 changes = chgset.get_changes() | |
378 self.assertEqual(('trunk/README2.txt', Node.FILE, Changeset.COPY, | |
379 'trunk/README.txt', 3), changes.next()) | |
380 self.assertRaises(StopIteration, changes.next) | |
381 | |
382 def test_changeset_root_propset(self): | |
383 chgset = self.repos.get_changeset(13) | |
384 self.assertEqual(13, chgset.rev) | |
385 self.assertEqual('Setting property on the repository_dir root', | |
386 chgset.message) | |
387 changes = chgset.get_changes() | |
388 self.assertEqual(('/', Node.DIRECTORY, Changeset.EDIT, '/', 12), | |
389 changes.next()) | |
390 self.assertEqual(('trunk', Node.DIRECTORY, Changeset.EDIT, 'trunk', 6), | |
391 changes.next()) | |
392 self.assertRaises(StopIteration, changes.next) | |
393 | |
394 def test_changeset_base_path_rev(self): | |
395 chgset = self.repos.get_changeset(9) | |
396 self.assertEqual(9, chgset.rev) | |
397 changes = chgset.get_changes() | |
398 self.assertEqual(('branches/v1x/README.txt', Node.FILE, | |
399 Changeset.EDIT, 'trunk/README.txt', 3), | |
400 changes.next()) | |
401 self.assertRaises(StopIteration, changes.next) | |
402 | |
403 def test_changeset_rename_and_edit(self): | |
404 chgset = self.repos.get_changeset(14) | |
405 self.assertEqual(14, chgset.rev) | |
406 changes = chgset.get_changes() | |
407 self.assertEqual(('trunk/README3.txt', Node.FILE, | |
408 Changeset.MOVE, 'trunk/README2.txt', 13), | |
409 changes.next()) | |
410 self.assertRaises(StopIteration, changes.next) | |
411 | |
412 def test_changeset_edit_after_wc2wc_copy__original_deleted(self): | |
413 chgset = self.repos.get_changeset(16) | |
414 self.assertEqual(16, chgset.rev) | |
415 changes = chgset.get_changes() | |
416 self.assertEqual(('branches/v2', Node.DIRECTORY, Changeset.COPY, | |
417 'tags/v1.1', 14), | |
418 changes.next()) | |
419 self.assertEqual(('branches/v2/README2.txt', Node.FILE, | |
420 Changeset.EDIT, 'trunk/README2.txt', 6), | |
421 changes.next()) | |
422 self.assertRaises(StopIteration, changes.next) | |
423 | |
424 | |
425 class ScopedSubversionRepositoryTestCase(unittest.TestCase): | |
426 | |
427 def setUp(self): | |
428 self.repos = SubversionRepository(REPOS_PATH + '/trunk', None, | |
429 logger_factory('test')) | |
430 | |
431 def tearDown(self): | |
432 self.repos = None | |
433 | |
434 def test_repos_normalize_path(self): | |
435 self.assertEqual('/', self.repos.normalize_path('/')) | |
436 self.assertEqual('/', self.repos.normalize_path('')) | |
437 self.assertEqual('/', self.repos.normalize_path(None)) | |
438 self.assertEqual('dir1', self.repos.normalize_path('dir1')) | |
439 self.assertEqual('dir1', self.repos.normalize_path('/dir1')) | |
440 self.assertEqual('dir1', self.repos.normalize_path('dir1/')) | |
441 self.assertEqual('dir1', self.repos.normalize_path('/dir1/')) | |
442 | |
443 def test_repos_normalize_rev(self): | |
444 self.assertEqual(17, self.repos.normalize_rev('latest')) | |
445 self.assertEqual(17, self.repos.normalize_rev('head')) | |
446 self.assertEqual(17, self.repos.normalize_rev('')) | |
447 self.assertEqual(17, self.repos.normalize_rev(None)) | |
448 self.assertEqual(5, self.repos.normalize_rev('5')) | |
449 self.assertEqual(5, self.repos.normalize_rev(5)) | |
450 | |
451 def test_rev_navigation(self): | |
452 self.assertEqual(1, self.repos.oldest_rev) | |
453 self.assertEqual(None, self.repos.previous_rev(0)) | |
454 self.assertEqual(1, self.repos.previous_rev(2)) | |
455 self.assertEqual(17, self.repos.youngest_rev) | |
456 self.assertEqual(2, self.repos.next_rev(1)) | |
457 self.assertEqual(3, self.repos.next_rev(2)) | |
458 # ... | |
459 self.assertEqual(None, self.repos.next_rev(17)) | |
460 | |
461 def test_has_node(self): | |
462 self.assertEqual(False, self.repos.has_node('/dir1', 3)) | |
463 self.assertEqual(True, self.repos.has_node('/dir1', 4)) | |
464 | |
465 def test_get_node(self): | |
466 node = self.repos.get_node('/dir1') | |
467 self.assertEqual('dir1', node.name) | |
468 self.assertEqual('/dir1', node.path) | |
469 self.assertEqual(Node.DIRECTORY, node.kind) | |
470 self.assertEqual(5, node.rev) | |
471 self.assertEqual(1112372739, node.last_modified) | |
472 node = self.repos.get_node('/README.txt') | |
473 self.assertEqual('README.txt', node.name) | |
474 self.assertEqual('/README.txt', node.path) | |
475 self.assertEqual(Node.FILE, node.kind) | |
476 self.assertEqual(3, node.rev) | |
477 self.assertEqual(1112361898, node.last_modified) | |
478 | |
479 def test_get_node_specific_rev(self): | |
480 node = self.repos.get_node('/dir1', 4) | |
481 self.assertEqual('dir1', node.name) | |
482 self.assertEqual('/dir1', node.path) | |
483 self.assertEqual(Node.DIRECTORY, node.kind) | |
484 self.assertEqual(4, node.rev) | |
485 self.assertEqual(1112370155, node.last_modified) | |
486 node = self.repos.get_node('/README.txt', 2) | |
487 self.assertEqual('README.txt', node.name) | |
488 self.assertEqual('/README.txt', node.path) | |
489 self.assertEqual(Node.FILE, node.kind) | |
490 self.assertEqual(2, node.rev) | |
491 self.assertEqual(1112361138, node.last_modified) | |
492 | |
493 def test_get_dir_entries(self): | |
494 node = self.repos.get_node('/') | |
495 entries = node.get_entries() | |
496 self.assertEqual(u'R\xe9sum\xe9.txt', entries.next().name) | |
497 self.assertEqual('dir1', entries.next().name) | |
498 self.assertEqual('README3.txt', entries.next().name) | |
499 self.assertEqual('README.txt', entries.next().name) | |
500 self.assertRaises(StopIteration, entries.next) | |
501 | |
502 def test_get_file_entries(self): | |
503 node = self.repos.get_node('/README.txt') | |
504 entries = node.get_entries() | |
505 self.assertRaises(StopIteration, entries.next) | |
506 | |
507 def test_get_dir_content(self): | |
508 node = self.repos.get_node('/dir1') | |
509 self.assertEqual(None, node.content_length) | |
510 self.assertEqual(None, node.content_type) | |
511 self.assertEqual(None, node.get_content()) | |
512 | |
513 def test_get_file_content(self): | |
514 node = self.repos.get_node('/README.txt') | |
515 self.assertEqual(8, node.content_length) | |
516 self.assertEqual('text/plain', node.content_type) | |
517 self.assertEqual('A test.\n', node.get_content().read()) | |
518 | |
519 def test_get_dir_properties(self): | |
520 f = self.repos.get_node('/dir1') | |
521 props = f.get_properties() | |
522 self.assertEqual(0, len(props)) | |
523 | |
524 def test_get_file_properties(self): | |
525 f = self.repos.get_node('/README.txt') | |
526 props = f.get_properties() | |
527 self.assertEqual('native', props['svn:eol-style']) | |
528 self.assertEqual('text/plain', props['svn:mime-type']) | |
529 | |
530 # Revision Log / node history | |
531 | |
532 def test_get_node_history(self): | |
533 node = self.repos.get_node('/README3.txt') | |
534 history = node.get_history() | |
535 self.assertEqual(('README3.txt', 14, 'copy'), history.next()) | |
536 self.assertEqual(('README2.txt', 6, 'copy'), history.next()) | |
537 self.assertEqual(('README.txt', 3, 'edit'), history.next()) | |
538 self.assertEqual(('README.txt', 2, 'add'), history.next()) | |
539 self.assertRaises(StopIteration, history.next) | |
540 | |
541 def test_get_node_history_follow_copy(self): | |
542 node = self.repos.get_node('dir1/dir3', ) | |
543 history = node.get_history() | |
544 self.assertEqual(('dir1/dir3', 5, 'copy'), history.next()) | |
545 self.assertEqual(('dir3', 4, 'add'), history.next()) | |
546 self.assertRaises(StopIteration, history.next) | |
547 | |
548 # Revision Log / path history | |
549 | |
550 def test_get_path_history(self): | |
551 history = self.repos.get_path_history('dir3', None) | |
552 self.assertEqual(('dir3', 5, 'delete'), history.next()) | |
553 self.assertEqual(('dir3', 4, 'add'), history.next()) | |
554 self.assertRaises(StopIteration, history.next) | |
555 | |
556 def test_get_path_history_copied_file(self): | |
557 history = self.repos.get_path_history('README3.txt', None) | |
558 self.assertEqual(('README3.txt', 14, 'copy'), history.next()) | |
559 self.assertEqual(('README2.txt', 6, 'unknown'), history.next()) | |
560 self.assertRaises(StopIteration, history.next) | |
561 | |
562 def test_get_path_history_copied_dir(self): | |
563 history = self.repos.get_path_history('dir1/dir3', None) | |
564 self.assertEqual(('dir1/dir3', 5, 'copy'), history.next()) | |
565 self.assertEqual(('dir3', 4, 'unknown'), history.next()) | |
566 self.assertRaises(StopIteration, history.next) | |
567 | |
568 def test_changeset_repos_creation(self): | |
569 chgset = self.repos.get_changeset(0) | |
570 self.assertEqual(0, chgset.rev) | |
571 self.assertEqual(None, chgset.message) | |
572 self.assertEqual(None, chgset.author) | |
573 self.assertEqual(1112349461, chgset.date) | |
574 self.assertRaises(StopIteration, chgset.get_changes().next) | |
575 | |
576 def test_changeset_added_dirs(self): | |
577 chgset = self.repos.get_changeset(4) | |
578 self.assertEqual(4, chgset.rev) | |
579 self.assertEqual('More directories.', chgset.message) | |
580 self.assertEqual('john', chgset.author) | |
581 self.assertEqual(1112370155, chgset.date) | |
582 | |
583 changes = chgset.get_changes() | |
584 self.assertEqual(('dir1', Node.DIRECTORY, 'add', None, -1), | |
585 changes.next()) | |
586 self.assertEqual(('dir2', Node.DIRECTORY, 'add', None, -1), | |
587 changes.next()) | |
588 self.assertEqual(('dir3', Node.DIRECTORY, 'add', None, -1), | |
589 changes.next()) | |
590 self.assertRaises(StopIteration, changes.next) | |
591 | |
592 def test_changeset_file_edit(self): | |
593 chgset = self.repos.get_changeset(3) | |
594 self.assertEqual(3, chgset.rev) | |
595 self.assertEqual('Fixed README.\n', chgset.message) | |
596 self.assertEqual('kate', chgset.author) | |
597 self.assertEqual(1112361898, chgset.date) | |
598 | |
599 changes = chgset.get_changes() | |
600 self.assertEqual(('README.txt', Node.FILE, Changeset.EDIT, | |
601 'README.txt', 2), changes.next()) | |
602 self.assertRaises(StopIteration, changes.next) | |
603 | |
604 def test_changeset_dir_moves(self): | |
605 chgset = self.repos.get_changeset(5) | |
606 self.assertEqual(5, chgset.rev) | |
607 self.assertEqual('Moved directories.', chgset.message) | |
608 self.assertEqual('kate', chgset.author) | |
609 self.assertEqual(1112372739, chgset.date) | |
610 | |
611 changes = chgset.get_changes() | |
612 self.assertEqual(('dir1/dir2', Node.DIRECTORY, Changeset.MOVE, | |
613 'dir2', 4), changes.next()) | |
614 self.assertEqual(('dir1/dir3', Node.DIRECTORY, Changeset.MOVE, | |
615 'dir3', 4), changes.next()) | |
616 self.assertRaises(StopIteration, changes.next) | |
617 | |
618 def test_changeset_file_copy(self): | |
619 chgset = self.repos.get_changeset(6) | |
620 self.assertEqual(6, chgset.rev) | |
621 self.assertEqual('More things to read', chgset.message) | |
622 self.assertEqual('john', chgset.author) | |
623 self.assertEqual(1112381806, chgset.date) | |
624 | |
625 changes = chgset.get_changes() | |
626 self.assertEqual(('README2.txt', Node.FILE, Changeset.COPY, | |
627 'README.txt', 3), changes.next()) | |
628 self.assertRaises(StopIteration, changes.next) | |
629 | |
630 def test_changeset_root_propset(self): | |
631 chgset = self.repos.get_changeset(13) | |
632 self.assertEqual(13, chgset.rev) | |
633 self.assertEqual('Setting property on the repository_dir root', | |
634 chgset.message) | |
635 changes = chgset.get_changes() | |
636 self.assertEqual(('/', Node.DIRECTORY, Changeset.EDIT, '/', 6), | |
637 changes.next()) | |
638 self.assertRaises(StopIteration, changes.next) | |
639 | |
640 | |
641 class RecentPathScopedRepositoryTestCase(unittest.TestCase): | |
642 | |
643 def setUp(self): | |
644 self.repos = SubversionRepository(REPOS_PATH + '/trunk/dir1', None, | |
645 logger_factory('test')) | |
646 | |
647 def tearDown(self): | |
648 self.repos = None | |
649 | |
650 def test_rev_navigation(self): | |
651 self.assertEqual(False, self.repos.has_node('/', 1)) | |
652 self.assertEqual(False, self.repos.has_node('/', 2)) | |
653 self.assertEqual(False, self.repos.has_node('/', 3)) | |
654 self.assertEqual(True, self.repos.has_node('/', 4)) | |
655 self.assertEqual(4, self.repos.oldest_rev) | |
656 self.assertEqual(None, self.repos.previous_rev(4)) | |
657 | |
658 | |
659 class NonSelfContainedScopedTestCase(unittest.TestCase): | |
660 | |
661 def setUp(self): | |
662 self.repos = SubversionRepository(REPOS_PATH + '/tags/v1', None, | |
663 logger_factory('test')) | |
664 | |
665 def tearDown(self): | |
666 self.repos = None | |
667 | |
668 def test_mixed_changeset(self): | |
669 chgset = self.repos.get_changeset(7) | |
670 self.assertEqual(7, chgset.rev) | |
671 changes = chgset.get_changes() | |
672 self.assertEqual(('/', Node.DIRECTORY, Changeset.ADD, None, -1), | |
673 changes.next()) | |
674 self.assertRaises(TracError, lambda: self.repos.get_node(None, 6)) | |
675 | |
676 | |
677 class AnotherNonSelfContainedScopedTestCase(unittest.TestCase): | |
678 | |
679 def setUp(self): | |
680 self.repos = SubversionRepository(REPOS_PATH + '/branches', None, | |
681 logger_factory('test')) | |
682 | |
683 def tearDown(self): | |
684 self.repos = None | |
685 | |
686 def test_mixed_changeset_with_edit(self): | |
687 chgset = self.repos.get_changeset(9) | |
688 self.assertEqual(9, chgset.rev) | |
689 changes = chgset.get_changes() | |
690 self.assertEqual(('v1x/README.txt', Node.FILE, Changeset.EDIT, | |
691 'v1x/README.txt', 8), | |
692 changes.next()) | |
693 | |
694 | |
695 def suite(): | |
696 global has_svn | |
697 suite = unittest.TestSuite() | |
698 if has_svn: | |
699 suite.addTest(unittest.makeSuite(SubversionRepositoryTestCase, | |
700 'test', suiteClass=SubversionRepositoryTestSetup)) | |
701 suite.addTest(unittest.makeSuite(ScopedSubversionRepositoryTestCase, | |
702 'test', suiteClass=SubversionRepositoryTestSetup)) | |
703 suite.addTest(unittest.makeSuite(RecentPathScopedRepositoryTestCase, | |
704 'test', suiteClass=SubversionRepositoryTestSetup)) | |
705 suite.addTest(unittest.makeSuite(NonSelfContainedScopedTestCase, | |
706 'test', suiteClass=SubversionRepositoryTestSetup)) | |
707 suite.addTest(unittest.makeSuite(AnotherNonSelfContainedScopedTestCase, | |
708 'test', suiteClass=SubversionRepositoryTestSetup)) | |
709 return suite | |
710 | |
711 if __name__ == '__main__': | |
712 runner = unittest.TextTestRunner() | |
713 runner.run(suite()) |