From b2d72160e2a68991c66ea6017b871d7f42c0b29d Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C5=81ukasz=20Rekucki?= Date: Mon, 21 Sep 2009 11:09:57 +0200 Subject: [PATCH] Testy do Client API. --- apps/api/__init__.py | 0 apps/api/forms.py | 20 ++ apps/api/handlers.py | 157 ++++++++ apps/api/models.py | 3 + apps/api/tests.py | 23 ++ apps/api/tests/__init__.py | 199 ++++++++++ apps/api/tests/data/empty/.hg/00changelog.i | Bin 0 -> 57 bytes .../tests/data/empty/.hg/branchheads.cache | 2 + apps/api/tests/data/empty/.hg/dirstate | Bin 0 -> 65 bytes apps/api/tests/data/empty/.hg/requires | 3 + .../tests/data/empty/.hg/store/00changelog.i | Bin 0 -> 169 bytes .../tests/data/empty/.hg/store/00manifest.i | Bin 0 -> 115 bytes .../data/empty/.hg/store/data/.library.i | Bin 0 -> 64 bytes apps/api/tests/data/empty/.hg/store/fncache | 1 + apps/api/tests/data/empty/.hg/store/undo | Bin 0 -> 49 bytes apps/api/tests/data/empty/.hg/undo.branch | 1 + apps/api/tests/data/empty/.hg/undo.dirstate | Bin 0 -> 65 bytes apps/api/tests/data/empty/.library | 0 apps/api/tests/data/test2/.hg/00changelog.i | Bin 0 -> 57 bytes apps/api/tests/data/test2/.hg/branch | 1 + .../tests/data/test2/.hg/branchheads.cache | 3 + apps/api/tests/data/test2/.hg/dirstate | Bin 0 -> 98 bytes apps/api/tests/data/test2/.hg/requires | 3 + .../tests/data/test2/.hg/store/00changelog.i | Bin 0 -> 553 bytes .../tests/data/test2/.hg/store/00manifest.i | Bin 0 -> 372 bytes .../data/test2/.hg/store/data/.library.i | Bin 0 -> 64 bytes .../test2/.hg/store/data/pub__testfile.xml.i | Bin 0 -> 85 bytes apps/api/tests/data/test2/.hg/store/fncache | 2 + apps/api/tests/data/test2/.hg/store/undo | Bin 0 -> 35 bytes apps/api/tests/data/test2/.hg/undo.branch | 1 + apps/api/tests/data/test2/.hg/undo.dirstate | Bin 0 -> 98 bytes apps/api/tests/data/test2/.library | 0 apps/api/tests/data/test2/pub_testfile.xml | 1 + apps/api/tests/data/testone/.hg/00changelog.i | Bin 0 -> 57 bytes .../tests/data/testone/.hg/branchheads.cache | 2 + apps/api/tests/data/testone/.hg/dirstate | Bin 0 -> 98 bytes apps/api/tests/data/testone/.hg/requires | 3 + .../data/testone/.hg/store/00changelog.i | Bin 0 -> 348 bytes .../tests/data/testone/.hg/store/00manifest.i | Bin 0 -> 249 bytes .../data/testone/.hg/store/data/.library.i | Bin 0 -> 64 bytes .../.hg/store/data/pub__testfile.xml.i | Bin 0 -> 85 bytes apps/api/tests/data/testone/.hg/store/fncache | 2 + apps/api/tests/data/testone/.hg/store/undo | Bin 0 -> 61 bytes apps/api/tests/data/testone/.hg/undo.branch | 1 + apps/api/tests/data/testone/.hg/undo.dirstate | Bin 0 -> 98 bytes apps/api/tests/data/testone/.library | 0 apps/api/tests/data/testone/pub_testfile.xml | 1 + apps/api/urls.py | 48 +++ apps/api/utils.py | 25 ++ apps/api/views.py | 1 + lib/run_tests.sh | 1 + lib/wlrepo/__init__.py | 111 ++++++ lib/wlrepo/backend_mercurial.py | 339 ++++++++++++++++++ lib/wlrepo/tests/__init__.py | 7 + .../data/repos/cleanrepo/.hg/00changelog.i | Bin 0 -> 57 bytes .../tests/data/repos/cleanrepo/.hg/dirstate | Bin 0 -> 130 bytes .../tests/data/repos/cleanrepo/.hg/requires | 3 + .../repos/cleanrepo/.hg/store/00changelog.i | Bin 0 -> 366 bytes .../repos/cleanrepo/.hg/store/00manifest.i | Bin 0 -> 265 bytes .../cleanrepo/.hg/store/data/.hgignore.i | Bin 0 -> 64 bytes .../cleanrepo/.hg/store/data/ignored__file.i | Bin 0 -> 64 bytes .../.hg/store/data/pub__valid__file.xml.i | Bin 0 -> 64 bytes .../data/repos/cleanrepo/.hg/store/fncache | 3 + .../tests/data/repos/cleanrepo/.hg/store/undo | Bin 0 -> 85 bytes .../data/repos/cleanrepo/.hg/undo.branch | 1 + .../data/repos/cleanrepo/.hg/undo.dirstate | Bin 0 -> 130 bytes .../tests/data/repos/cleanrepo/.hgignore | 0 .../tests/data/repos/cleanrepo/ignored_file | 0 .../data/repos/cleanrepo/pub_valid_file.xml | 0 .../data/repos/testrepoI/.hg/00changelog.i | Bin 0 -> 57 bytes .../tests/data/repos/testrepoI/.hg/dirstate | Bin 0 -> 166 bytes .../tests/data/repos/testrepoI/.hg/requires | 3 + .../repos/testrepoI/.hg/store/00changelog.i | Bin 0 -> 545 bytes .../repos/testrepoI/.hg/store/00manifest.i | Bin 0 -> 442 bytes .../testrepoI/.hg/store/data/.hgignore.i | Bin 0 -> 64 bytes .../testrepoI/.hg/store/data/ignored__file.i | Bin 0 -> 64 bytes .../.hg/store/data/pub__polish__file.xml.i | Bin 0 -> 73 bytes .../.hg/store/data/pub__valid__file.xml.i | Bin 0 -> 152 bytes .../data/repos/testrepoI/.hg/store/fncache | 4 + .../tests/data/repos/testrepoI/.hg/store/undo | Bin 0 -> 93 bytes .../data/repos/testrepoI/.hg/undo.branch | 1 + .../data/repos/testrepoI/.hg/undo.dirstate | Bin 0 -> 166 bytes .../tests/data/repos/testrepoI/.hgignore | 0 .../tests/data/repos/testrepoI/ignored_file | 0 .../data/repos/testrepoI/pub_polish_file.xml | 1 + .../data/repos/testrepoI/pub_valid_file.xml | 1 + .../data/repos/testrepoII/.hg/00changelog.i | Bin 0 -> 57 bytes .../tests/data/repos/testrepoII/.hg/branch | 1 + .../repos/testrepoII/.hg/branchheads.cache | 4 + .../tests/data/repos/testrepoII/.hg/dirstate | Bin 0 -> 166 bytes .../tests/data/repos/testrepoII/.hg/requires | 3 + .../repos/testrepoII/.hg/store/00changelog.i | Bin 0 -> 947 bytes .../repos/testrepoII/.hg/store/00manifest.i | Bin 0 -> 670 bytes .../testrepoII/.hg/store/data/.hgignore.i | Bin 0 -> 64 bytes .../testrepoII/.hg/store/data/ignored__file.i | Bin 0 -> 64 bytes .../.hg/store/data/pub__polish__file.xml.i | Bin 0 -> 73 bytes .../.hg/store/data/pub__valid__file.xml.i | Bin 0 -> 152 bytes .../data/repos/testrepoII/.hg/store/fncache | 4 + .../data/repos/testrepoII/.hg/store/undo | Bin 0 -> 35 bytes .../data/repos/testrepoII/.hg/undo.branch | 1 + .../data/repos/testrepoII/.hg/undo.dirstate | Bin 0 -> 101 bytes .../tests/data/repos/testrepoII/.hgignore | 0 .../tests/data/repos/testrepoII/ignored_file | 0 .../data/repos/testrepoII/pub_polish_file.xml | 1 + .../data/repos/testrepoII/pub_valid_file.xml | 1 + lib/wlrepo/tests/test_mercurial.py | 99 +++++ 106 files changed, 1092 insertions(+) create mode 100644 apps/api/__init__.py create mode 100644 apps/api/forms.py create mode 100644 apps/api/handlers.py create mode 100644 apps/api/models.py create mode 100644 apps/api/tests.py create mode 100644 apps/api/tests/__init__.py create mode 100644 apps/api/tests/data/empty/.hg/00changelog.i create mode 100644 apps/api/tests/data/empty/.hg/branchheads.cache create mode 100644 apps/api/tests/data/empty/.hg/dirstate create mode 100644 apps/api/tests/data/empty/.hg/requires create mode 100644 apps/api/tests/data/empty/.hg/store/00changelog.i create mode 100644 apps/api/tests/data/empty/.hg/store/00manifest.i create mode 100644 apps/api/tests/data/empty/.hg/store/data/.library.i create mode 100644 apps/api/tests/data/empty/.hg/store/fncache create mode 100644 apps/api/tests/data/empty/.hg/store/undo create mode 100644 apps/api/tests/data/empty/.hg/undo.branch create mode 100644 apps/api/tests/data/empty/.hg/undo.dirstate create mode 100644 apps/api/tests/data/empty/.library create mode 100644 apps/api/tests/data/test2/.hg/00changelog.i create mode 100644 apps/api/tests/data/test2/.hg/branch create mode 100644 apps/api/tests/data/test2/.hg/branchheads.cache create mode 100644 apps/api/tests/data/test2/.hg/dirstate create mode 100644 apps/api/tests/data/test2/.hg/requires create mode 100644 apps/api/tests/data/test2/.hg/store/00changelog.i create mode 100644 apps/api/tests/data/test2/.hg/store/00manifest.i create mode 100644 apps/api/tests/data/test2/.hg/store/data/.library.i create mode 100644 apps/api/tests/data/test2/.hg/store/data/pub__testfile.xml.i create mode 100644 apps/api/tests/data/test2/.hg/store/fncache create mode 100644 apps/api/tests/data/test2/.hg/store/undo create mode 100644 apps/api/tests/data/test2/.hg/undo.branch create mode 100644 apps/api/tests/data/test2/.hg/undo.dirstate create mode 100644 apps/api/tests/data/test2/.library create mode 100644 apps/api/tests/data/test2/pub_testfile.xml create mode 100644 apps/api/tests/data/testone/.hg/00changelog.i create mode 100644 apps/api/tests/data/testone/.hg/branchheads.cache create mode 100644 apps/api/tests/data/testone/.hg/dirstate create mode 100644 apps/api/tests/data/testone/.hg/requires create mode 100644 apps/api/tests/data/testone/.hg/store/00changelog.i create mode 100644 apps/api/tests/data/testone/.hg/store/00manifest.i create mode 100644 apps/api/tests/data/testone/.hg/store/data/.library.i create mode 100644 apps/api/tests/data/testone/.hg/store/data/pub__testfile.xml.i create mode 100644 apps/api/tests/data/testone/.hg/store/fncache create mode 100644 apps/api/tests/data/testone/.hg/store/undo create mode 100644 apps/api/tests/data/testone/.hg/undo.branch create mode 100644 apps/api/tests/data/testone/.hg/undo.dirstate create mode 100644 apps/api/tests/data/testone/.library create mode 100644 apps/api/tests/data/testone/pub_testfile.xml create mode 100644 apps/api/urls.py create mode 100644 apps/api/utils.py create mode 100644 apps/api/views.py create mode 100755 lib/run_tests.sh create mode 100644 lib/wlrepo/__init__.py create mode 100644 lib/wlrepo/backend_mercurial.py create mode 100644 lib/wlrepo/tests/__init__.py create mode 100644 lib/wlrepo/tests/data/repos/cleanrepo/.hg/00changelog.i create mode 100644 lib/wlrepo/tests/data/repos/cleanrepo/.hg/dirstate create mode 100644 lib/wlrepo/tests/data/repos/cleanrepo/.hg/requires create mode 100644 lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/00changelog.i create mode 100644 lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/00manifest.i create mode 100644 lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/data/.hgignore.i create mode 100644 lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/data/ignored__file.i create mode 100644 lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/data/pub__valid__file.xml.i create mode 100644 lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/fncache create mode 100644 lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/undo create mode 100644 lib/wlrepo/tests/data/repos/cleanrepo/.hg/undo.branch create mode 100644 lib/wlrepo/tests/data/repos/cleanrepo/.hg/undo.dirstate create mode 100644 lib/wlrepo/tests/data/repos/cleanrepo/.hgignore create mode 100644 lib/wlrepo/tests/data/repos/cleanrepo/ignored_file create mode 100644 lib/wlrepo/tests/data/repos/cleanrepo/pub_valid_file.xml create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/.hg/00changelog.i create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/.hg/dirstate create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/.hg/requires create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/.hg/store/00changelog.i create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/.hg/store/00manifest.i create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/.hg/store/data/.hgignore.i create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/.hg/store/data/ignored__file.i create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/.hg/store/data/pub__polish__file.xml.i create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/.hg/store/data/pub__valid__file.xml.i create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/.hg/store/fncache create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/.hg/store/undo create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/.hg/undo.branch create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/.hg/undo.dirstate create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/.hgignore create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/ignored_file create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/pub_polish_file.xml create mode 100644 lib/wlrepo/tests/data/repos/testrepoI/pub_valid_file.xml create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hg/00changelog.i create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hg/branch create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hg/branchheads.cache create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hg/dirstate create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hg/requires create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hg/store/00changelog.i create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hg/store/00manifest.i create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hg/store/data/.hgignore.i create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hg/store/data/ignored__file.i create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hg/store/data/pub__polish__file.xml.i create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hg/store/data/pub__valid__file.xml.i create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hg/store/fncache create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hg/store/undo create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hg/undo.branch create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hg/undo.dirstate create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/.hgignore create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/ignored_file create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/pub_polish_file.xml create mode 100644 lib/wlrepo/tests/data/repos/testrepoII/pub_valid_file.xml create mode 100644 lib/wlrepo/tests/test_mercurial.py diff --git a/apps/api/__init__.py b/apps/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/api/forms.py b/apps/api/forms.py new file mode 100644 index 00000000..2b09e178 --- /dev/null +++ b/apps/api/forms.py @@ -0,0 +1,20 @@ +# -*- encoding: utf-8 -*- + +__author__= "Łukasz Rekucki" +__date__ = "$2009-09-20 21:34:52$" +__doc__ = "Micro-forms for the API." + + +from django import forms + +class DocumentGetForm(forms.Form): + autocabinet = forms.BooleanField(required=False) + + +class DocumentUploadForm(forms.Form): + ocr = forms.FileField(label='Source OCR file') + bookname = forms.RegexField(regex=r'[0-9\.\w_-]+', \ + label='Publication name', help_text='Example: slowacki-beniowski') + + generate_dc = forms.BooleanField(required=False, initial=True, label=u"Generate DublinCore template") + diff --git a/apps/api/handlers.py b/apps/api/handlers.py new file mode 100644 index 00000000..352e35e4 --- /dev/null +++ b/apps/api/handlers.py @@ -0,0 +1,157 @@ +from piston.handler import BaseHandler, AnonymousBaseHandler +from piston.utils import rc, validate + +import settings +import librarian +import api.forms as forms +from datetime import date + +from django.core.urlresolvers import reverse +from wlrepo import MercurialLibrary, CabinetNotFound + +# +# Document List Handlers +# +class BasicLibraryHandler(AnonymousBaseHandler): + allowed_methods = ('GET',) + + def read(self, request): + """Return the list of documents.""" + lib = MercurialLibrary(path=settings.REPOSITORY_PATH) + cab = lib.main_cabinet + + document_list = [{ + 'url': reverse('document_view', args=[docid]), + 'name': docid } for docid in cab.documents() ] + + return { + 'cabinet': cab.name, + 'latest_rev': cab.shelf(), + 'documents' : document_list } + +class LibraryHandler(BaseHandler): + allowed_methods = ('GET', 'POST') + anonymous = BasicLibraryHandler + + def read(self, request): + """Return the list of documents.""" + lib = MercurialLibrary(path=settings.REPOSITORY_PATH) + cab = lib.main_cabinet + + document_list = [{ + 'url': reverse('document_view', args=[docid]), + 'name': docid } for docid in cab.documents() ] + + return { + 'cabinet': cab.name, + 'latest_rev': cab.shelf(), + 'documents' : document_list } + + def create(self, request): + """Create a new document.""" + lib = MercurialLibrary(path=settings.REPOSITORY_PATH) + cab = lib.main_cabinet + + form = forms.DocumentUploadForm(request.POST, request.FILES) + if not form.is_valid(): + return rc.BAD_REQUEST + + f = request.FILES['ocr'] + data = f.read().decode('utf-8') + + if form.cleaned_data['generate_dc']: + data = librarian.wrap_text(data, unicode(date.today())) + + doc = cab.create(form.cleaned_data['bookname'], initial_data=data) + + return { + 'url': reverse('document_view', args=[doc.name]), + 'name': doc.name, + 'size': doc.size, + 'revision': doc.shelf() } + +# +# Document Handlers +# +class BasicDocumentHandler(AnonymousBaseHandler): + allowed_methods = ('GET',) + + def read(self, request, docid): + lib = MercurialLibrary(path=settings.REPOSITORY_PATH) + + opts = forms.DocumentGetForm(request.GET) + if not opts.is_valid(): + return rc.BAD_REQUEST + + document = lib.main_cabinet.retrieve(docid) + + result = { + 'name': document.name, + 'size': document.size, + 'text_url': reverse('doctext_view', args=[docid]), + #'dc_url': reverse('docdc_view', docid=document.name), + #'parts_url': reverse('docparts_view', docid=document.name), + 'latest_rev': document.shelf(), + } + + if request.GET.get('with_part', 'no') == 'yes': + result['parts'] = document.parts() + + return result + +class DocumentHandler(BaseHandler): + allowed_methods = ('GET', 'PUT') + anonymous = BasicDocumentHandler + + def read(self, request, docid): + """Read document's meta data""" + lib = MercurialLibrary(path=settings.REPOSITORY_PATH) + + opts = forms.DocumentGetForm(request.GET) + if not opts.is_valid(): + return rc.BAD_REQUEST + + document = lib.cabinet(docid, request.user.username, \ + create=opts.cleaned_data['autocabinet'] ).retrieve() + + shared = lib.main_cabinet.retrieve(docid) + + result = { + 'name': document.name, + 'size': document.size, + 'text_url': reverse('doctext_view', args=[docid]), + 'dc_url': reverse('docdc_view', args=[docid]), + 'parts_url': reverse('docparts_view', args=[docid]), + 'latest_rev': document.shelf(), + 'latest_shared_rev': shared.shelf(), + #'shared': lib.isparentof(document, shared), + #'up_to_date': lib.isparentof(shared, document), + } + + if request.GET.get('with_part', 'no') == 'yes': + result['parts'] = document.parts() + + return result + +# +# Document Text View +# +class DocumentTextHandler(BaseHandler): + allowed_methods = ('GET', 'PUT') + + def read(self, request, docid): + """Read document as raw text""" + lib = MercurialLibrary(path=settings.REPOSITORY_PATH) + try: + return lib.document(docid, request.user.username).read() + except CabinetNotFound: + return rc.NOT_HERE + + def update(self, request, docid): + lib = MercurialLibrary(path=settings.REPOSITORY_PATH) + try: + data = request.PUT['contents'] + lib.document(docid, request.user.username).write(data) + return rc.ALL_OK + except (CabinetNotFound, KeyError): + return rc.NOT_HERE \ No newline at end of file diff --git a/apps/api/models.py b/apps/api/models.py new file mode 100644 index 00000000..71a83623 --- /dev/null +++ b/apps/api/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/apps/api/tests.py b/apps/api/tests.py new file mode 100644 index 00000000..2247054b --- /dev/null +++ b/apps/api/tests.py @@ -0,0 +1,23 @@ +""" +This file demonstrates two different styles of tests (one doctest and one +unittest). These will both pass when you run "manage.py test". + +Replace these with more appropriate tests for your application. +""" + +from django.test import TestCase + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.failUnlessEqual(1 + 1, 2) + +__test__ = {"doctest": """ +Another way to test that 1 + 1 is equal to 2. + +>>> 1 + 1 == 2 +True +"""} + diff --git a/apps/api/tests/__init__.py b/apps/api/tests/__init__.py new file mode 100644 index 00000000..671978a1 --- /dev/null +++ b/apps/api/tests/__init__.py @@ -0,0 +1,199 @@ +""" +This file demonstrates two different styles of tests (one doctest and one +unittest). These will both pass when you run "manage.py test". + +Replace these with more appropriate tests for your application. +""" + +from django.test import TestCase +from django.test.client import Client +from django.core.urlresolvers import reverse + +from django.utils import simplejson as json + +from django.contrib.auth.models import User + +import settings +from os.path import join, dirname +from StringIO import StringIO +import shutil +import tempfile + +REPO_TEMPLATES = join(dirname(__file__), 'data') + +def temprepo(name): + def decorator(func): + def decorated(self, *args, **kwargs): + clean = False + try: + temp = tempfile.mkdtemp("", "testdir_" ) + shutil.copytree(join(REPO_TEMPLATES, name), join(temp, 'repo'), False) + settings.REPOSITORY_PATH = join(temp, 'repo') + func(self, *args, **kwargs) + clean = True + finally: + if not clean and self.response: + print "RESULT", func.__name__, ">>>" + print self.response + print "<<<" + + shutil.rmtree(temp, True) + settings.REPOSITORY_PATH = '' + + return decorated + return decorator + + +class SimpleTest(TestCase): + + def setUp(self): + self.response = None + u = User.objects.create_user('admin', 'test@localhost', 'admin') + u.save() + + @temprepo('empty') + def test_documents_get_anonymous(self): + self.response = self.client.get( reverse("document_list_view") ) + self.assert_json_response({ + u'latest_rev': u'e56b2a7e06a97d7c3697fc4295974e0f20a66190', + u'documents': [], + u'cabinet': u'default', + }, exclude=['latest_shared_rev']) + + @temprepo('empty') + def test_documents_get_with_login(self): + self.assertTrue(self.client.login(username='admin', password='admin')) + + self.response = self.client.get( reverse("document_list_view") ) + self.assert_json_response({ + u'latest_rev': u'e56b2a7e06a97d7c3697fc4295974e0f20a66190', + u'documents': [], + u'cabinet': u'default', + }) + + @temprepo('empty') + def test_documents_post(self): + self.assertTrue(self.client.login(username='admin', password='admin')) + + infile = tempfile.NamedTemporaryFile("w+") + infile.write('0123456789') + infile.flush() + infile.seek(0) + + self.response = self.client.post( reverse("document_list_view"), + data = { + 'bookname': 'testbook', + 'ocr': infile, + 'generate_dc': False, + }) + + infile.close() + + result = self.assert_json_response({ + 'url': reverse('document_view', args=['testbook']), + 'name': 'testbook', + 'size': 10, + # can't test revision number, 'cause it's random + },) + + @temprepo('empty') + def test_document_creation(self): + self.assertTrue(self.client.login(username='admin', password='admin')) + + infile = tempfile.NamedTemporaryFile("w+") + infile.write('012340123456789') + infile.flush() + infile.seek(0) + + self.response = self.client.post( reverse("document_list_view"), + data = { + 'bookname': 'testbook', + 'ocr': infile, + 'generate_dc': False, + }) + + r = self.assert_json_response({ + 'url': reverse('document_view', args=['testbook']), + 'name': 'testbook', + 'size': 15, + # can't test revision number, 'cause it's random + }) + + created_rev = r['revision'] + + self.response = self.client.get( \ + reverse("document_view", args=["testbook"])+'?autocabinet=true' ) + + result = self.assert_json_response({ + u'latest_shared_rev': created_rev, + u'size': 15, + }) + + + @temprepo('testone') + def test_document_meta_get_with_login(self): + self.assertTrue(self.client.login(username='admin', password='admin')) + + self.response = self.client.get( reverse("document_list_view") ) + self.assert_json_response({ + u'latest_rev': u'f94a263812dbe46a3a13d5209bb119988d0078d5', + u'documents': [{u'url': u'/api/documents/testfile', u'name': u'testfile'}], + u'cabinet': u'default', + }) + + self.response = self.client.get( \ + reverse("document_view", args=['testfile'])+'?autocabinet=true' ) + + self.assert_json_response({ + u'latest_shared_rev': u'f94a263812dbe46a3a13d5209bb119988d0078d5', + u'text_url': reverse("doctext_view", args=[u'testfile']), + u'dc_url': reverse("docdc_view", args=[u'testfile']), + u'parts_url': reverse("docparts_view", args=[u'testfile']), + u'name': u'testfile', + u'size': 20, + }) + + + @temprepo('test2') + def test_document_text_with_login(self): + self.assertTrue(self.client.login(username='admin', password='admin')) + + self.response = self.client.get( \ + reverse("doctext_view", args=['testfile']) ) + + self.assertEqual(self.response.status_code, 200) + self.assertEqual(self.response.content, "Test file contents.\n") + + + @temprepo('test2') + def test_document_text_update(self): + self.assertTrue(self.client.login(username='admin', password='admin')) + TEXT = u"Ala ma kota i psa" + + self.response = self.client.put( \ + reverse("doctext_view", args=['testfile']), {'contents': TEXT }) + self.assertEqual(self.response.status_code, 200) + + self.response = self.client.get( \ + reverse("doctext_view", args=['testfile']) ) + self.assertEqual(self.response.status_code, 200) + self.assertEqual(self.response.content, TEXT) + + def assert_json_response(self, must_have={}, exclude=[]): + self.assertEqual(self.response.status_code, 200) + result = json.loads(self.response.content) + + for (k,v) in must_have.items(): + self.assertTrue(result.has_key(k), "Required field '%s' missing in response." % k) + self.assertEqual(result[k], v) + + if exclude is True: + for (k,v) in result.items(): + self.assertTrue(must_have.has_key(k)) + self.assertEqual(must_have[k], v) + + for key in exclude: + self.assertFalse(result.has_key(key)) + + return result + \ No newline at end of file diff --git a/apps/api/tests/data/empty/.hg/00changelog.i b/apps/api/tests/data/empty/.hg/00changelog.i new file mode 100644 index 0000000000000000000000000000000000000000..d3a8311050e54c57c5be7cfe169e60a95768812c GIT binary patch literal 57 zcmWN_K?=Yi3h($ literal 0 HcmV?d00001 diff --git a/apps/api/tests/data/empty/.hg/requires b/apps/api/tests/data/empty/.hg/requires new file mode 100644 index 00000000..5175383b --- /dev/null +++ b/apps/api/tests/data/empty/.hg/requires @@ -0,0 +1,3 @@ +revlogv1 +store +fncache diff --git a/apps/api/tests/data/empty/.hg/store/00changelog.i b/apps/api/tests/data/empty/.hg/store/00changelog.i new file mode 100644 index 0000000000000000000000000000000000000000..f6361419fd9f94de756b336366331ce573bd6ebb GIT binary patch literal 169 zcmZQzWME`~fJ`8j17$P(hk~csT6JtIYirD=|8bf+-H%^kS>gnk8W3GENA{Q@-(dwF zh68ukpJ4CG5o)@*>zm{;POVA8B8Mj34}aymeCY+ZLz?bimYkSra{NSRcb-teLxI1u zB-Xs2zHjZy8{6+5{#*Wz`9ynVWTo4jxQoh7n`iC*!v3K6THsN&+~a}mzZnmPDAWM} DWl~7n literal 0 HcmV?d00001 diff --git a/apps/api/tests/data/empty/.hg/store/00manifest.i b/apps/api/tests/data/empty/.hg/store/00manifest.i new file mode 100644 index 0000000000000000000000000000000000000000..267c71add2ecbb538408cc402e6b67403377ed04 GIT binary patch literal 115 zcmZQzWME`~0AnC!1Z6Y)hl2ATFRqwfpm?BLW_!hqKeqxr!qsNL)PU$xy`0RXqQs&~ uh9nDvlvL9cLt_hbQwviQ!(`Jm15+b2)5H`*6O+Uw%d|ubvlPRWBrX7{+9C)5 literal 0 HcmV?d00001 diff --git a/apps/api/tests/data/empty/.hg/store/data/.library.i b/apps/api/tests/data/empty/.hg/store/data/.library.i new file mode 100644 index 0000000000000000000000000000000000000000..2431023a17b1e7b5c96e5db8e264c251f39beab0 GIT binary patch literal 64 ncmZQzWME{#0{%n64&J91ElOJ*kA4VBT`S_X^H%VaR%GBC(Z%*#wmEiQp_lQRLVSAd^EcCo`!iv8WONnu-gB literal 0 HcmV?d00001 diff --git a/apps/api/tests/data/empty/.library b/apps/api/tests/data/empty/.library new file mode 100644 index 00000000..e69de29b diff --git a/apps/api/tests/data/test2/.hg/00changelog.i b/apps/api/tests/data/test2/.hg/00changelog.i new file mode 100644 index 0000000000000000000000000000000000000000..d3a8311050e54c57c5be7cfe169e60a95768812c GIT binary patch literal 57 zcmWN_K?=Yi3?`$?9S@KuG`8zpD-GE`h;zyk6>V*jB4$mGz=$xJFrEUE-bG%f)OhW^(u060L2v^h5!Hn literal 0 HcmV?d00001 diff --git a/apps/api/tests/data/test2/.hg/requires b/apps/api/tests/data/test2/.hg/requires new file mode 100644 index 00000000..5175383b --- /dev/null +++ b/apps/api/tests/data/test2/.hg/requires @@ -0,0 +1,3 @@ +revlogv1 +store +fncache diff --git a/apps/api/tests/data/test2/.hg/store/00changelog.i b/apps/api/tests/data/test2/.hg/store/00changelog.i new file mode 100644 index 0000000000000000000000000000000000000000..4d3d86a3c0176126e1d5b8f2e123ea1608d00901 GIT binary patch literal 553 zcmZQzWME`~fJ`8j17$P(hk~csT6JtIYirD=|8bf+-H%^kS>gnk8W3GENA{Q@-(dwF zh68ukpJ4CG5o)@*>zm{;POVA8B8Mj34}aymeCY+ZLz?bimYkSra{NSRcb-teLxI1u zB-Xs2zHjZy8{6+5{#*Wz`9ynVWTo4jxQoh7n`iC*!v3K6THsN&+~a}mzZnmPDAa*1 z1v!y{p%{oO!7K)d<3Voy>7`~Nbo)t`mGD)C*&8Ki^fFXjg{lEl6?2jk7?^zp{Jc%P zy#0(lx0v`CdYYMf8~b}2ni+2Q*lOTuVqj!!?qTL_k*V26 z12bcTunVT`CJ$3awPoMF;y86Uf#+7}nk7N|Y3Vl31eFGUhH4gwS=DjRe z0k-!JnCu0Ti-DL4iWxypo}Ab(eAsGrlr76Vj)b$eic7-J)`C?-iHbS8XMFjZ6$Bg} z+Ae>9z9v(du&OA#PdCF z@}EU`7CdU}FL^wxVSAO=_h84sYrK2s*T}QgO3pR3GSkT1EqCKwRD*a#xt6!uG1m`M l^h1t+IeE)_WwoMW!rWK;CclW8Z6{^x_`&|wy~&fz`T(I_&I#eZ32$2-xUWg@08ifQ`M14)B&-9gh7zUZTMYmdt7j4b literal 0 HcmV?d00001 diff --git a/apps/api/tests/data/test2/.hg/store/data/.library.i b/apps/api/tests/data/test2/.hg/store/data/.library.i new file mode 100644 index 0000000000000000000000000000000000000000..2431023a17b1e7b5c96e5db8e264c251f39beab0 GIT binary patch literal 64 ncmZQzWME{#0{%n64&J91ElOJ*kA4VBT`S_X^H?`$?9S@KuG`8zpD-GE`h;zygZU#5nYFGLwoDiz@RN7#f!VB}KfpEwKmE V0tKZ>@g=FnC25&Csd^Q;IRHKv7P0^U literal 0 HcmV?d00001 diff --git a/apps/api/tests/data/test2/.library b/apps/api/tests/data/test2/.library new file mode 100644 index 00000000..e69de29b diff --git a/apps/api/tests/data/test2/pub_testfile.xml b/apps/api/tests/data/test2/pub_testfile.xml new file mode 100644 index 00000000..57873f23 --- /dev/null +++ b/apps/api/tests/data/test2/pub_testfile.xml @@ -0,0 +1 @@ +Test file contents. diff --git a/apps/api/tests/data/testone/.hg/00changelog.i b/apps/api/tests/data/testone/.hg/00changelog.i new file mode 100644 index 0000000000000000000000000000000000000000..d3a8311050e54c57c5be7cfe169e60a95768812c GIT binary patch literal 57 zcmWN_K?=Yi3?`$?9S@KuG`8zpD-GE`h;zyk6Z7#f#=#J#pHQ3O&PdO4X%MTtd~FbNT$ ZggsC~prAAgnk8W3GENA{Q@-(dwF zh68ukpJ4CG5o)@*>zm{;POVA8B8Mj34}aymeCY+ZLz?bimYkSra{NSRcb-teLxI1u zB-Xs2zHjZy8{6+5{#*Wz`9ynVWTo4jxQoh7n`iC*!v3K6THsN&+~a}mzZnmPDAa*1 z1v!y{p%{oO!7K)d<3Voy>7`~Nbo)t`mGD)C*&8Ki^fFXjg{lEl6?2jk7?^zp{Jc%P zy#0(lx0v`CdYYMf8~b}2ni+2Q*lOTuVqj!!?qTL_k*V26 z12bcTunVT`CJ$3awPoMF;y86Uf#+7}nk7N|Y3Vl31eFGUhH4gwS=DjRe F0RTDwd*}cF literal 0 HcmV?d00001 diff --git a/apps/api/tests/data/testone/.hg/store/00manifest.i b/apps/api/tests/data/testone/.hg/store/00manifest.i new file mode 100644 index 0000000000000000000000000000000000000000..0239a8f7899d5bdcd848c8340ba48fe20f00258e GIT binary patch literal 249 zcmZQzWME`~0AnC!1Z6Y)hl2ATFRqwfpm?BLW_!hqKeqxr!qsNL)PU$xy`0RXqQs&~ zh9nDvlvL9cLt_hbQwviQ!(`Jm15+b2)5H`*6O+Uw%d|ubvlPRWBrdRakYx-EZa|y^ zW-&mV0kZX%{&}y7SB~b_UUu(mS)f*MZ1dmiP&F_Lxml|json|yaml|django)$" + +library_resource = Resource(LibraryHandler, **authdata) +document_resource = Resource(DocumentHandler, **authdata) +document_text_resource = Resource(DocumentTextHandler, **authdata) + +urlpatterns = patterns('', +# url(r'^hello$', hello_resource, {'emitter_format': 'json'}), +# url(r'^hello\.(?P.+)$', hello_resource), + + # Documents + url(r'^documents$', library_resource, {'emitter_format': 'json'}, + name="document_list_view"), + + url(r'^documents/(?P[^/]+)'+FORMAT_EXT, + document_resource, name="document_view_withformat"), + + url(r'^documents/(?P[^/]+)$', + document_resource, {'emitter_format': 'json'}, + name="document_view"), + + url(r'^documents/(?P[^/]+)/text$', + document_text_resource, {'emitter_format': 'rawxml'}, + name="doctext_view"), + + url(r'^documents/(?P[^/]+)/dc$', + document_resource, {'emitter_format': 'json'}, + name="docdc_view"), + + url(r'^documents/(?P[^/]+)/parts$', + document_resource, {'emitter_format': 'json'}, + name="docparts_view"), + + # url(r'^posts/(?P[^/]+)/$', blogpost_resource), + # url(r'^other/(?P[^/]+)/(?P.+)/$', arbitrary_resource), +) + diff --git a/apps/api/utils.py b/apps/api/utils.py new file mode 100644 index 00000000..67e8ea5a --- /dev/null +++ b/apps/api/utils.py @@ -0,0 +1,25 @@ +# -*- encoding: utf-8 -*- + +__author__= "Łukasz Rekucki" +__date__ = "$2009-09-20 21:48:03$" +__doc__ = "Module documentation." + + +from piston.emitters import Emitter +from piston.utils import rc + +class TextEmitter(Emitter): + def render(self, request): + return unicode(self.construct()) + +Emitter.register('text', TextEmitter, 'text/plain; charset=utf-8') +Emitter.register('rawxml', TextEmitter, 'application/xml; charset=utf-8') + + +class DjangoAuth(object): + + def is_authenticated(self, request): + return request.user.is_authenticated() + + def challenge(self): + return rc.FORBIDDEN \ No newline at end of file diff --git a/apps/api/views.py b/apps/api/views.py new file mode 100644 index 00000000..60f00ef0 --- /dev/null +++ b/apps/api/views.py @@ -0,0 +1 @@ +# Create your views here. diff --git a/lib/run_tests.sh b/lib/run_tests.sh new file mode 100755 index 00000000..0b086ef2 --- /dev/null +++ b/lib/run_tests.sh @@ -0,0 +1 @@ +PYTYONPATH=./lib:$PYTHONPATH nosetests --detailed-errors --with-doctest --with-coverage --cover-package=wlrepo diff --git a/lib/wlrepo/__init__.py b/lib/wlrepo/__init__.py new file mode 100644 index 00000000..5c27dc97 --- /dev/null +++ b/lib/wlrepo/__init__.py @@ -0,0 +1,111 @@ +# -*- encoding: utf-8 -*- +__author__="Łukasz Rekucki" +__date__ ="$2009-09-18 10:49:24$" + +__doc__ = """Main module for the Repository Abstraction Layer""" + +class Library(object): + + def __init__(self, create=False): + """Open an existing library, or create a new one. By default, fails if + the library doesn't exist.""" + self.create = create + + def main_cabinet(self): + """Return the "main" cabinet of the library.""" + pass + + def cabinets(self): + """List all cabinets in the library.""" + pass + + def cabinet(self, document, user, create=False): + """Open a cabinet belonging to the _user_ for a given _document_. + If the _document_ is actually a sub-document, it's parent's cabinet is + opened istead. + + If the cabinet doesn't exists and create is False (the default), a + CabinetNotFound exception is raised. + + If create is True, a new cabinet is created if it doesn't exist yet.""" + pass + + +class Cabinet(object): + + def __init__(self, library, name=None, doc=None, user=None): + self._library = library + if name: + self._name = name + self._maindoc = '' + elif doc and user: + self._name = user + ':' + doc + self._maindoc = doc + else: + raise ValueError("You must provide either name or doc and user.") + + def documents(self): + """Lists all documents and sub-documents in this cabinet.""" + pass + + def retrieve(self, parts=None, shelve=None): + """Retrieve a document from a given shelve in the cabinet. If no + part is given, the main document is retrieved. If no shelve is given, + the top-most shelve is used. + + If parts is a list, all the given parts are retrieved atomicly. Use None + as the name for the main document""" + pass + + def create(self, name): + """Create a new sub-document in the cabinet with the given name.""" + pass + + def maindoc_name(self): + return self._maindoc + + + @property + def library(self): + return self._library + + @property + def name(self): + return self._name + +class Document(object): + def __init__(self, cabinet, name): + self._cabinet = cabinet + self._name = name + + def read(self): + pass + + def write(self, data): + pass + + @property + def cabinet(self): + return self._cabinet + + @property + def library(self): + return self._cabinet.library + + +# +# Exception classes +# + +class LibraryException(Exception): + + def __init__(self, msg, cause=None): + Exception.__init__(self, msg) + self.cause = cause + +class CabinetNotFound(LibraryException): + pass + + +# import backends to local namespace +from backend_mercurial import MercurialLibrary \ No newline at end of file diff --git a/lib/wlrepo/backend_mercurial.py b/lib/wlrepo/backend_mercurial.py new file mode 100644 index 00000000..38f01da6 --- /dev/null +++ b/lib/wlrepo/backend_mercurial.py @@ -0,0 +1,339 @@ +# -*- encoding: utf-8 -*- +__author__ = "Łukasz Rekucki" +__date__ = "$2009-09-18 10:49:24$" + +__doc__ = """RAL implementation over Mercurial""" + +import mercurial +from mercurial import localrepo as hglrepo +from mercurial import ui as hgui +import re +import wlrepo + +FILTER = re.compile(r"^pub_(.+)\.xml$", re.UNICODE) + +def default_filter(name): + m = FILTER.match(name) + if m is not None: + return name, m.group(1) + return None + +class MercurialLibrary(wlrepo.Library): + + def __init__(self, path, maincabinet="default", ** kwargs): + super(wlrepo.Library, self).__init__( ** kwargs) + + self._hgui = hgui.ui() + self._hgui.config('ui', 'quiet', 'true') + self._hgui.config('ui', 'interactive', 'false') + + import os.path + self._ospath = self._sanitize_string(os.path.realpath(path)) + + maincabinet = self._sanitize_string(maincabinet) + + if os.path.isdir(path): + try: + self._hgrepo = hglrepo.localrepository(self._hgui, path) + except mercurial.error.RepoError: + raise wlrepo.LibraryException("[HGLibrary]Not a valid repository at path '%s'." % path) + elif kwargs['create']: + os.makedirs(path) + try: + self._hgrepo = hglrepo.localrepository(self._hgui, path, create=1) + except mercurial.error.RepoError: + raise wlrepo.LibraryException("[HGLibrary] Can't create a repository on path '%s'." % path) + else: + raise wlrepo.LibraryException("[HGLibrary] Can't open a library on path '%s'." % path) + + # fetch the main cabinet + lock = self._hgrepo.lock() + try: + btags = self._hgrepo.branchtags() + + if not self._has_branch(maincabinet): + raise wlrepo.LibraryException("[HGLibrary] No branch named '%s' to init main cabinet" % maincabinet) + + self._maincab = MercurialCabinet(self, maincabinet) + finally: + lock.release() + + @property + def main_cabinet(self): + return self._maincab + + def cabinet(self, docid, user, create=False): + bname = self._bname(user, docid) + + lock = self._lock(True) + try: + if self._has_branch(bname): + return MercurialCabinet(self, bname, doc=docid, user=user) + + if not create: + raise wlrepo.CabinetNotFound(docid, user) + + # check if the docid exists in the main cabinet + needs_touch = not self._maincab.exists(docid) + print "Creating branch: ", needs_touch + cab = MercurialCabinet(self, bname, doc=docid, user=user) + + fileid = cab._fileid(None) + + def cleanup_action(l): + if needs_touch: + print "Touch for file", docid + l._fileopener()(fileid, "w").write('') + l._fileadd(fileid) + + garbage = [fid for (fid, did) in l._filelist() if not did.startswith(docid)] + print "Garbage: ", garbage + l._filesrm(garbage) + + # create the branch + self._create_branch(bname, before_commit=cleanup_action) + return MercurialCabinet(self, bname, doc=docid, user=user) + finally: + lock.release() + + # + # Private methods + # + + # + # Locking + # + + def _lock(self, write_mode=False): + return self._hgrepo.wlock() # no support for read/write mode yet + + def _transaction(self, write_mode, action): + lock = self._lock(write_mode) + try: + return action(self) + finally: + lock.release() + + # + # Basic repo manipulation + # + + def _checkout(self, rev, force=True): + return MergeStatus(mercurial.merge.update(self._hgrepo, rev, False, force, None)) + + def _merge(self, rev): + """ Merge the revision into current working directory """ + return MergeStatus(mercurial.merge.update(self._hgrepo, rev, True, False, None)) + + def _common_ancestor(self, revA, revB): + return self._hgrepo[revA].ancestor(self.repo[revB]) + + def _commit(self, message, user="library"): + return self._hgrepo.commit(\ + text=self._sanitize_string(message), \ + user=self._sanitize_string(user)) + + + def _fileexists(self, fileid): + return (fileid in self._hgrepo[None]) + + def _fileadd(self, fileid): + return self._hgrepo.add([fileid]) + + def _filesadd(self, fileid_list): + return self._hgrepo.add(fileid_list) + + def _filerm(self, fileid): + return self._hgrepo.remove([fileid]) + + def _filesrm(self, fileid_list): + return self._hgrepo.remove(fileid_list) + + def _filelist(self, filter=default_filter): + for name in self._hgrepo[None]: + result = filter(name) + if result is None: continue + + yield result + + def _fileopener(self): + return self._hgrepo.wopener + + # + # BASIC BRANCH routines + # + + def _bname(self, user, docid): + """Returns a branch name for a given document and user.""" + docid = self._sanitize_string(docid) + uname = self._sanitize_string(user) + return "personal_" + uname + "_file_" + docid; + + def _has_branch(self, name): + return self._hgrepo.branchmap().has_key(self._sanitize_string(name)) + + def _branch_tip(self, name): + name = self._sanitize_string(name) + return self._hgrepo.branchtags()[name] + + def _create_branch(self, name, parent=None, before_commit=None): + name = self._sanitize_string(name) + + if self._has_branch(name): return # just exit + + if parent is None: + parent = self._maincab + + parentrev = parent._hgtip() + + self._checkout(parentrev) + self._hgrepo.dirstate.setbranch(name) + + if before_commit: before_commit(self) + + print "commiting" + self._commit("[AUTO] Initial commit for branch '%s'." % name, user='library') + + # revert back to main + self._checkout(self._maincab._hgtip()) + return self._branch_tip(name) + + def _switch_to_branch(self, branchname): + current = self._hgrepo[None].branch() + + if current == branchname: + return current # quick exit + + self._checkout(self._branch_tip(branchname)) + return branchname + + # + # Merges + # + + + + # + # Utils + # + + @staticmethod + def _sanitize_string(s): + if isinstance(s, unicode): # + return s.encode('utf-8') + else: # it's a string, so we have no idea what encoding it is + return s + +class MercurialCabinet(wlrepo.Cabinet): + + def __init__(self, library, branchname, doc=None, user=None): + if doc and user: + super(MercurialCabinet, self).__init__(library, doc=doc, user=user) + else: + super(MercurialCabinet, self).__init__(library, name=branchname) + + self._branchname = branchname + + def documents(self): + return self._execute_in_branch(action=lambda l, c: ( e[1] for e in l._filelist()) ) + + def retrieve(self, part=None, shelve=None): + fileid = self._fileid(part) + + if fileid is None: + raise wlrepo.LibraryException("Can't retrieve main document from main cabinet.") + + return self._execute_in_branch(lambda l, c: MercurialDocument(c, fileid)) + + def create(self, name, initial_data=''): + fileid = self._fileid(name) + + if name is None: + raise ValueError("Can't create main doc for maincabinet.") + + def create_action(l, c): + if l._fileexists(fileid): + raise wlrepo.LibraryException("Can't create document '%s' in cabinet '%s' - it already exists" % (fileid, c.name)) + + fd = l._fileopener()(fileid, "w") + fd.write(initial_data) + l._fileadd(fileid) + l._commit("File '%d' created.") + + return MercurialDocument(c, fileid) + + return self._execute_in_branch(create_action) + + def exists(self, part=None, shelve=None): + fileid = self._fileid(part) + + if fileid is None: return false + return self._execute_in_branch(lambda l, c: l._fileexists(fileid)) + + def _execute_in_branch(self, action, write=False): + def switch_action(library): + old = library._switch_to_branch(self._branchname) + try: + return action(library, self) + finally: + library._switch_to_branch(old) + + return self._library._transaction(write_mode=write, action=switch_action) + + def _fileid(self, part): + fileid = None + + if self._maindoc == '': + if part is None: return None + fileid = part + else: + fileid = self._maindoc + (('$' + part) if part else '') + + return 'pub_' + fileid + '.xml' + + def _fileopener(self): + return self._library._fileopener() + + def _hgtip(self): + return self._library._branch_tip(self._branchname) + +class MercurialDocument(wlrepo.Document): + + def __init__(self, cabinet, fileid): + super(MercurialDocument, self).__init__(cabinet, fileid) + self._opener = self._cabinet._fileopener() + + def read(self): + return self._opener(self._name, "r").read() + + def write(self, data): + return self._opener(self._name, "w").write(data) + + +class MergeStatus(object): + def __init__(self, mstatus): + self.updated = mstatus[0] + self.merged = mstatus[1] + self.removed = mstatus[2] + self.unresolved = mstatus[3] + + def isclean(self): + return self.unresolved == 0 + +class UpdateStatus(object): + + def __init__(self, mstatus): + self.modified = mstatus[0] + self.added = mstatus[1] + self.removed = mstatus[2] + self.deleted = mstatus[3] + self.untracked = mstatus[4] + self.ignored = mstatus[5] + self.clean = mstatus[6] + + def has_changes(self): + return bool(len(self.modified) + len(self.added) + \ + len(self.removed) + len(self.deleted)) + + +__all__ = ["MercurialLibrary", "MercurialCabinet", "MercurialDocument"] \ No newline at end of file diff --git a/lib/wlrepo/tests/__init__.py b/lib/wlrepo/tests/__init__.py new file mode 100644 index 00000000..c9e2f1d7 --- /dev/null +++ b/lib/wlrepo/tests/__init__.py @@ -0,0 +1,7 @@ +# -*- encoding: utf-8 -*- + +__author__= "Łukasz Rekucki" +__date__ = "$2009-09-18 14:42:53$" +__doc__ = "Test package for WL-RAL" + + diff --git a/lib/wlrepo/tests/data/repos/cleanrepo/.hg/00changelog.i b/lib/wlrepo/tests/data/repos/cleanrepo/.hg/00changelog.i new file mode 100644 index 0000000000000000000000000000000000000000..d3a8311050e54c57c5be7cfe169e60a95768812c GIT binary patch literal 57 zcmWN_K?=Yi3@Mjj?cSw?dOV93|K%O14H8ykhs_8E;k@0R8X1}UzV7YnG&Ct mnUktlk(-00q*Ds0gi|jgJu^KozbF++rpq2E!vhh9XaxYsUnMaB literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/cleanrepo/.hg/requires b/lib/wlrepo/tests/data/repos/cleanrepo/.hg/requires new file mode 100644 index 00000000..5175383b --- /dev/null +++ b/lib/wlrepo/tests/data/repos/cleanrepo/.hg/requires @@ -0,0 +1,3 @@ +revlogv1 +store +fncache diff --git a/lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/00changelog.i b/lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/00changelog.i new file mode 100644 index 0000000000000000000000000000000000000000..45c1c46177d336ccad272b8c6cf07f3c682a4075 GIT binary patch literal 366 zcmZQzWME`~fNUU@4`nm_hk~=S;zLg^v+$|qZP;?$crmy9%Z5^z8W3GENA{RC-(dwF zh6{I>pJ44eP?&Q=>!}Lgg#MNVsycgXm+pBvQQfmqH1bi?Id;E1{~d`7Vkf0PT(L>h z@#RnH`%7JQ(|5O5hJ9veKizXL>d;Ho4BZ)@cl6z=VvF#;X7%+?=6BPm|1<5GY7`fN ztpz!ffuR|QyTL35i1R_Nm33R5vFjhp%&X$erPq$nyLIj7ic?TEV5(w{>S;&5Lka?{ z7uM};h~B1`Bay(eE$-k}vxduUEn=6$9)Dz=`$V_y-~4sI?{3@}m((G+_}FG8<=$fs zhbnm$<_JAtl=0fIrceLsTBZprmWX;u*BJ$IOk1{e%@>JdQ#x(q6Dxkt`M2@^nVq)x dR|muWc(kRlNkJ21J+YWu#}O=j9ir zG9+0Tq@{0V2{o&YfH71pwttR|xQPrLGn6+WD*P;%#K*02?S1MgRZ+ literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/data/pub__valid__file.xml.i b/lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/data/pub__valid__file.xml.i new file mode 100644 index 0000000000000000000000000000000000000000..a6bdf46f1091be151835fda73ea8ccb9f8c70c21 GIT binary patch literal 64 ocmZQzWME{#1dRWoUQPrLGn6+WD*P;%#K*02?S1MgRZ+ literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/fncache b/lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/fncache new file mode 100644 index 00000000..a1607dd1 --- /dev/null +++ b/lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/fncache @@ -0,0 +1,3 @@ +data/.hgignore.i +data/ignored_file.i +data/pub_valid_file.xml.i diff --git a/lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/undo b/lib/wlrepo/tests/data/repos/cleanrepo/.hg/store/undo new file mode 100644 index 0000000000000000000000000000000000000000..90d4cb1dc75ccb52022f9d46d05a89318eb8531c GIT binary patch literal 85 zcmYdEEJ@VQOwY?NN==DR%gjmD%VaR%N&$%$lqSWOCFW#8#Vc}iz;Xr#xruq1X{p5} aK(3*o8JB@Uaz*D?aq(G7Fzt-i9s5jTdvvzicRFzycCMV*jB4$P_9lO^Po|%*jlNPs_|n)vL(O j$zxz>Tmn+&wYgIYNO9_Aq-Un*pJ44eP?&Q=>!}Lgg#MNVsycgXm+pBvQQfmqH1bi?Id;E1{~d`7Vkf0PT(L>h z@#RnH`%7JQ(|5O5hJ9veKizXL>d;Ho4BZ)@cl6z=VvF#;X7%+?=6BPm|1<5GY7`fN ztpz!ffuR|QyTL35i1R_Nm33R5vFjhp%&X$erPq$nyLIj7ic?TEV5(w{>S;&5Lka?{ z7uM};h~B1`Bay(eE$-k}vxduUEn=6$9)Dz=`$V_y-~4sI?{3@}m((G+_}FG8<=$fs zhbnm$<_JAtl=0fIrceLsTBZprmWX;u*BJ$IOk1{e%@>JdQ#x(q6Dxkt`M2@^nVq)x zR|muWc(kRlNkJ21J+YWu#}O=j9ir zG9+0Tq@{0V2{o&YfH71=!?HFj)vBAAwm63`{_p5#*?s97-9I{z^erhG`zsf+EJ( zW(1o-)qtsrIj*N2xtI)j7!J(&ZaAszvPtFHNh#4fAu$53@=xrqPHwm4W8h(^sNdVS zJO6lT-|foR$=fb}HgYuVPSO(dY2{fu%cNLc>5I_L?5kI^qUwGo7QgwgJ?l)t*&8#J ar|exU_&q~W?oDRuMq8(8{1-XYCIA58f0nHP literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/testrepoI/.hg/store/data/.hgignore.i b/lib/wlrepo/tests/data/repos/testrepoI/.hg/store/data/.hgignore.i new file mode 100644 index 0000000000000000000000000000000000000000..2431023a17b1e7b5c96e5db8e264c251f39beab0 GIT binary patch literal 64 ncmZQzWME{#0{%n64&J91ElOJ*kA4VBT`S_X^HQPrLGn6+WD*P;%#K*02?S1MgRZ+ literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/testrepoI/.hg/store/data/pub__polish__file.xml.i b/lib/wlrepo/tests/data/repos/testrepoI/.hg/store/data/pub__polish__file.xml.i new file mode 100644 index 0000000000000000000000000000000000000000..3488bccb18f799c89d416b5fca591ba90e6ee85c GIT binary patch literal 73 zcmZQzWME`~08Svq0cA7&hk^+j6GYdfge+)Z@oKk=!`4GTE3FElYQR*f`;pe->_kN_ E0K(N3$^ZZW literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/testrepoI/.hg/store/data/pub__valid__file.xml.i b/lib/wlrepo/tests/data/repos/testrepoI/.hg/store/data/pub__valid__file.xml.i new file mode 100644 index 0000000000000000000000000000000000000000..fd3c7f7b76f7cc2c3d01256a69093bd8f5817e58 GIT binary patch literal 152 zcmZQzWME{#1dRWoUQPrLGn6+WD*P;%!XjU=ax*$pe*R0?{BNI;9pE m@u!`cwx7%G&ztUJ8_l}zoPer9r+6H55*2b26|(b761f1Y*(LG- literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/testrepoI/.hg/store/fncache b/lib/wlrepo/tests/data/repos/testrepoI/.hg/store/fncache new file mode 100644 index 00000000..8730267a --- /dev/null +++ b/lib/wlrepo/tests/data/repos/testrepoI/.hg/store/fncache @@ -0,0 +1,4 @@ +data/.hgignore.i +data/ignored_file.i +data/pub_valid_file.xml.i +data/pub_polish_file.xml.i diff --git a/lib/wlrepo/tests/data/repos/testrepoI/.hg/store/undo b/lib/wlrepo/tests/data/repos/testrepoI/.hg/store/undo new file mode 100644 index 0000000000000000000000000000000000000000..62ca7e43c419bfee7c1f6abc157924b8650a34d8 GIT binary patch literal 93 zcmYdEEJ@TaC{2nl$j`|v&WKOT%t_U&$j#BqWH8`Lfk~Dn=47TI%bA&Q85ray=4Ga( c7MB3k8kv~_1(Guo^U_mu^3#DL#%5+*00amglK=n! literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/testrepoI/.hg/undo.branch b/lib/wlrepo/tests/data/repos/testrepoI/.hg/undo.branch new file mode 100644 index 00000000..331d858c --- /dev/null +++ b/lib/wlrepo/tests/data/repos/testrepoI/.hg/undo.branch @@ -0,0 +1 @@ +default \ No newline at end of file diff --git a/lib/wlrepo/tests/data/repos/testrepoI/.hg/undo.dirstate b/lib/wlrepo/tests/data/repos/testrepoI/.hg/undo.dirstate new file mode 100644 index 0000000000000000000000000000000000000000..fb1041a549c5d0289f62fc04475b8dd4faed9138 GIT binary patch literal 166 zcmb1jTb{A&AIr?E;>@Mjj?cSw?dOV93|K%O14H8ykhs_8E;k@0R8X1}UzV7YnG&Ct ynUktlk(-08q!g%xQ!gVuGd(ZAC^ZqJ@jny*nZh8=1^GFd#Thtt^FXvhj0XS(AvNLv literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/testrepoI/.hgignore b/lib/wlrepo/tests/data/repos/testrepoI/.hgignore new file mode 100644 index 00000000..e69de29b diff --git a/lib/wlrepo/tests/data/repos/testrepoI/ignored_file b/lib/wlrepo/tests/data/repos/testrepoI/ignored_file new file mode 100644 index 00000000..e69de29b diff --git a/lib/wlrepo/tests/data/repos/testrepoI/pub_polish_file.xml b/lib/wlrepo/tests/data/repos/testrepoI/pub_polish_file.xml new file mode 100644 index 00000000..c7ada58c --- /dev/null +++ b/lib/wlrepo/tests/data/repos/testrepoI/pub_polish_file.xml @@ -0,0 +1 @@ +Gąska! diff --git a/lib/wlrepo/tests/data/repos/testrepoI/pub_valid_file.xml b/lib/wlrepo/tests/data/repos/testrepoI/pub_valid_file.xml new file mode 100644 index 00000000..84321884 --- /dev/null +++ b/lib/wlrepo/tests/data/repos/testrepoI/pub_valid_file.xml @@ -0,0 +1 @@ +Ala ma kota diff --git a/lib/wlrepo/tests/data/repos/testrepoII/.hg/00changelog.i b/lib/wlrepo/tests/data/repos/testrepoII/.hg/00changelog.i new file mode 100644 index 0000000000000000000000000000000000000000..d3a8311050e54c57c5be7cfe169e60a95768812c GIT binary patch literal 57 zcmWN_K?=Yi3!|qGE?Hy zGILV(DsppRN*JI@IQ25pGt=|(i&9}S9A2AO*aI~SgESZ9=VTUVVABm&!voO@F&+Tx CT`!gZ literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/testrepoII/.hg/requires b/lib/wlrepo/tests/data/repos/testrepoII/.hg/requires new file mode 100644 index 00000000..5175383b --- /dev/null +++ b/lib/wlrepo/tests/data/repos/testrepoII/.hg/requires @@ -0,0 +1,3 @@ +revlogv1 +store +fncache diff --git a/lib/wlrepo/tests/data/repos/testrepoII/.hg/store/00changelog.i b/lib/wlrepo/tests/data/repos/testrepoII/.hg/store/00changelog.i new file mode 100644 index 0000000000000000000000000000000000000000..f7ca408798d7ba9fc9bf89a4dce54b1bef739d89 GIT binary patch literal 947 zcmZQzWME`~fNUU@4`nm_hk~=S;zLg^v+$|qZP;?$crmy9%Z5^z8W3GENA{RC-(dwF zh6{I>pJ44eP?&Q=>!}Lgg#MNVsycgXm+pBvQQfmqH1bi?Id;E1{~d`7Vkf0PT(L>h z@#RnH`%7JQ(|5O5hJ9veKizXL>d;Ho4BZ)@cl6z=VvF#;X7%+?=6BPm|1<5GY7`fN ztpz!ffuR|QyTL35i1R_Nm33R5vFjhp%&X$erPq$nyLIj7ic?TEV5(w{>S;&5Lka?{ z7uM};h~B1`Bay(eE$-k}vxduUEn=6$9)Dz=`$V_y-~4sI?{3@}m((G+_}FG8<=$fs zhbnm$<_JAtl=0fIrceLsTBZprmWX;u*BJ$IOk1{e%@>JdQ#x(q6Dxkt`M2@^nVq)x zR|mQ*=Y=IN_wgctipkj{e2}8bS10IG0w(DQ8OC2psnzQ!)ixwsp!IQZf7gib9KaQUo zv1_iLyLyL?z~2su4W2A#;ubJ7_?r|=aX8{O{m-lXsNYM1W6i5y%`|70;81O7KfTrQ z`I$fOZtcv9TwbO#>+Sc2&ub@5dl>&LuK(^ohTksgdLZi=Q^1ax10?qWG04@-AR6Rq zlPjwlN|QIWm+aZc{%y_f8D2~7^aADJ0O;y-8@Ub{2sAuASKF2ID4-*AlA7P6XK$FN zWLK?hG||i~xNy|nJnCR`zJ*2Ix>fr&|7TchaVW!AJ5b~1DZZV{+KSagmriTG%Cx|^ z)Y4A;`lFJBMX6o}dLEYzy-rS0m~p%C;FeO;;y3Vow@FqM7Y42$!6!qUQ#Y@3eGs(-`#p}+{_AFyYDR51`Y05J;`GlTs0;P;L@ z_92H|8(VrK7l~fHq_pzIM4&tzfYQG=C{Zz7uwDLwHK${Ky1hqcyU$Sq#*4M1kxAg~BX)*!;fMSQt literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/testrepoII/.hg/store/00manifest.i b/lib/wlrepo/tests/data/repos/testrepoII/.hg/store/00manifest.i new file mode 100644 index 0000000000000000000000000000000000000000..997a181d7e9baa46f9dc848e4c5421907e3f8269 GIT binary patch literal 670 zcmZQzWME`~023f(3}rL?hXN1xn^|f#K@!t0{?*p>uWc(kRlNkJ21J+YWu#}O=j9ir zG9+0Tq@{0V2{o&YfH71=!?HFj)vBAAwm63`{_p5#*?s97-9I{z^erhG`zsf+EJ( zW(1o-)qtsrIj*N2xtI)j7!J(&ZaAszvPtFHNh#4fAu$53@=xrqPHwm4W8h(^sNdVS zJO6lT-|foR$=fb}HgYuVPSO(dY2{fu%cNLc>5I_L?5kI^qUwGo7QgwgJ?l)t*&8#J zr|exU_&q~W?oDRuMq8(8{1-XYCV*}I1twE~WIhlxLopM`!7E!{-9MZck(~Zy!V#wo zhA-=QPrLGn6+WD*P;%#K*02?S1MgRZ+ literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/testrepoII/.hg/store/data/pub__polish__file.xml.i b/lib/wlrepo/tests/data/repos/testrepoII/.hg/store/data/pub__polish__file.xml.i new file mode 100644 index 0000000000000000000000000000000000000000..3488bccb18f799c89d416b5fca591ba90e6ee85c GIT binary patch literal 73 zcmZQzWME`~08Svq0cA7&hk^+j6GYdfge+)Z@oKk=!`4GTE3FElYQR*f`;pe->_kN_ E0K(N3$^ZZW literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/testrepoII/.hg/store/data/pub__valid__file.xml.i b/lib/wlrepo/tests/data/repos/testrepoII/.hg/store/data/pub__valid__file.xml.i new file mode 100644 index 0000000000000000000000000000000000000000..fd3c7f7b76f7cc2c3d01256a69093bd8f5817e58 GIT binary patch literal 152 zcmZQzWME{#1dRWoUQPrLGn6+WD*P;%!XjU=ax*$pe*R0?{BNI;9pE m@u!`cwx7%G&ztUJ8_l}zoPer9r+6H55*2b26|(b761f1Y*(LG- literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/testrepoII/.hg/store/fncache b/lib/wlrepo/tests/data/repos/testrepoII/.hg/store/fncache new file mode 100644 index 00000000..8730267a --- /dev/null +++ b/lib/wlrepo/tests/data/repos/testrepoII/.hg/store/fncache @@ -0,0 +1,4 @@ +data/.hgignore.i +data/ignored_file.i +data/pub_valid_file.xml.i +data/pub_polish_file.xml.i diff --git a/lib/wlrepo/tests/data/repos/testrepoII/.hg/store/undo b/lib/wlrepo/tests/data/repos/testrepoII/.hg/store/undo new file mode 100644 index 0000000000000000000000000000000000000000..fb22969a85191a628adce30a6f24bf31fc6576f0 GIT binary patch literal 35 pcmXpo$W6@4OiL{;(aU5oGce;aFi6fw%u7$r$xjE0n44K}0RY1>3PS(@ literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/testrepoII/.hg/undo.branch b/lib/wlrepo/tests/data/repos/testrepoII/.hg/undo.branch new file mode 100644 index 00000000..620a92c9 --- /dev/null +++ b/lib/wlrepo/tests/data/repos/testrepoII/.hg/undo.branch @@ -0,0 +1 @@ +personal_tester_file_valid_file \ No newline at end of file diff --git a/lib/wlrepo/tests/data/repos/testrepoII/.hg/undo.dirstate b/lib/wlrepo/tests/data/repos/testrepoII/.hg/undo.dirstate new file mode 100644 index 0000000000000000000000000000000000000000..2c1df6a1ec8a436e730390e7d6582109d438162b GIT binary patch literal 101 zcmXrHvZ|ppc~g7Io_*}!*6g0)wd77O0~V0Sz|gn^D9+=xdCn^!EmTmN6knE@lbI5q bmYI{PSCN|oQ^EjM!l{>$o|&GPUz7>}RmL8T literal 0 HcmV?d00001 diff --git a/lib/wlrepo/tests/data/repos/testrepoII/.hgignore b/lib/wlrepo/tests/data/repos/testrepoII/.hgignore new file mode 100644 index 00000000..e69de29b diff --git a/lib/wlrepo/tests/data/repos/testrepoII/ignored_file b/lib/wlrepo/tests/data/repos/testrepoII/ignored_file new file mode 100644 index 00000000..e69de29b diff --git a/lib/wlrepo/tests/data/repos/testrepoII/pub_polish_file.xml b/lib/wlrepo/tests/data/repos/testrepoII/pub_polish_file.xml new file mode 100644 index 00000000..c7ada58c --- /dev/null +++ b/lib/wlrepo/tests/data/repos/testrepoII/pub_polish_file.xml @@ -0,0 +1 @@ +Gąska! diff --git a/lib/wlrepo/tests/data/repos/testrepoII/pub_valid_file.xml b/lib/wlrepo/tests/data/repos/testrepoII/pub_valid_file.xml new file mode 100644 index 00000000..84321884 --- /dev/null +++ b/lib/wlrepo/tests/data/repos/testrepoII/pub_valid_file.xml @@ -0,0 +1 @@ +Ala ma kota diff --git a/lib/wlrepo/tests/test_mercurial.py b/lib/wlrepo/tests/test_mercurial.py new file mode 100644 index 00000000..a4e1cfb4 --- /dev/null +++ b/lib/wlrepo/tests/test_mercurial.py @@ -0,0 +1,99 @@ +# -*- encoding: utf-8 -*- + +__author__= "Łukasz Rekucki" +__date__ = "$2009-09-18 14:43:27$" +__doc__ = "Tests for RAL mercurial backend." + +from nose.tools import * + +import wlrepo +from wlrepo import MercurialLibrary +from wlrepo.backend_mercurial import * + +import os, os.path, tempfile +import shutil + +REPO_TEMPLATES = os.path.join( os.path.dirname(__file__), 'data/repos') +ROOT_PATH = None + +class testBasicLibrary(object): + + def setUp(self): + self.path = tempfile.mkdtemp("", "testdir_" ) + print self.path + for subdir in os.listdir(REPO_TEMPLATES): + shutil.copytree(REPO_TEMPLATES + '/' + subdir, self.path + '/' + subdir, False) + + def tearDown(self): + if self.path is not None: + shutil.rmtree(self.path, True) + pass + + def testOpening(self): + library = MercurialLibrary(self.path + '/cleanrepo') + + def testMainCabinet(self): + library = MercurialLibrary(self.path + '/cleanrepo') + + mcab = library.main_cabinet + assert_equal(mcab.maindoc_name(), '') + + # @type mcab MercurialCabinet + doclist = mcab.documents() + assert_equal( list(doclist), ['valid_file']) + + + def testReadDocument(self): + library = MercurialLibrary(self.path + '/testrepoI') + doc = library.main_cabinet.retrieve('valid_file') + + assert_equal(doc.read().strip(), 'Ala ma kota') + + def testReadUTF8Document(self): + library = MercurialLibrary(self.path + '/testrepoI') + doc = library.main_cabinet.retrieve('polish_file') + + assert_equal(doc.read().strip(), u'Gąska!'.encode('utf-8')) + + def testWriteDocument(self): + library = MercurialLibrary(self.path + '/testrepoI') + doc = library.main_cabinet.retrieve('valid_file') + + assert_equal(doc.read().strip(), 'Ala ma kota') + + STRING = u'Gąski lubią pływać!\n'.encode('utf-8') + doc.write(STRING) + + assert_equal(doc.read(), STRING) + + def testCreateDocument(self): + repopath = os.path.join(self.path, 'testrepoI') + + library = MercurialLibrary(repopath) + doc = library.main_cabinet.create("another_file") + doc.write("Some text") + assert_equal( doc.read(), "Some text") + assert_true( os.path.isfile( os.path.join(repopath, "pub_another_file.xml")) ) + + def testSwitchBranch(self): + library = MercurialLibrary(self.path + '/testrepoII') + + tester_cab = library.cabinet("valid_file", "tester", create=False) + assert_equal( list(tester_cab.documents()), ['valid_file']) + + @raises(wlrepo.CabinetNotFound) + def testNoBranch(self): + library = MercurialLibrary(self.path + '/testrepoII') + tester_cab = library.cabinet("ugh", "tester", create=False) + + + def testCreateBranch(self): + repopath = os.path.join(self.path, 'testrepoII') + library = MercurialLibrary(repopath) + + tester_cab = library.cabinet("anotherone", "tester", create=True) + assert_equal( list(tester_cab.documents()), ['anotherone']) + + + + \ No newline at end of file -- 2.20.1