Mercurial > kallithea
changeset 3912:91f440a11b94 beta
fixes issues #849 IMC failed for non-ascii files
- added set of regression tests into vcs lib
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Wed, 29 May 2013 00:20:27 +0200 |
parents | 7cca0d07c12b |
children | 5f192af1ba21 |
files | rhodecode/lib/vcs/backends/git/changeset.py rhodecode/lib/vcs/backends/git/inmemory.py rhodecode/lib/vcs/nodes.py rhodecode/model/scm.py rhodecode/tests/vcs/test_changesets.py rhodecode/tests/vcs/test_inmemchangesets.py |
diffstat | 6 files changed, 74 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/rhodecode/lib/vcs/backends/git/changeset.py Tue May 28 23:27:44 2013 +0200 +++ b/rhodecode/lib/vcs/backends/git/changeset.py Wed May 29 00:20:27 2013 +0200 @@ -104,7 +104,7 @@ return path def _get_id_for_path(self, path): - + path = safe_str(path) # FIXME: Please, spare a couple of minutes and make those codes cleaner; if not path in self._paths: path = path.strip('/') @@ -154,7 +154,7 @@ if not path in self._paths: raise NodeDoesNotExistError("There is no file nor directory " "at the given path '%s' at revision %s" - % (path, self.short_id)) + % (path, safe_str(self.short_id))) return self._paths[path] def _get_kind(self, path): @@ -254,6 +254,7 @@ Returns stat mode of the file at the given ``path``. """ # ensure path is traversed + path = safe_str(path) self._get_id_for_path(path) return self._stat_modes[path]
--- a/rhodecode/lib/vcs/backends/git/inmemory.py Tue May 28 23:27:44 2013 +0200 +++ b/rhodecode/lib/vcs/backends/git/inmemory.py Wed May 29 00:20:27 2013 +0200 @@ -46,7 +46,7 @@ for node in self.added + self.changed: # Compute subdirs if needed dirpath, nodename = posixpath.split(node.path) - dirnames = dirpath and dirpath.split('/') or [] + dirnames = map(safe_str, dirpath and dirpath.split('/') or []) parent = commit_tree ancestors = [('', parent)]
--- a/rhodecode/lib/vcs/nodes.py Tue May 28 23:27:44 2013 +0200 +++ b/rhodecode/lib/vcs/nodes.py Wed May 29 00:20:27 2013 +0200 @@ -16,7 +16,7 @@ from rhodecode.lib.vcs.backends.base import EmptyChangeset from rhodecode.lib.vcs.exceptions import NodeError, RemovedFileNodeError from rhodecode.lib.vcs.utils.lazy import LazyProperty -from rhodecode.lib.vcs.utils import safe_unicode +from rhodecode.lib.vcs.utils import safe_unicode, safe_str class NodeKind: @@ -100,8 +100,8 @@ def __init__(self, path, kind): if path.startswith('/'): raise NodeError("Cannot initialize Node objects with slash at " - "the beginning as only relative paths are supported") - self.path = path.rstrip('/') + "the beginning as only relative paths are supported") + self.path = safe_str(path.rstrip('/')) # we store paths as str if path == '' and kind != NodeKind.DIR: raise NodeError("Only DirNode and its subclasses may be " "initialized with empty path")
--- a/rhodecode/model/scm.py Tue May 28 23:27:44 2013 +0200 +++ b/rhodecode/model/scm.py Wed May 29 00:20:27 2013 +0200 @@ -580,8 +580,8 @@ raise NonRelativePathError('%s is not an relative path' % f_path) if f_path: f_path = os.path.normpath(f_path) + content = nodes[f_path]['content'] f_path = safe_str(f_path) - content = nodes[f_path]['content'] # decoding here will force that we have proper encoded values # in any other case this will throw exceptions and deny commit if isinstance(content, (basestring,)):
--- a/rhodecode/tests/vcs/test_changesets.py Tue May 28 23:27:44 2013 +0200 +++ b/rhodecode/tests/vcs/test_changesets.py Wed May 29 00:20:27 2013 +0200 @@ -1,3 +1,4 @@ +# encoding: utf8 from __future__ import with_statement import time @@ -302,6 +303,7 @@ 'date': datetime.datetime(2010, 1, 1, 20), 'added': [ FileNode('foo/bar', content='foo'), + FileNode('foo/bał', content='foo'), FileNode('foobar', content='foo'), FileNode('qwe', content='foo'), ], @@ -323,6 +325,7 @@ changeset = self.repo.get_changeset(0) self.assertItemsEqual(changeset.added, [ changeset.get_node('foo/bar'), + changeset.get_node('foo/bał'), changeset.get_node('foobar'), changeset.get_node('qwe'), ]) @@ -344,6 +347,14 @@ self.assertEqual(len(changeset.removed), 1) self.assertEqual(list(changeset.removed)[0].path, 'qwe') + def test_get_filemode(self): + changeset = self.repo.get_changeset() + self.assertEqual(33188, changeset.get_file_mode('foo/bar')) + + def test_get_filemode_non_ascii(self): + changeset = self.repo.get_changeset() + self.assertEqual(33188, changeset.get_file_mode('foo/bał')) + self.assertEqual(33188, changeset.get_file_mode(u'foo/bał')) # For each backend create test case class for alias in SCM_TESTS:
--- a/rhodecode/tests/vcs/test_inmemchangesets.py Tue May 28 23:27:44 2013 +0200 +++ b/rhodecode/tests/vcs/test_inmemchangesets.py Wed May 29 00:20:27 2013 +0200 @@ -1,3 +1,4 @@ +# encoding: utf8 """ Tests so called "in memory changesets" commit API of vcs. """ @@ -18,6 +19,7 @@ from rhodecode.lib.vcs.nodes import DirNode from rhodecode.lib.vcs.nodes import FileNode from rhodecode.lib.vcs.utils.compat import unittest +from rhodecode.lib.vcs.utils import safe_unicode class InMemoryChangesetTestMixin(object): @@ -112,6 +114,28 @@ self.assertEqual(changeset.get_node('foobar/foobaz/file').content, 'foo') self.assertEqual(changeset.get_node('foobar/barbaz').content, 'foo') + def test_add_non_ascii_files(self): + rev_count = len(self.repo.revisions) + to_add = [ + FileNode('żółwik/zwierzątko', content='ćććć'), + FileNode(u'żółwik/zwierzątko_uni', content=u'ćććć'), + ] + for node in to_add: + self.imc.add(node) + message = u'Added: %s' % ', '.join((node.path for node in self.nodes)) + author = unicode(self.__class__) + changeset = self.imc.commit(message=message, author=author) + + newtip = self.repo.get_changeset() + self.assertEqual(changeset, newtip) + self.assertEqual(rev_count + 1, len(self.repo.revisions)) + self.assertEqual(newtip.message, message) + self.assertEqual(newtip.author, author) + self.assertTrue(not any((self.imc.added, self.imc.changed, + self.imc.removed))) + for node in to_add: + self.assertEqual(newtip.get_node(node.path).content, node.content) + def test_add_raise_already_added(self): node = FileNode('foobar', content='baz') self.imc.add(node) @@ -140,7 +164,37 @@ self.assertNotEqual(tip, newtip) self.assertNotEqual(tip.id, newtip.id) self.assertEqual(newtip.get_node('foo/bar/baz').content, - 'My **changed** content') + 'My **changed** content') + + def test_change_non_ascii(self): + to_add = [ + FileNode('żółwik/zwierzątko', content='ćććć'), + FileNode(u'żółwik/zwierzątko_uni', content=u'ćććć'), + ] + for node in to_add: + self.imc.add(node) + + tip = self.imc.commit(u'Initial', u'joe.doe@example.com') + + # Change node's content + node = FileNode('żółwik/zwierzątko', content='My **changed** content') + self.imc.change(node) + self.imc.commit(u'Changed %s' % safe_unicode(node.path), + u'joe.doe@example.com') + + node = FileNode(u'żółwik/zwierzątko_uni', content=u'My **changed** content') + self.imc.change(node) + self.imc.commit(u'Changed %s' % safe_unicode(node.path), + u'joe.doe@example.com') + + newtip = self.repo.get_changeset() + self.assertNotEqual(tip, newtip) + self.assertNotEqual(tip.id, newtip.id) + + self.assertEqual(newtip.get_node('żółwik/zwierzątko').content, + 'My **changed** content') + self.assertEqual(newtip.get_node('żółwik/zwierzątko_uni').content, + 'My **changed** content') def test_change_raise_empty_repository(self): node = FileNode('foobar')