summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2009-10-22 16:20:35 +0200
committerSebastian Thiel <byronimo@gmail.com>2009-10-22 16:20:35 +0200
commit3c658c16f3437ed7e78f6072b6996cb423a8f504 (patch)
tree4dcb21b565410c48878be31deebbb441201d542b /test
parent59e26435a8d2008073fc315bafe9f329d0ef689a (diff)
parentb197b2dbb527de9856e6e808339ab0ceaf0a512d (diff)
downloadgitpython-3c658c16f3437ed7e78f6072b6996cb423a8f504.tar.gz
Merge branch 'testsystem' into improvements
* testsystem: Adjusted all remaining test suites to use the new TestBase class where appropriate Fixed decorator issue that would cause a function to be passed even though there is a default argument. This feels inconsistent as the 'argument passer' wrapper function can be called with a function or a string as first argument depending on whether the client code was explicitly passing an argument or not. That ... sucks. Now test for that case specifically and fail with a proper assertion error. I don't like it, but what can I do ... . Implemented decorators, tests pass at least Added frame for new Repo handling and some neat decorators, including tests that test whether the testing framework does what it should
Diffstat (limited to 'test')
-rw-r--r--test/git/test_base.py29
-rw-r--r--test/git/test_blob.py12
-rw-r--r--test/git/test_commit.py28
-rw-r--r--test/git/test_config.py4
-rw-r--r--test/git/test_diff.py14
-rw-r--r--test/git/test_git.py8
-rw-r--r--test/git/test_head.py8
-rw-r--r--test/git/test_index.py18
-rw-r--r--test/git/test_performance.py6
-rw-r--r--test/git/test_remote.py27
-rw-r--r--test/git/test_repo.py88
-rw-r--r--test/git/test_stats.py6
-rw-r--r--test/git/test_tag.py8
-rw-r--r--test/testlib/__init__.py1
-rw-r--r--test/testlib/helper.py118
15 files changed, 240 insertions, 135 deletions
diff --git a/test/git/test_base.py b/test/git/test_base.py
index b93e61c1..a7ef9374 100644
--- a/test/git/test_base.py
+++ b/test/git/test_base.py
@@ -14,16 +14,13 @@ from itertools import chain
from git.objects.utils import get_object_type_by_name
import tempfile
-class TestBase(object):
+class TestBase(TestBase):
type_tuples = ( ("blob", "8741fc1d09d61f02ffd8cded15ff603eff1ec070"),
("tree", "3a6a5e3eeed3723c09f1ef0399f81ed6b8d82e79"),
("commit", "4251bd59fb8e11e40c40548cba38180a9536118c"),
("tag", "e56a60e8e9cd333cfba0140a77cd12b0d9398f10") )
- def setup(self):
- self.repo = Repo(GIT_REPO)
-
def test_base_object(self):
# test interface of base object classes
types = (Blob, Tree, Commit, TagObject)
@@ -33,7 +30,7 @@ class TestBase(object):
num_objs = 0
num_index_objs = 0
for obj_type, (typename, hexsha) in zip(types, self.type_tuples):
- item = obj_type(self.repo,hexsha)
+ item = obj_type(self.rorepo,hexsha)
num_objs += 1
assert item.id == hexsha
assert item.type == typename
@@ -74,7 +71,7 @@ class TestBase(object):
# tag refs can point to tag objects or to commits
s = set()
ref_count = 0
- for ref in chain(self.repo.tags, self.repo.heads):
+ for ref in chain(self.rorepo.tags, self.rorepo.heads):
ref_count += 1
assert isinstance(ref, refs.Reference)
assert str(ref) == ref.name
@@ -88,7 +85,7 @@ class TestBase(object):
def test_heads(self):
# see how it dynmically updates its object
- for head in self.repo.heads:
+ for head in self.rorepo.heads:
head.name
head.path
prev_object = head.object
@@ -106,4 +103,20 @@ class TestBase(object):
def test_object_resolution(self):
# objects must be resolved to shas so they compare equal
- assert self.repo.head.object == self.repo.active_branch.object
+ assert self.rorepo.head.object == self.rorepo.active_branch.object
+
+ @with_bare_rw_repo
+ def test_with_bare_rw_repo(self, bare_rw_repo):
+ assert bare_rw_repo.config_reader("repository").getboolean("core", "bare")
+ assert os.path.isfile(os.path.join(bare_rw_repo.path,'HEAD'))
+
+ @with_rw_repo('0.1.6')
+ def test_with_rw_repo(self, rw_repo):
+ assert not rw_repo.config_reader("repository").getboolean("core", "bare")
+ assert os.path.isdir(os.path.join(rw_repo.git.git_dir,'lib'))
+
+ @with_rw_and_rw_remote_repo('0.1.6')
+ def test_with_rw_remote_and_rw_repo(self, rw_repo, rw_remote_repo):
+ assert not rw_repo.config_reader("repository").getboolean("core", "bare")
+ assert rw_remote_repo.config_reader("repository").getboolean("core", "bare")
+ assert os.path.isdir(os.path.join(rw_repo.git.git_dir,'lib'))
diff --git a/test/git/test_blob.py b/test/git/test_blob.py
index e151b3c8..1b3b68f8 100644
--- a/test/git/test_blob.py
+++ b/test/git/test_blob.py
@@ -7,26 +7,24 @@
from test.testlib import *
from git import *
-class TestBlob(object):
- def setup(self):
- self.repo = Repo(GIT_REPO)
+class TestBlob(TestBase):
def test_should_cache_data(self):
bid = 'a802c139d4767c89dcad79d836d05f7004d39aac'
- blob = Blob(self.repo, bid)
+ blob = Blob(self.rorepo, bid)
blob.data
assert blob.data
blob.size
blob.size
def test_mime_type_should_return_mime_type_for_known_types(self):
- blob = Blob(self.repo, **{'id': 'abc', 'path': 'foo.png'})
+ blob = Blob(self.rorepo, **{'id': 'abc', 'path': 'foo.png'})
assert_equal("image/png", blob.mime_type)
def test_mime_type_should_return_text_plain_for_unknown_types(self):
- blob = Blob(self.repo, **{'id': 'abc','path': 'something'})
+ blob = Blob(self.rorepo, **{'id': 'abc','path': 'something'})
assert_equal("text/plain", blob.mime_type)
def test_should_return_appropriate_representation(self):
- blob = Blob(self.repo, **{'id': 'abc'})
+ blob = Blob(self.rorepo, **{'id': 'abc'})
assert_equal('<git.Blob "abc">', repr(blob))
diff --git a/test/git/test_commit.py b/test/git/test_commit.py
index 3d7feb6d..1a74593d 100644
--- a/test/git/test_commit.py
+++ b/test/git/test_commit.py
@@ -7,13 +7,11 @@
from test.testlib import *
from git import *
-class TestCommit(object):
- def setup(self):
- self.repo = Repo(GIT_REPO)
+class TestCommit(TestBase):
def test_bake(self):
- commit = Commit(self.repo, **{'id': '2454ae89983a4496a445ce347d7a41c0bb0ea7ae'})
+ commit = Commit(self.rorepo, **{'id': '2454ae89983a4496a445ce347d7a41c0bb0ea7ae'})
commit.author # bake
assert_equal("Sebastian Thiel", commit.author.name)
@@ -21,7 +19,7 @@ class TestCommit(object):
def test_stats(self):
- commit = Commit(self.repo, id='33ebe7acec14b25c5f84f35a664803fcab2f7781')
+ commit = Commit(self.rorepo, id='33ebe7acec14b25c5f84f35a664803fcab2f7781')
stats = commit.stats
def check_entries(d):
@@ -48,13 +46,13 @@ class TestCommit(object):
git.return_value = fixture('rev_list_bisect_all')
- revs = self.repo.git.rev_list('HEAD',
+ revs = self.rorepo.git.rev_list('HEAD',
pretty='raw',
first_parent=True,
bisect_all=True)
assert_true(git.called)
- commits = Commit._iter_from_process_or_stream(self.repo, ListProcessAdapter(revs))
+ commits = Commit._iter_from_process_or_stream(self.rorepo, ListProcessAdapter(revs))
expected_ids = (
'cf37099ea8d1d8c7fbf9b6d12d7ec0249d3acb8b',
'33ebe7acec14b25c5f84f35a664803fcab2f7781',
@@ -66,29 +64,29 @@ class TestCommit(object):
assert_equal(sha1, commit.id)
def test_count(self):
- assert self.repo.tag('0.1.5').commit.count( ) == 141
+ assert self.rorepo.tag('0.1.5').commit.count( ) == 141
def test_list(self):
- assert isinstance(Commit.list_items(self.repo, '0.1.5', max_count=5)['5117c9c8a4d3af19a9958677e45cda9269de1541'], Commit)
+ assert isinstance(Commit.list_items(self.rorepo, '0.1.5', max_count=5)['5117c9c8a4d3af19a9958677e45cda9269de1541'], Commit)
def test_str(self):
- commit = Commit(self.repo, id='abc')
+ commit = Commit(self.rorepo, id='abc')
assert_equal ("abc", str(commit))
def test_repr(self):
- commit = Commit(self.repo, id='abc')
+ commit = Commit(self.rorepo, id='abc')
assert_equal('<git.Commit "abc">', repr(commit))
def test_equality(self):
- commit1 = Commit(self.repo, id='abc')
- commit2 = Commit(self.repo, id='abc')
- commit3 = Commit(self.repo, id='zyx')
+ commit1 = Commit(self.rorepo, id='abc')
+ commit2 = Commit(self.rorepo, id='abc')
+ commit3 = Commit(self.rorepo, id='zyx')
assert_equal(commit1, commit2)
assert_not_equal(commit2, commit3)
def test_iter_parents(self):
# should return all but ourselves, even if skip is defined
- c = self.repo.commit('0.1.5')
+ c = self.rorepo.commit('0.1.5')
for skip in (0, 1):
piter = c.iter_parents(skip=skip)
first_parent = piter.next()
diff --git a/test/git/test_config.py b/test/git/test_config.py
index 843da723..c2909b8f 100644
--- a/test/git/test_config.py
+++ b/test/git/test_config.py
@@ -11,10 +11,6 @@ from copy import copy
class TestBase(TestCase):
- @classmethod
- def setUpAll(cls):
- cls.repo = Repo(GIT_REPO)
-
def _to_memcache(self, file_path):
fp = open(file_path, "r")
sio = StringIO.StringIO()
diff --git a/test/git/test_diff.py b/test/git/test_diff.py
index 501d937d..d7505987 100644
--- a/test/git/test_diff.py
+++ b/test/git/test_diff.py
@@ -7,19 +7,17 @@
from test.testlib import *
from git import *
-class TestDiff(TestCase):
- def setUp(self):
- self.repo = Repo(GIT_REPO)
-
+class TestDiff(TestBase):
+
def test_list_from_string_new_mode(self):
output = ListProcessAdapter(fixture('diff_new_mode'))
- diffs = Diff._index_from_patch_format(self.repo, output.stdout)
+ diffs = Diff._index_from_patch_format(self.rorepo, output.stdout)
assert_equal(1, len(diffs))
assert_equal(10, len(diffs[0].diff.splitlines()))
def test_diff_with_rename(self):
output = ListProcessAdapter(fixture('diff_rename'))
- diffs = Diff._index_from_patch_format(self.repo, output.stdout)
+ diffs = Diff._index_from_patch_format(self.rorepo, output.stdout)
assert_equal(1, len(diffs))
@@ -37,13 +35,13 @@ class TestDiff(TestCase):
for fixture_name in fixtures:
diff_proc = ListProcessAdapter(fixture(fixture_name))
- diffs = Diff._index_from_patch_format(self.repo, diff_proc.stdout)
+ diffs = Diff._index_from_patch_format(self.rorepo, diff_proc.stdout)
# END for each fixture
def test_diff_interface(self):
# test a few variations of the main diff routine
assertion_map = dict()
- for i, commit in enumerate(self.repo.iter_commits('0.1.6', max_count=10)):
+ for i, commit in enumerate(self.rorepo.iter_commits('0.1.6', max_count=10)):
diff_item = commit
if i%2 == 0:
diff_item = commit.tree
diff --git a/test/git/test_git.py b/test/git/test_git.py
index 1f44aebc..c4a39e85 100644
--- a/test/git/test_git.py
+++ b/test/git/test_git.py
@@ -8,9 +8,11 @@ import os, sys
from test.testlib import *
from git import Git, GitCommandError
-class TestGit(object):
- def setup(self):
- self.git = Git(GIT_REPO)
+class TestGit(TestCase):
+
+ @classmethod
+ def setUpAll(cls):
+ cls.git = Git(GIT_REPO)
@patch_object(Git, 'execute')
def test_call_process_calls_execute(self, git):
diff --git a/test/git/test_head.py b/test/git/test_head.py
index b8380838..9b18ad7c 100644
--- a/test/git/test_head.py
+++ b/test/git/test_head.py
@@ -7,12 +7,10 @@
from test.testlib import *
from git import *
-class TestHead(object):
- def setup(self):
- self.repo = Repo(GIT_REPO)
+class TestHead(TestBase):
def test_base(self):
- for head in self.repo.heads:
+ for head in self.rorepo.heads:
assert head.name
assert "refs/heads" in head.path
# END for each head
@@ -20,7 +18,7 @@ class TestHead(object):
@patch_object(Git, '_call_process')
def test_ref_with_path_component(self, git):
git.return_value = fixture('for_each_ref_with_path_component')
- head = self.repo.heads[0]
+ head = self.rorepo.heads[0]
assert_equal('refactoring/feature1', head.name)
assert_true(git.called)
diff --git a/test/git/test_index.py b/test/git/test_index.py
index 4c17f5e5..10ffb79d 100644
--- a/test/git/test_index.py
+++ b/test/git/test_index.py
@@ -10,15 +10,11 @@ import inspect
import os
import tempfile
-class TestTree(TestCase):
+class TestTree(TestBase):
- @classmethod
- def setUpAll(cls):
- cls.repo = Repo(GIT_REPO)
-
def test_base(self):
# read from file
- index = Index.from_file(self.repo, fixture_path("index"))
+ index = Index.from_file(self.rorepo, fixture_path("index"))
assert index.entries
assert index.version > 0
@@ -31,7 +27,7 @@ class TestTree(TestCase):
# END for each method
# test stage
- index_merge = Index.from_file(self.repo, fixture_path("index_merge"))
+ index_merge = Index.from_file(self.rorepo, fixture_path("index_merge"))
assert len(index_merge.entries) == 106
assert len(list(e for e in index_merge.entries.itervalues() if e.stage != 0 ))
@@ -50,7 +46,7 @@ class TestTree(TestCase):
def _cmp_tree_index(self, tree, index):
# fail unless both objects contain the same paths and blobs
if isinstance(tree, str):
- tree = self.repo.commit(tree).tree
+ tree = self.rorepo.commit(tree).tree
num_blobs = 0
for blob in tree.traverse(predicate = lambda e: e.type == "blob"):
@@ -65,17 +61,17 @@ class TestTree(TestCase):
other_sha = "39f85c4358b7346fee22169da9cad93901ea9eb9"
# simple index from tree
- base_index = Index.from_tree(self.repo, common_ancestor_sha)
+ base_index = Index.from_tree(self.rorepo, common_ancestor_sha)
assert base_index.entries
self._cmp_tree_index(common_ancestor_sha, base_index)
# merge two trees - its like a fast-forward
- two_way_index = Index.from_tree(self.repo, common_ancestor_sha, cur_sha)
+ two_way_index = Index.from_tree(self.rorepo, common_ancestor_sha, cur_sha)
assert two_way_index.entries
self._cmp_tree_index(cur_sha, two_way_index)
# merge three trees - here we have a merge conflict
- three_way_index = Index.from_tree(self.repo, common_ancestor_sha, cur_sha, other_sha)
+ three_way_index = Index.from_tree(self.rorepo, common_ancestor_sha, cur_sha, other_sha)
assert len(list(e for e in three_way_index.entries.values() if e.stage != 0))
diff --git a/test/git/test_performance.py b/test/git/test_performance.py
index 77567515..83d4a91e 100644
--- a/test/git/test_performance.py
+++ b/test/git/test_performance.py
@@ -8,9 +8,7 @@ from test.testlib import *
from git import *
from time import time
-class TestPerformance(object):
- def setup(self):
- self.repo = Repo(GIT_REPO)
+class TestPerformance(TestBase):
def test_iteration(self):
num_objs = 0
@@ -21,7 +19,7 @@ class TestPerformance(object):
# return quite a lot of commits, we just take one and hence abort the operation
st = time()
- for c in self.repo.iter_commits('0.1.6'):
+ for c in self.rorepo.iter_commits('0.1.6'):
num_commits += 1
c.author
c.authored_date
diff --git a/test/git/test_remote.py b/test/git/test_remote.py
index aeb6b4af..ef00056d 100644
--- a/test/git/test_remote.py
+++ b/test/git/test_remote.py
@@ -7,16 +7,13 @@
from test.testlib import *
from git import *
-class TestRemote(TestCase):
+class TestRemote(TestBase):
- @classmethod
- def setUpAll(cls):
- cls.repo = Repo(GIT_REPO)
-
- def test_base(self):
+ @with_rw_and_rw_remote_repo('0.1.6')
+ def test_base(self, rw_repo, remote_repo):
num_remotes = 0
remote_set = set()
- for remote in self.repo.remotes:
+ for remote in rw_repo.remotes:
num_remotes += 1
assert remote == remote
assert str(remote) != repr(remote)
@@ -64,27 +61,29 @@ class TestRemote(TestCase):
remote.fetch()
self.failUnlessRaises(GitCommandError, remote.pull)
+ remote.pull('master')
remote.update()
self.fail("test push once there is a test-repo")
# END for each remote
assert num_remotes
assert num_remotes == len(remote_set)
- origin = self.repo.remote('origin')
- assert origin == self.repo.remotes.origin
+ origin = rw_repo.remote('origin')
+ assert origin == rw_repo.remotes.origin
- def test_creation_and_removal(self):
+ @with_bare_rw_repo
+ def test_creation_and_removal(self, bare_rw_repo):
new_name = "test_new_one"
arg_list = (new_name, "git@server:hello.git")
- remote = Remote.create(self.repo, *arg_list )
+ remote = Remote.create(bare_rw_repo, *arg_list )
assert remote.name == "test_new_one"
# create same one again
- self.failUnlessRaises(GitCommandError, Remote.create, self.repo, *arg_list)
+ self.failUnlessRaises(GitCommandError, Remote.create, bare_rw_repo, *arg_list)
- Remote.remove(self.repo, new_name)
+ Remote.remove(bare_rw_repo, new_name)
- for remote in self.repo.remotes:
+ for remote in bare_rw_repo.remotes:
if remote.name == new_name:
raise AssertionError("Remote removal failed")
# END if deleted remote matches existing remote's name
diff --git a/test/git/test_repo.py b/test/git/test_repo.py
index ff10f6a6..02eea7de 100644
--- a/test/git/test_repo.py
+++ b/test/git/test_repo.py
@@ -8,11 +8,7 @@ import os, sys
from test.testlib import *
from git import *
-class TestRepo(TestCase):
-
- @classmethod
- def setUpAll(cls):
- cls.repo = Repo(GIT_REPO)
+class TestRepo(TestBase):
@raises(InvalidGitRepositoryError)
def test_new_should_raise_on_invalid_repo_location(self):
@@ -27,27 +23,27 @@ class TestRepo(TestCase):
def test_description(self):
txt = "Test repository"
- self.repo.description = txt
- assert_equal(self.repo.description, txt)
+ self.rorepo.description = txt
+ assert_equal(self.rorepo.description, txt)
def test_heads_should_return_array_of_head_objects(self):
- for head in self.repo.heads:
+ for head in self.rorepo.heads:
assert_equal(Head, head.__class__)
def test_heads_should_populate_head_data(self):
- for head in self.repo.heads:
+ for head in self.rorepo.heads:
assert head.name
assert isinstance(head.commit,Commit)
# END for each head
- assert isinstance(self.repo.heads.master, Head)
- assert isinstance(self.repo.heads['master'], Head)
+ assert isinstance(self.rorepo.heads.master, Head)
+ assert isinstance(self.rorepo.heads['master'], Head)
@patch_object(Git, '_call_process')
def test_commits(self, git):
git.return_value = ListProcessAdapter(fixture('rev_list'))
- commits = list( self.repo.iter_commits('master', max_count=10) )
+ commits = list( self.rorepo.iter_commits('master', max_count=10) )
c = commits[0]
assert_equal('4c8124ffcf4039d292442eeccabdeca5af5c5017', c.id)
@@ -73,7 +69,7 @@ class TestRepo(TestCase):
def test_trees(self):
mc = 30
num_trees = 0
- for tree in self.repo.iter_trees('0.1.5', max_count=mc):
+ for tree in self.rorepo.iter_trees('0.1.5', max_count=mc):
num_trees += 1
assert isinstance(tree, Tree)
# END for each tree
@@ -93,7 +89,7 @@ class TestRepo(TestCase):
assert_true(repo.called)
def test_bare_property(self):
- self.repo.bare
+ self.rorepo.bare
@patch_object(Repo, '__init__')
@patch_object(Git, '_call_process')
@@ -113,7 +109,7 @@ class TestRepo(TestCase):
git.return_value = None
repo.return_value = None
- self.repo.clone("repos/foo/bar.git")
+ self.rorepo.clone("repos/foo/bar.git")
assert_true(git.called)
path = os.path.join(absolute_project_path(), '.git')
@@ -126,7 +122,7 @@ class TestRepo(TestCase):
git.return_value = None
repo.return_value = None
- self.repo.clone("repos/foo/bar.git", **{'template': '/awesome'})
+ self.rorepo.clone("repos/foo/bar.git", **{'template': '/awesome'})
assert_true(git.called)
path = os.path.join(absolute_project_path(), '.git')
@@ -136,63 +132,63 @@ class TestRepo(TestCase):
def test_daemon_export(self):
- orig_val = self.repo.daemon_export
- self.repo.daemon_export = not orig_val
- assert self.repo.daemon_export == ( not orig_val )
- self.repo.daemon_export = orig_val
- assert self.repo.daemon_export == orig_val
+ orig_val = self.rorepo.daemon_export
+ self.rorepo.daemon_export = not orig_val
+ assert self.rorepo.daemon_export == ( not orig_val )
+ self.rorepo.daemon_export = orig_val
+ assert self.rorepo.daemon_export == orig_val
def test_alternates(self):
- cur_alternates = self.repo.alternates
+ cur_alternates = self.rorepo.alternates
# empty alternates
- self.repo.alternates = []
- assert self.repo.alternates == []
+ self.rorepo.alternates = []
+ assert self.rorepo.alternates == []
alts = [ "other/location", "this/location" ]
- self.repo.alternates = alts
- assert alts == self.repo.alternates
- self.repo.alternates = cur_alternates
+ self.rorepo.alternates = alts
+ assert alts == self.rorepo.alternates
+ self.rorepo.alternates = cur_alternates
def test_repr(self):
path = os.path.join(os.path.abspath(GIT_REPO), '.git')
- assert_equal('<git.Repo "%s">' % path, repr(self.repo))
+ assert_equal('<git.Repo "%s">' % path, repr(self.rorepo))
def test_is_dirty_with_bare_repository(self):
- self.repo._bare = True
- assert_false(self.repo.is_dirty)
+ self.rorepo._bare = True
+ assert_false(self.rorepo.is_dirty)
def test_is_dirty(self):
- self.repo._bare = False
+ self.rorepo._bare = False
for index in (0,1):
for working_tree in (0,1):
for untracked_files in (0,1):
- assert self.repo.is_dirty in (True, False)
+ assert self.rorepo.is_dirty in (True, False)
# END untracked files
# END working tree
# END index
- self.repo._bare = True
- assert self.repo.is_dirty == False
+ self.rorepo._bare = True
+ assert self.rorepo.is_dirty == False
@patch_object(Git, '_call_process')
def test_active_branch(self, git):
git.return_value = 'refs/heads/major-refactoring'
- assert_equal(self.repo.active_branch.name, 'major-refactoring')
+ assert_equal(self.rorepo.active_branch.name, 'major-refactoring')
assert_equal(git.call_args, (('symbolic_ref', 'HEAD'), {}))
def test_head(self):
- assert self.repo.head.object == self.repo.active_branch.object
+ assert self.rorepo.head.object == self.rorepo.active_branch.object
def test_tag(self):
- assert self.repo.tag('0.1.5').commit
+ assert self.rorepo.tag('0.1.5').commit
def test_archive(self):
tmpfile = os.tmpfile()
- self.repo.archive(tmpfile, '0.1.5')
+ self.rorepo.archive(tmpfile, '0.1.5')
assert tmpfile.tell()
@patch_object(Git, '_call_process')
def test_should_display_blame_information(self, git):
git.return_value = fixture('blame')
- b = self.repo.blame( 'master', 'lib/git.py')
+ b = self.rorepo.blame( 'master', 'lib/git.py')
assert_equal(13, len(b))
assert_equal( 2, len(b[0]) )
# assert_equal(25, reduce(lambda acc, x: acc + len(x[-1]), b))
@@ -217,7 +213,7 @@ class TestRepo(TestCase):
assert_true( len( tlist ) < sum( len(t) for t in tlist ) ) # test for single-char bug
def test_untracked_files(self):
- base = self.repo.git.git_dir
+ base = self.rorepo.git.git_dir
files = (base+"/__test_myfile", base+"/__test_other_file")
num_recently_untracked = 0
try:
@@ -225,7 +221,7 @@ class TestRepo(TestCase):
fd = open(fpath,"wb")
fd.close()
# END for each filename
- untracked_files = self.repo.untracked_files
+ untracked_files = self.rorepo.untracked_files
num_recently_untracked = len(untracked_files)
# assure we have all names - they are relative to the git-dir
@@ -239,18 +235,18 @@ class TestRepo(TestCase):
os.remove(fpath)
# END handle files
- assert len(self.repo.untracked_files) == (num_recently_untracked - len(files))
+ assert len(self.rorepo.untracked_files) == (num_recently_untracked - len(files))
def test_config_reader(self):
- reader = self.repo.config_reader() # all config files
+ reader = self.rorepo.config_reader() # all config files
assert reader.read_only
- reader = self.repo.config_reader("repository") # single config file
+ reader = self.rorepo.config_reader("repository") # single config file
assert reader.read_only
def test_config_writer(self):
- for config_level in self.repo.config_level:
+ for config_level in self.rorepo.config_level:
try:
- writer = self.repo.config_writer(config_level)
+ writer = self.rorepo.config_writer(config_level)
assert not writer.read_only
except IOError:
# its okay not to get a writer for some configuration files if we
diff --git a/test/git/test_stats.py b/test/git/test_stats.py
index 706f29a4..7392a96e 100644
--- a/test/git/test_stats.py
+++ b/test/git/test_stats.py
@@ -7,13 +7,11 @@
from test.testlib import *
from git import *
-class TestStats(object):
- def setup(self):
- self.repo = Repo(GIT_REPO)
+class TestStats(TestBase):
def test__list_from_string(self):
output = fixture('diff_numstat')
- stats = Stats._list_from_string(self.repo, output)
+ stats = Stats._list_from_string(self.rorepo, output)
assert_equal(2, stats.total['files'])
assert_equal(52, stats.total['lines'])
diff --git a/test/git/test_tag.py b/test/git/test_tag.py
index 9641e0ac..97e0acd1 100644
--- a/test/git/test_tag.py
+++ b/test/git/test_tag.py
@@ -9,13 +9,11 @@ from test.testlib import *
from git import *
from git.objects.tag import TagObject
-class TestTag(object):
- def setup(self):
- self.repo = Repo(GIT_REPO)
+class TestTag(TestBase):
def test_tag_base(self):
tag_object_refs = list()
- for tag in self.repo.tags:
+ for tag in self.rorepo.tags:
assert "refs/tags" in tag.path
assert tag.name
assert isinstance( tag.commit, Commit )
@@ -30,6 +28,6 @@ class TestTag(object):
# END if we have a tag object
# END for tag in repo-tags
assert tag_object_refs
- assert isinstance(self.repo.tags['0.1.5'], TagReference)
+ assert isinstance(self.rorepo.tags['0.1.5'], TagReference)
diff --git a/test/testlib/__init__.py b/test/testlib/__init__.py
index f364171b..2133eb8c 100644
--- a/test/testlib/__init__.py
+++ b/test/testlib/__init__.py
@@ -8,7 +8,6 @@ import inspect
from mock import *
from asserts import *
from helper import *
-from unittest import TestCase
__all__ = [ name for name, obj in locals().items()
if not (name.startswith('_') or inspect.ismodule(obj)) ]
diff --git a/test/testlib/helper.py b/test/testlib/helper.py
index b34c9303..eef7876f 100644
--- a/test/testlib/helper.py
+++ b/test/testlib/helper.py
@@ -5,6 +5,10 @@
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
import os
+from git import Repo
+from unittest import TestCase
+import tempfile
+import shutil
GIT_REPO = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
@@ -58,3 +62,117 @@ class ListProcessAdapter(object):
return 0
poll = wait
+
+
+def with_bare_rw_repo(func):
+ """
+ Decorator providing a specially made read-write repository to the test case
+ decorated with it. The test case requires the following signature::
+ def case(self, rw_repo)
+
+ The rwrepo will be a bare clone or the types rorepo. Once the method finishes,
+ it will be removed completely.
+
+ Use this if you want to make purely index based adjustments, change refs, create
+ heads, generally operations that do not need a working tree.
+ """
+ def bare_repo_creator(self):
+ repo_dir = tempfile.mktemp("bare_repo")
+ rw_repo = self.rorepo.clone(repo_dir, shared=True, bare=True)
+ try:
+ return func(self, rw_repo)
+ finally:
+ shutil.rmtree(repo_dir)
+ # END cleanup
+ # END bare repo creator
+ bare_repo_creator.__name__ = func.__name__
+ return bare_repo_creator
+
+def with_rw_repo(working_tree_ref):
+ """
+ Same as with_bare_repo, but clones the rorepo as non-bare repository, checking
+ out the working tree at the given working_tree_ref.
+
+ This repository type is more costly due to the working copy checkout.
+ """
+ assert isinstance(working_tree_ref, basestring), "Decorator requires ref name for working tree checkout"
+ def argument_passer(func):
+ def repo_creator(self):
+ repo_dir = tempfile.mktemp("non_bare_repo")
+ rw_repo = self.rorepo.clone(repo_dir, shared=True, bare=False, n=True)
+ rw_repo.git.checkout(working_tree_ref)
+ try:
+ return func(self, rw_repo)
+ finally:
+ shutil.rmtree(repo_dir)
+ # END cleanup
+ # END rw repo creator
+ repo_creator.__name__ = func.__name__
+ return repo_creator
+ # END argument passer
+ return argument_passer
+
+def with_rw_and_rw_remote_repo(working_tree_ref):
+ """
+ Same as with_rw_repo, but also provides a writable remote repository from which the
+ rw_repo has been forked. The remote repository was cloned as bare repository from
+ the rorepo, wheras the rw repo has a working tree and was cloned from the remote repository.
+
+ The following scetch demonstrates this::
+ rorepo ---<bare clone>---> rw_remote_repo ---<clone>---> rw_repo
+
+ The test case needs to support the following signature::
+ def case(self, rw_repo, rw_remote_repo)
+
+ This setup allows you to test push and pull scenarios and hooks nicely.
+ """
+ assert isinstance(working_tree_ref, basestring), "Decorator requires ref name for working tree checkout"
+ def argument_passer(func):
+ def remote_repo_creator(self):
+ remote_repo_dir = tempfile.mktemp("remote_repo")
+ repo_dir = tempfile.mktemp("remote_clone_non_bare_repo")
+
+ rw_remote_repo = self.rorepo.clone(remote_repo_dir, shared=True, bare=True)
+ rw_repo = rw_remote_repo.clone(repo_dir, shared=True, bare=False, n=True) # recursive alternates info ?
+ rw_repo.git.checkout(working_tree_ref)
+ try:
+ return func(self, rw_repo, rw_remote_repo)
+ finally:
+ shutil.rmtree(repo_dir)
+ shutil.rmtree(remote_repo_dir)
+ # END cleanup
+ # END bare repo creator
+ remote_repo_creator.__name__ = func.__name__
+ return remote_repo_creator
+ # END remote repo creator
+ # END argument parsser
+
+ return argument_passer
+
+
+class TestBase(TestCase):
+ """
+ Base Class providing default functionality to all tests such as:
+
+ - Utility functions provided by the TestCase base of the unittest method such as::
+ self.fail("todo")
+ self.failUnlessRaises(...)
+
+ - Class level repository which is considered read-only as it is shared among
+ all test cases in your type.
+ Access it using::
+ self.rorepo # 'ro' stands for read-only
+
+ 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 ).
+ """
+
+ @classmethod
+ def setUpAll(cls):
+ """
+ Dynamically add a read-only repository to our actual type. This way
+ each test type has its own repository
+ """
+ cls.rorepo = Repo(GIT_REPO)
+