diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2011-05-30 13:06:37 +0200 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2011-05-30 13:06:37 +0200 |
commit | 024adf37acddd6a5d8293b6b5d15795c59a142c0 (patch) | |
tree | 3610b99168f984acb0eefe3a995295f4d3b1d096 | |
parent | 112bb1672d6b28f203e7839e320b985486636800 (diff) | |
download | gitpython-024adf37acddd6a5d8293b6b5d15795c59a142c0.tar.gz |
Fixed tests far enough to allow basic repository tests to be applied to any of the new database types. This reduces code duplication to the mere minimum, but allows custom tests to be added on top easily and flexibly
-rw-r--r-- | doc/source/changes.rst | 4 | ||||
-rw-r--r-- | git/db/cmd/__init__.py | 6 | ||||
-rw-r--r-- | git/db/cmd/base.py | 2 | ||||
-rw-r--r-- | git/db/cmd/complex.py | 20 | ||||
-rw-r--r-- | git/db/compat.py | 2 | ||||
-rw-r--r-- | git/db/complex.py | 8 | ||||
-rw-r--r-- | git/db/py/__init__.py | 2 | ||||
-rw-r--r-- | git/db/py/complex.py | 4 | ||||
-rw-r--r-- | git/db/py/resolve.py | 13 | ||||
-rw-r--r-- | git/exc.py | 15 | ||||
-rw-r--r-- | git/index/base.py | 5 | ||||
-rw-r--r-- | git/repo.py | 2 | ||||
-rw-r--r-- | git/test/db/base.py (renamed from git/test/test_repo.py) | 26 | ||||
-rw-r--r-- | git/test/db/cmd/__init__.py | 4 | ||||
-rw-r--r-- | git/test/db/cmd/test_base.py | 13 | ||||
-rw-r--r-- | git/test/db/lib.py | 7 | ||||
-rw-r--r-- | git/test/db/py/__init__.py | 4 | ||||
-rw-r--r-- | git/test/db/py/test_base.py | 18 | ||||
-rw-r--r-- | git/test/lib/base.py | 20 | ||||
-rw-r--r-- | git/test/lib/helper.py | 40 | ||||
-rw-r--r-- | git/test/test_git.py | 2 |
21 files changed, 152 insertions, 65 deletions
diff --git a/doc/source/changes.rst b/doc/source/changes.rst index d7fd02ff..131e0a5b 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -21,6 +21,10 @@ NEXT * ### Module Changes ### * Removed rev_parse function from git.repo.fun - the respective functionality is available only through the repository's rev_parse method, which might in turn translate to any implementation. + +* ### Exceptions ### + + * There is a new common base for all exceptions git-python will throw, namely `GitPythonError`. 0.3.1 Beta 2 ============ diff --git a/git/db/cmd/__init__.py b/git/db/cmd/__init__.py index 968d8c11..8a681e42 100644 --- a/git/db/cmd/__init__.py +++ b/git/db/cmd/__init__.py @@ -1,2 +1,4 @@ - -from complex import * +# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors +# +# This module is part of GitDB and is released under +# the New BSD License: http://www.opensource.org/licenses/bsd-license.php diff --git a/git/db/cmd/base.py b/git/db/cmd/base.py index 0025e9b0..6a2473a3 100644 --- a/git/db/cmd/base.py +++ b/git/db/cmd/base.py @@ -15,7 +15,7 @@ from git.util import ( bin_to_hex, hex_to_bin ) -from git.db.compat import RepoCompatInterface +from git.db.compat import RepoCompatibilityInterface from git.util import RemoteProgress from git.db.interface import FetchInfo as GitdbFetchInfo from git.db.interface import PushInfo as GitdbPushInfo diff --git a/git/db/cmd/complex.py b/git/db/cmd/complex.py index 9c26a8fa..3e6804f5 100644 --- a/git/db/cmd/complex.py +++ b/git/db/cmd/complex.py @@ -1,17 +1,27 @@ """Module with our own git implementation - it uses the git command""" -from git.db.compat import RepoCompatInterface +from git.db.compat import RepoCompatibilityInterface from git.db.py.complex import PureGitDB from base import * -__all__ = ['GitCmdDB', 'CmdCompatibilityGitDB'] +__all__ = ['GitCmdDB', 'CmdCompatibilityGitDB', 'CmdPartialGitDB'] -class CmdGitDB( GitCommandMixin, CmdObjectDBRMixin, CmdTransportMixin, - CmdHighLevelRepository, PureGitDB): +class CmdPartialGitDB( GitCommandMixin, CmdObjectDBRMixin, CmdTransportMixin, + CmdHighLevelRepository ): + """Utility repository which only partially implements all required methods. + It cannot be reliably used alone, but is provided to allow mixing it with other + implementations""" pass -class CmdCompatibilityGitDB(CmdGitDB, RepoCompatInterface): + +class CmdGitDB(CmdPartialGitDB, PureGitDB): + """A database which fills in its missing implementation using the pure python + implementation""" + pass + + +class CmdCompatibilityGitDB(CmdGitDB, RepoCompatibilityInterface): """Command git database with the compatabilty interface added for 0.3x code""" diff --git a/git/db/compat.py b/git/db/compat.py index b0c042a5..767ab5e0 100644 --- a/git/db/compat.py +++ b/git/db/compat.py @@ -4,7 +4,7 @@ # the New BSD License: http://www.opensource.org/licenses/bsd-license.php """Module providing adaptors to maintain backwards compatability""" -class RepoCompatInterface(object): +class RepoCompatibilityInterface(object): """Interface to install backwards compatability of the new complex repository types with the previous, all in one, repository.""" diff --git a/git/db/complex.py b/git/db/complex.py index dc85a595..ef2013e3 100644 --- a/git/db/complex.py +++ b/git/db/complex.py @@ -1,12 +1,12 @@ """Module with many useful complex databases with different useful combinations of primary implementations""" from py.complex import PureGitDB -from cmd.complex import CmdGitDB -from compat import RepoCompatInterface +from cmd.complex import CmdPartialGitDB +from compat import RepoCompatibilityInterface -__all__ = ['CmdGitDB', 'PureGitDB', 'PureCmdGitDB'] +__all__ = ['CmdPartialGitDB', 'PureGitDB', 'PureCmdGitDB'] -class PureCmdGitDB(PureGitDB, CmdGitDB, RepoCompatInterface): +class PureCmdGitDB(PureGitDB, CmdPartialGitDB, RepoCompatibilityInterface): """Repository which uses the pure implementation primarily, but falls back to the git command implementation. Please note that the CmdGitDB does it the opposite way around.""" diff --git a/git/db/py/__init__.py b/git/db/py/__init__.py index 73cc2bdf..8a681e42 100644 --- a/git/db/py/__init__.py +++ b/git/db/py/__init__.py @@ -2,5 +2,3 @@ # # This module is part of GitDB and is released under # the New BSD License: http://www.opensource.org/licenses/bsd-license.php - -from complex import * diff --git a/git/db/py/complex.py b/git/db/py/complex.py index efcbb2ba..9d891537 100644 --- a/git/db/py/complex.py +++ b/git/db/py/complex.py @@ -20,7 +20,7 @@ from pack import PurePackedODB from ref import PureReferenceDB from submodule import PureSubmoduleDB -from git.db.compat import RepoCompatInterface +from git.db.compat import RepoCompatibilityInterface from git.util import ( LazyMixin, @@ -123,6 +123,6 @@ class PureGitDB(PureGitODB, -class PureCompatibilityGitDB(PureGitDB, RepoCompatInterface): +class PureCompatibilityGitDB(PureGitDB, RepoCompatibilityInterface): """Pure git database with a compatability layer required by 0.3x code""" diff --git a/git/db/py/resolve.py b/git/db/py/resolve.py index d0685747..7194149c 100644 --- a/git/db/py/resolve.py +++ b/git/db/py/resolve.py @@ -3,12 +3,19 @@ version assuming compatible interface for reference and object types""" from git.db.interface import ReferencesMixin from git.exc import BadObject -from git.refs import SymbolicReference -from git.objects.base import Object -from git.objects.commit import Commit +from git.refs import ( + SymbolicReference, + Reference, + HEAD, + Head, + TagReference + ) from git.refs.head import HEAD from git.refs.headref import Head from git.refs.tag import TagReference + +from git.objects.base import Object +from git.objects.commit import Commit from git.util import ( join, isdir, @@ -7,7 +7,10 @@ from util import to_hex_sha -class ODBError(Exception): +class GitPythonError(Exception): + """Base exception for all git-python related errors""" + +class ODBError(GitPythonError): """All errors thrown by the object database""" @@ -40,15 +43,15 @@ class UnsupportedOperation(ODBError): """Thrown if the given operation cannot be supported by the object database""" -class InvalidGitRepositoryError(Exception): +class InvalidGitRepositoryError(GitPythonError): """ Thrown if the given repository appears to have an invalid format. """ -class NoSuchPathError(OSError): +class NoSuchPathError(GitPythonError): """ Thrown if a path could not be access by the system. """ -class GitCommandError(Exception): +class GitCommandError(GitPythonError): """ Thrown if execution of the git command fails with non-zero status code. """ def __init__(self, command, status, stderr=None): self.stderr = stderr @@ -60,7 +63,7 @@ class GitCommandError(Exception): (' '.join(str(i) for i in self.command), self.status, self.stderr)) -class CheckoutError( Exception ): +class CheckoutError(GitPythonError): """Thrown if a file could not be checked out from the index as it contained changes. @@ -83,7 +86,7 @@ class CheckoutError( Exception ): return Exception.__str__(self) + ":%s" % self.failed_files -class CacheError(Exception): +class CacheError(GitPythonError): """Base for all errors related to the git index, which is called cache internally""" diff --git a/git/index/base.py b/git/index/base.py index 75bfc6fe..e7002b29 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -63,7 +63,6 @@ from fun import ( ) from git.base import IStream -from git.db.py.mem import PureMemoryDB from git.util import to_bin_sha from itertools import izip @@ -512,7 +511,9 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable): :raise UnmergedEntriesError: """ # we obtain no lock as we just flush our contents to disk as tree # If we are a new index, the entries access will load our data accordingly - mdb = PureMemoryDB() + # Needs delayed import as db.py import IndexFile as well + import git.db.py.mem + mdb = git.db.py.mem.PureMemoryDB() entries = self._entries_sorted() binsha, tree_items = write_tree_from_cache(entries, mdb, slice(0, len(entries))) diff --git a/git/repo.py b/git/repo.py index 178947c8..8973dbd2 100644 --- a/git/repo.py +++ b/git/repo.py @@ -5,7 +5,7 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php """This module is just to maintain compatibility to git-python 0.3x""" -from git.db.cmd import CmdCompatibilityGitDB +from git.db.cmd.complex import CmdCompatibilityGitDB import warnings diff --git a/git/test/test_repo.py b/git/test/db/base.py index 8677d10d..470565b9 100644 --- a/git/test/test_repo.py +++ b/git/test/db/base.py @@ -3,7 +3,8 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from git.test.lib import TestBase +from lib import TestDBBase +from git.test.lib import * from git import * from git.util import join_path_native from git.exc import BadObject @@ -15,18 +16,22 @@ import shutil from cStringIO import StringIO -class TestRepo(TestBase): +class RepoGlobalsItemDeletorMetaCls(GlobalsItemDeletorMetaCls): + ModuleToDelete = 'RepoBase' + + +class RepoBase(TestDBBase): + """Basic test for everything a fully implemented repository should support""" + __metaclass__ = RepoGlobalsItemDeletorMetaCls - @raises(InvalidGitRepositoryError) def test_new_should_raise_on_invalid_repo_location(self): - Repo(tempfile.gettempdir()) + self.failUnlessRaises(InvalidGitRepositoryError, self.RepoCls, tempfile.gettempdir()) - @raises(NoSuchPathError) def test_new_should_raise_on_non_existant_path(self): - Repo("repos/foobar") + self.failUnlessRaises(NoSuchPathError, self.RepoCls, "repos/foobar") def test_repo_creation_from_different_paths(self): - r_from_gitdir = Repo(self.rorepo.git_dir) + r_from_gitdir = self.RepoCls(self.rorepo.git_dir) assert r_from_gitdir.git_dir == self.rorepo.git_dir assert r_from_gitdir.git_dir.endswith('.git') assert not self.rorepo.git.working_dir.endswith('.git') @@ -184,7 +189,10 @@ class TestRepo(TestBase): # END restore previous state def test_bare_property(self): - self.rorepo.bare + if isinstance(self.rorepo, RepoCompatibilityInterface): + self.rorepo.bare + #END handle compatability + self.rorepo.is_bare def test_daemon_export(self): orig_val = self.rorepo.daemon_export @@ -204,7 +212,7 @@ class TestRepo(TestBase): self.rorepo.alternates = cur_alternates def test_repr(self): - path = os.path.join(os.path.abspath(GIT_REPO), '.git') + path = os.path.join(os.path.abspath(rorepo_dir()), '.git') assert_equal('<git.Repo "%s">' % path, repr(self.rorepo)) def test_is_dirty_with_bare_repository(self): diff --git a/git/test/db/cmd/__init__.py b/git/test/db/cmd/__init__.py new file mode 100644 index 00000000..8a681e42 --- /dev/null +++ b/git/test/db/cmd/__init__.py @@ -0,0 +1,4 @@ +# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors +# +# This module is part of GitDB and is released under +# the New BSD License: http://www.opensource.org/licenses/bsd-license.php diff --git a/git/test/db/cmd/test_base.py b/git/test/db/cmd/test_base.py new file mode 100644 index 00000000..1404eca0 --- /dev/null +++ b/git/test/db/cmd/test_base.py @@ -0,0 +1,13 @@ +# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors +# +# This module is part of GitDB and is released under +# the New BSD License: http://www.opensource.org/licenses/bsd-license.php +from git.test.lib import * +from git.db import RefSpec + +class TestBase(TestDBBase): + + @with_rw_directory + def test_basics(self, path): + assert False + diff --git a/git/test/db/lib.py b/git/test/db/lib.py index bd230eda..5aebcd5c 100644 --- a/git/test/db/lib.py +++ b/git/test/db/lib.py @@ -12,11 +12,6 @@ from git.test.lib import ( ) from git.stream import Sha1Writer - -# import database types we want to support -# they will be set to None if the respective library could not be loaded -from git.db.py import PureGitDB - from git.base import ( IStream, OStream, @@ -40,8 +35,6 @@ class TestDBBase(TestBase): two_lines = "1234\nhello world" all_data = (two_lines, ) - # all supported database types. Add your own type - ref_db_types = (PureGitDB, ) def _assert_object_writing_simple(self, db): # write a bunch of objects and query their streams and info diff --git a/git/test/db/py/__init__.py b/git/test/db/py/__init__.py new file mode 100644 index 00000000..8a681e42 --- /dev/null +++ b/git/test/db/py/__init__.py @@ -0,0 +1,4 @@ +# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors +# +# This module is part of GitDB and is released under +# the New BSD License: http://www.opensource.org/licenses/bsd-license.php diff --git a/git/test/db/py/test_base.py b/git/test/db/py/test_base.py new file mode 100644 index 00000000..84899651 --- /dev/null +++ b/git/test/db/py/test_base.py @@ -0,0 +1,18 @@ +# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors +# +# This module is part of GitDB and is released under +# the New BSD License: http://www.opensource.org/licenses/bsd-license.php +from git.test.lib import * +from git.test.db.base import RepoBase +from git.db.py.complex import * + +from git.db.complex import PureCmdGitDB + +class TestPyDBBase(RepoBase): + + RepoCls = PureCmdGitDB + + def test_instantiation(self): + db = PureGitDB(rorepo_dir()) + cdb = PureCompatibilityGitDB(rorepo_dir()) + diff --git a/git/test/lib/base.py b/git/test/lib/base.py index 3725d544..221395c9 100644 --- a/git/test/lib/base.py +++ b/git/test/lib/base.py @@ -1,10 +1,9 @@ # Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors # -# This module is part of PureGitDB and is released under +# This module is part of PureCmdGitDB and is released under # the New BSD License: http://www.opensource.org/licenses/bsd-license.php """Utilities used in ODB testing""" from git.base import OStream -from git.db.py import PureGitDB from git.stream import ( Sha1Writer, ZippedStoreShaWriter @@ -73,7 +72,7 @@ def with_rw_repo(func): shutil.copytree(src_dir, path) target_gitdir = os.path.join(path, '.git') assert os.path.isdir(target_gitdir) - return func(self, PureGitDB(target_gitdir)) + return func(self, self.RepoCls(target_gitdir)) #END wrapper wrapper.__name__ = func.__name__ return with_rw_directory(wrapper) @@ -98,7 +97,7 @@ def with_packs_rw(func): #{ Routines -def repo_dir(): +def rorepo_dir(): """:return: path to our own repository, being our own .git directory. :note: doesn't work in bare repositories""" base = os.path.join(dirname(dirname(dirname(dirname(__file__)))), '.git') @@ -106,9 +105,9 @@ def repo_dir(): return base -def maketemp(*args): +def maketemp(*args, **kwargs): """Wrapper around default tempfile.mktemp to fix an osx issue""" - tdir = tempfile.mktemp(*args) + tdir = tempfile.mktemp(*args, **kwargs) if sys.platform == 'darwin': tdir = '/private' + tdir return tdir @@ -192,12 +191,3 @@ class DeriveTest(OStream): #} END stream utilitiess -#{ Bases - -class TestBase(unittest.TestCase): - """Base class for all tests""" - # The non-database specific tests just provides a default pure git database - rorepo = PureGitDB(repo_dir()) - -#} END bases - diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 48d684e0..4fd82899 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -12,13 +12,16 @@ import tempfile import shutil import cStringIO -from base import maketemp +from base import ( + maketemp, + rorepo_dir + ) -GIT_REPO = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) __all__ = ( 'fixture_path', 'fixture', 'absolute_project_path', 'StringProcessAdapter', - 'with_rw_repo', 'with_rw_and_rw_remote_repo', 'TestBase', 'TestCase', 'GIT_REPO' + 'with_rw_repo', 'with_rw_and_rw_remote_repo', 'TestBase', 'TestCase', + 'GlobalsItemDeletorMetaCls' ) #{ Routines @@ -200,6 +203,26 @@ def with_rw_and_rw_remote_repo(working_tree_ref): return argument_passer #} END decorators + +#{ Meta Classes +class GlobalsItemDeletorMetaCls(type): + """Utiltiy to prevent the RepoBase to be picked up by nose as the metacls + will delete the instance from the globals""" + #{ Configuration + # Set this to a string name of the module to delete + ModuleToDelete = None + #} END configuration + + def __new__(metacls, name, bases, clsdict): + assert metacls.ModuleToDelete is not None, "Invalid metaclass configuration" + new_type = super(GlobalsItemDeletorMetaCls, metacls).__new__(metacls, name, bases, clsdict) + if name != metacls.ModuleToDelete: + mod = __import__(new_type.__module__, globals(), locals(), new_type.__module__) + delattr(mod, metacls.ModuleToDelete) + #END handle deletion + return new_type + +#} END meta classes class TestBase(TestCase): """ @@ -217,7 +240,15 @@ class TestBase(TestCase): The rorepo is in fact your current project's git repo. If you refer to specific shas for your objects, be sure you choose some that are part of the immutable portion of the project history ( to assure tests don't fail for others ). + + Derived types can override the default repository type to create a differnt + read-only repo, allowing to test their specific type """ + #{ Configuration + # The repository type to instantiate. It takes at least a path to operate upon + # during instantiation. + RepoCls = None + #} END configuration @classmethod def setUpAll(cls): @@ -225,7 +256,8 @@ class TestBase(TestCase): Dynamically add a read-only repository to our actual type. This way each test type has its own repository """ - cls.rorepo = Repo(GIT_REPO) + assert cls.RepoCls is not None, "RepoCls class member must be set" + cls.rorepo = cls.RepoCls(rorepo_dir()) def _make_file(self, rela_path, data, repo=None): """ diff --git a/git/test/test_git.py b/git/test/test_git.py index 7d8ff371..1f5ec6dd 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -12,7 +12,7 @@ class TestGit(TestCase): @classmethod def setUpAll(cls): - cls.git = Git(GIT_REPO) + cls.git = Git(cls.rorepo.working_dir) @patch_object(Git, 'execute') def test_call_process_calls_execute(self, git): |