Fixed vstorage to pass tests. Added test for reverting a page.
authorŁukasz Rekucki <lrekucki@gmail.com>
Wed, 9 Jun 2010 07:27:55 +0000 (09:27 +0200)
committerŁukasz Rekucki <lrekucki@gmail.com>
Wed, 9 Jun 2010 07:27:55 +0000 (09:27 +0200)
lib/vstorage/__init__.py
lib/vstorage/hgui.py [new file with mode: 0644]
lib/vstorage/tests.py

index 9f7084b..8d22e10 100644 (file)
@@ -18,10 +18,11 @@ os.environ['HGENCODING'] = 'utf-8'
 os.environ['HGMERGE'] = "internal:merge"
 
 import mercurial.hg
-import mercurial.ui
 import mercurial.revlog
 import mercurial.util
 
+from vstorage.hgui import SilentUI
+
 
 def urlquote(url, safe='/'):
     """Quotes URL
@@ -129,10 +130,7 @@ class VersionedStorage(object):
             os.makedirs(self.path)
         self.repo_path = find_repo_path(self.path)
 
-        self.ui = mercurial.ui.ui()
-        self.ui.quiet = True
-        self.ui._report_untrusted = False
-        self.ui.setconfig('ui', 'interactive', False)
+        self.ui = SilentUI()
 
         if self.repo_path is None:
             self.repo_path = self.path
@@ -148,8 +146,8 @@ class VersionedStorage(object):
         """Close and reopen the repo, to make sure we are up to date."""
         self.repo = mercurial.hg.repository(self.ui, self.repo_path)
 
-    def _file_path(self, title):
-        return os.path.join(self.path, urlquote(title, safe=''))
+    def _file_path(self, title, type='.xml'):
+        return os.path.join(self.path, urlquote(title, safe='')) + type
 
     def _title_to_file(self, title, type=".xml"):
         return os.path.join(self.repo_prefix, urlquote(title, safe='')) + type
@@ -160,7 +158,7 @@ class VersionedStorage(object):
         return urlunquote(name)
 
     def __contains__(self, title):
-        return urlquote(title) in self.repo['tip']
+        return self._title_to_file(title) in self.repo['tip']
 
     def __iter__(self):
         return self.all_pages()
@@ -221,6 +219,8 @@ class VersionedStorage(object):
             author = '<wiki>'
             comment = msg.encode('utf-8')
 
+        logger.debug("Commiting %r", repo_file)
+
         self._commit([repo_file], comment, author)
 
     def save_data(self, title, data, **kwargs):
@@ -440,3 +440,12 @@ class VersionedStorage(object):
         for filename in modified + added + removed + deleted:
             if filename.startswith(self.repo_prefix):
                 yield self._file_to_title(filename)
+
+    def revert(self, pageid, rev, **commit_args):
+        """ Make the given version of page the current version (reverting changes). """
+
+        # Find the old version
+        fctx = self._find_filectx(pageid, rev)
+
+        # Restore the contents
+        self.save_data(pageid, fctx.data(), **commit_args)
diff --git a/lib/vstorage/hgui.py b/lib/vstorage/hgui.py
new file mode 100644 (file)
index 0000000..bae3f09
--- /dev/null
@@ -0,0 +1,57 @@
+"""
+    Mercurial ui module replacement.   
+"""
+
+import mercurial.ui
+import logging
+
+class SilentUI(mercurial.ui.ui):
+
+    def __init__(self, *args, **kwargs):
+        super(SilentUI, self).__init__(*args, **kwargs)
+
+        # make sure this doesn't collide with anything in Mercurial 
+        self.__logger = logging.getLogger('mercurial')
+
+    def _is_trusted(self, fd, filename):
+        """ Checks if config file is trusted - on server side, this isn't very useful. """
+        return True
+
+    def write(self, *args):
+        if self._buffers:
+            self._buffers[-1].extend([str(a) for a in args])
+        else:
+            self.__logger.info(''.join(args))
+
+    def write_err(self, *args):
+        self.__logger.error(''.join(args))
+
+    def flush(self):
+        pass
+
+    def interactive(self):
+        return False
+
+    def _readline(self, prompt=''):
+        return u''
+
+    def status(self, *msg):
+        self.__logger.debug(''.join(msg))
+
+    def warn(self, *msg):
+        self.__logger.warn(''.join(msg))
+
+    def note(self, *msg):
+        self.__logger.info(''.join(msg))
+
+    def debug(self, *msg):
+        self.__logger.debug(''.join(msg))
+
+    def edit(self, text, user):
+        return text
+
+    def traceback(self, exc=None):
+        if exc is not None: self.__logger.exception()
+
+    def progress(self, *args):
+        pass
index 10618f1..25e2b06 100644 (file)
@@ -60,6 +60,7 @@ class TestVersionedStorage(object):
                     text=text, author=author,
                     comment=comment, parent=None)
 
+
         saved_text, rev = self.repo.page_text(title)
         assert_equal(saved_text, text)
         assert_equal(rev, 0)
@@ -128,11 +129,11 @@ text
                     text=text, author=author,
                     comment=comment, parent=None)
 
-        assert title in self.repo
+        ok_(title in self.repo, "Document not in repository.")
 
         self.repo.delete_page(title, author, comment)
 
-        assert title not in self.repo
+        ok_(title not in self.repo, "Document in repository after delete")
 
     @raises(vstorage.DocumentNotFound)
     def test_document_not_found(self):
@@ -161,6 +162,24 @@ text
             assert_equal(entry["description"], COMMITS[n]["comment"])
             assert_equal(entry["tag"], [])
 
+    def test_data_revert(self):
+        COMMITS = [
+            {u"title": u"one", "author": "bunny", "text":"1.1", "comment": "1"},
+            {u"title": u"one", "author": "frank", "text":"1.2", "comment": "2"},
+            {u"title": u"two", "author": "bunny", "text":"2.1", "comment": "3"},
+            {u"title": u"one", "author": "frank", "text":"1.3", "comment": "4"},
+        ]
+
+        for commit in COMMITS:
+            self.repo.save_text(**commit)
+
+        # now revert last change on one
+        self.repo.revert(u"one", 0)
+        assert_equal(self.repo.page_text(u"one"), (u"1.1", 3))
+        assert_equal(self.repo.page_text(u"two"), (u"2.1", 0))
+
+        self.repo.revert(u"one", 2)
+        assert_equal(self.repo.page_text(u"one"), (u"1.3", 4))
 
 class TestVSTags(object):