diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2009-10-15 10:04:17 +0200 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2009-10-15 10:04:17 +0200 |
commit | 6226720b0e6a5f7cb9223fc50363def487831315 (patch) | |
tree | 10f70f8e41c91f5bf57f04b616f3e5afdb9f8407 /test/git/test_repo.py | |
parent | b0e84a3401c84507dc017d6e4f57a9dfdb31de53 (diff) | |
parent | 4186a2dbbd48fd67ff88075c63bbd3e6c1d8a2df (diff) | |
download | gitpython-6226720b0e6a5f7cb9223fc50363def487831315.tar.gz |
Initial set of improvementes merged into master, including a class hierarchy redesign and performance improvements
Merge commit 'origin/improvements'
* commit 'origin/improvements': (38 commits)
test_performance: module containing benchmarks to get an idea of the achieved throughput
Removed plenty of mocked tree tests as they cannot work anymore with persistent commands that require stdin AND binary data - not even an adapter would help here. These tests will have to be replaced.
tree: now reads tress directly by parsing the binary data, allowing it to safe possibly hundreds of command calls
Refs are now truly dynamic - this costs a little bit of (persistent command) work, but assures refs behave as expected
persistent command signature changed to also return the hexsha from a possible input ref - the objects pointed to by refs are now baked on demand - perhaps it should change to always be re-retrieved using a property as it is relatively fast - this way refs can always be cached
test_blob: removed many redundant tests that would fail now as the mock cannot handle the complexity of the command backend
Implemented git command facility to keep persistent commands for fast object information retrieval
test: Added time-consuming test which could also be a benchmark in fact - currently it cause hundreds of command invocations which is slow
cmd: added option to return the process directly, allowing to read the output directly from the output stream
added Iterable interface to Ref type
renamed find_all to list_all, changed commit to use iterable interface in preparation for command changes
Added base for all iteratable objects
unified name of utils module, recently it was named util and utils in different packages
tree: renamed content_from_string to _from_string to make it private. Removed tests that were testing that method
tree: now behaves like a list with string indexing functionality - using a dict as cache is a problem as the tree is ordered, added blobs, trees and traverse method
test_base: Improved basic object creation as well as set hash tests
repo.active_branch now returns a Head object, not a string
IndexObjects are now checking their slots to raise a proper error message in case someone tries to access an unset path or mode - this information cannot be retrieved afterwards as IndexObject information is kept in the object that pointed at them. To find this information, one would have to search all objects which is not feasible
refs now take repo as first argument and derive from LazyMixin to allow them to dynamically retrieve their objects
renamed from_string and list_from_string to _from_string and _list_from_string to indicate their new status as private method, adjusted all callers respectively
...
Diffstat (limited to 'test/git/test_repo.py')
-rw-r--r-- | test/git/test_repo.py | 450 |
1 files changed, 216 insertions, 234 deletions
diff --git a/test/git/test_repo.py b/test/git/test_repo.py index a9d3beaf..e998ac6d 100644 --- a/test/git/test_repo.py +++ b/test/git/test_repo.py @@ -10,255 +10,237 @@ from test.testlib import * from git import * class TestRepo(object): - def setup(self): - self.repo = Repo(GIT_REPO) - - @raises(InvalidGitRepositoryError) - def test_new_should_raise_on_invalid_repo_location(self): - if sys.platform == "win32": - Repo("C:\\WINDOWS\\Temp") - else: - Repo("/tmp") + def setup(self): + self.repo = Repo(GIT_REPO) + + @raises(InvalidGitRepositoryError) + def test_new_should_raise_on_invalid_repo_location(self): + if sys.platform == "win32": + Repo("C:\\WINDOWS\\Temp") + else: + Repo("/tmp") + + @raises(NoSuchPathError) + def test_new_should_raise_on_non_existant_path(self): + Repo("repos/foobar") + + def test_description(self): + txt = "Test repository" + self.repo.description = txt + assert_equal(self.repo.description, txt) + + def test_heads_should_return_array_of_head_objects(self): + for head in self.repo.heads: + assert_equal(Head, head.__class__) + + def test_heads_should_populate_head_data(self): + for head in self.repo.heads: + assert head.name + assert isinstance(head.commit,Commit) + # END for each head + + @patch_object(Git, '_call_process') + def test_commits(self, git): + git.return_value = ListProcessAdapter(fixture('rev_list')) + + commits = self.repo.commits('master', max_count=10) + + c = commits[0] + assert_equal('4c8124ffcf4039d292442eeccabdeca5af5c5017', c.id) + assert_equal(["634396b2f541a9f2d58b00be1a07f0c358b999b3"], [p.id for p in c.parents]) + assert_equal("672eca9b7f9e09c22dcb128c283e8c3c8d7697a4", c.tree.id) + assert_equal("Tom Preston-Werner", c.author.name) + assert_equal("tom@mojombo.com", c.author.email) + assert_equal(time.gmtime(1191999972), c.authored_date) + assert_equal("Tom Preston-Werner", c.committer.name) + assert_equal("tom@mojombo.com", c.committer.email) + assert_equal(time.gmtime(1191999972), c.committed_date) + assert_equal("implement Grit#heads", c.message) + + c = commits[1] + assert_equal(tuple(), c.parents) + + c = commits[2] + assert_equal(["6e64c55896aabb9a7d8e9f8f296f426d21a78c2c", "7f874954efb9ba35210445be456c74e037ba6af2"], map(lambda p: p.id, c.parents)) + assert_equal("Merge branch 'site'", c.summary) + + assert_true(git.called) + + @patch_object(Git, '_call_process') + def test_commit_count(self, git): + git.return_value = fixture('rev_list_count') + + assert_equal(655, self.repo.commit_count('master')) + + assert_true(git.called) + assert_equal(git.call_args, (('rev_list', 'master', '--', ''), {})) + + @patch_object(Git, '_call_process') + def test_commit(self, git): + git.return_value = ListProcessAdapter(fixture('rev_list_single')) + + commit = self.repo.commit('4c8124ffcf4039d292442eeccabdeca5af5c5017') + + assert_equal("4c8124ffcf4039d292442eeccabdeca5af5c5017", commit.id) + + assert_true(git.called) + + @patch_object(Repo, '__init__') + @patch_object(Git, '_call_process') + def test_init_bare(self, git, repo): + git.return_value = True + repo.return_value = None + + Repo.init_bare("repos/foo/bar.git") + + assert_true(git.called) + assert_equal(git.call_args, (('init', '--bare'), {})) + assert_true(repo.called) + assert_equal(repo.call_args, (('repos/foo/bar.git',), {})) + + @patch_object(Repo, '__init__') + @patch_object(Git, '_call_process') + def test_init_bare_with_options(self, git, repo): + git.return_value = True + repo.return_value = None + + Repo.init_bare("repos/foo/bar.git", **{'template': "/baz/sweet"}) + + assert_true(git.called) + assert_equal(git.call_args, (('init', '--bare'), {'template': '/baz/sweet'})) + assert_true(repo.called) + assert_equal(repo.call_args, (('repos/foo/bar.git',), {})) + + @patch_object(Repo, '__init__') + @patch_object(Git, '_call_process') + def test_fork_bare(self, git, repo): + git.return_value = None + repo.return_value = None - @raises(NoSuchPathError) - def test_new_should_raise_on_non_existant_path(self): - Repo("repos/foobar") + self.repo.fork_bare("repos/foo/bar.git") - def test_description(self): - txt = "Test repository" - self.repo.description = txt - assert_equal(self.repo.description, txt) + assert_true(git.called) + path = os.path.join(absolute_project_path(), '.git') + assert_equal(git.call_args, (('clone', path, 'repos/foo/bar.git'), {'bare': True})) + assert_true(repo.called) - def test_heads_should_return_array_of_head_objects(self): - for head in self.repo.heads: - assert_equal(Head, head.__class__) + @patch_object(Repo, '__init__') + @patch_object(Git, '_call_process') + def test_fork_bare_with_options(self, git, repo): + git.return_value = None + repo.return_value = None - @patch_object(Git, '_call_process') - def test_heads_should_populate_head_data(self, git): - git.return_value = fixture('for_each_ref') + self.repo.fork_bare("repos/foo/bar.git", **{'template': '/awesome'}) - head = self.repo.heads[0] - assert_equal('master', head.name) - assert_equal('634396b2f541a9f2d58b00be1a07f0c358b999b3', head.commit.id) + assert_true(git.called) + path = os.path.join(absolute_project_path(), '.git') + assert_equal(git.call_args, (('clone', path, 'repos/foo/bar.git'), + {'bare': True, 'template': '/awesome'})) + assert_true(repo.called) - assert_true(git.called) - assert_equal(git.call_args, (('for_each_ref', 'refs/heads'), {'sort': 'committerdate', 'format': '%(refname)%00%(objectname)'})) + @patch_object(Git, '_call_process') + def test_diff(self, git): + self.repo.diff('master^', 'master') - @patch_object(Git, '_call_process') - def test_commits(self, git): - git.return_value = fixture('rev_list') + assert_true(git.called) + assert_equal(git.call_args, (('diff', 'master^', 'master', '--'), {})) - commits = self.repo.commits('master', max_count=10) + self.repo.diff('master^', 'master', 'foo/bar') - c = commits[0] - assert_equal('4c8124ffcf4039d292442eeccabdeca5af5c5017', c.id) - assert_equal(["634396b2f541a9f2d58b00be1a07f0c358b999b3"], [p.id for p in c.parents]) - assert_equal("672eca9b7f9e09c22dcb128c283e8c3c8d7697a4", c.tree.id) - assert_equal("Tom Preston-Werner", c.author.name) - assert_equal("tom@mojombo.com", c.author.email) - assert_equal(time.gmtime(1191999972), c.authored_date) - assert_equal("Tom Preston-Werner", c.committer.name) - assert_equal("tom@mojombo.com", c.committer.email) - assert_equal(time.gmtime(1191999972), c.committed_date) - assert_equal("implement Grit#heads", c.message) + assert_true(git.called) + assert_equal(git.call_args, (('diff', 'master^', 'master', '--', 'foo/bar'), {})) - c = commits[1] - assert_equal([], c.parents) + self.repo.diff('master^', 'master', 'foo/bar', 'foo/baz') - c = commits[2] - assert_equal(["6e64c55896aabb9a7d8e9f8f296f426d21a78c2c", "7f874954efb9ba35210445be456c74e037ba6af2"], map(lambda p: p.id, c.parents)) - assert_equal("Merge branch 'site'", c.summary) + assert_true(git.called) + assert_equal(git.call_args, (('diff', 'master^', 'master', '--', 'foo/bar', 'foo/baz'), {})) - assert_true(git.called) - assert_equal(git.call_args, (('rev_list', 'master', '--', ''), {'skip': 0, 'pretty': 'raw', 'max_count': 10})) + @patch_object(Git, '_call_process') + def test_diff_with_parents(self, git): + git.return_value = fixture('diff_p') - @patch_object(Git, '_call_process') - def test_commit_count(self, git): - git.return_value = fixture('rev_list_count') + diffs = self.repo.commit_diff('master') + assert_equal(15, len(diffs)) + assert_true(git.called) - assert_equal(655, self.repo.commit_count('master')) + def test_archive_tar(self): + assert self.repo.archive_tar() - assert_true(git.called) - assert_equal(git.call_args, (('rev_list', 'master', '--', ''), {})) + def test_archive_tar_gz(self): + assert self.repo.archive_tar_gz() - @patch_object(Git, '_call_process') - def test_commit(self, git): - git.return_value = fixture('rev_list_single') + @patch('git.utils.touch') + def test_enable_daemon_serve(self, touch): + self.repo.daemon_serve = False + assert_false(self.repo.daemon_serve) - commit = self.repo.commit('4c8124ffcf4039d292442eeccabdeca5af5c5017') - - assert_equal("4c8124ffcf4039d292442eeccabdeca5af5c5017", commit.id) - - assert_true(git.called) - assert_equal(git.call_args, (('rev_list', '4c8124ffcf4039d292442eeccabdeca5af5c5017', '--', ''), {'pretty': 'raw', 'max_count': 1})) - - @patch_object(Git, '_call_process') - def test_tree(self, git): - git.return_value = fixture('ls_tree_a') - - tree = self.repo.tree('master') - - assert_equal(4, len([c for c in tree.values() if isinstance(c, Blob)])) - assert_equal(3, len([c for c in tree.values() if isinstance(c, Tree)])) - - assert_true(git.called) - assert_equal(git.call_args, (('ls_tree', 'master'), {})) - - @patch_object(Git, '_call_process') - def test_blob(self, git): - git.return_value = fixture('cat_file_blob') - - blob = self.repo.blob("abc") - assert_equal("Hello world", blob.data) - - assert_true(git.called) - assert_equal(git.call_args, (('cat_file', 'abc'), {'p': True, 'with_raw_output': True})) - - @patch_object(Repo, '__init__') - @patch_object(Git, '_call_process') - def test_init_bare(self, git, repo): - git.return_value = True - repo.return_value = None - - Repo.init_bare("repos/foo/bar.git") - - assert_true(git.called) - assert_equal(git.call_args, (('init', '--bare'), {})) - assert_true(repo.called) - assert_equal(repo.call_args, (('repos/foo/bar.git',), {})) - - @patch_object(Repo, '__init__') - @patch_object(Git, '_call_process') - def test_init_bare_with_options(self, git, repo): - git.return_value = True - repo.return_value = None - - Repo.init_bare("repos/foo/bar.git", **{'template': "/baz/sweet"}) - - assert_true(git.called) - assert_equal(git.call_args, (('init', '--bare'), {'template': '/baz/sweet'})) - assert_true(repo.called) - assert_equal(repo.call_args, (('repos/foo/bar.git',), {})) - - @patch_object(Repo, '__init__') - @patch_object(Git, '_call_process') - def test_fork_bare(self, git, repo): - git.return_value = None - repo.return_value = None - - self.repo.fork_bare("repos/foo/bar.git") - - assert_true(git.called) - path = os.path.join(absolute_project_path(), '.git') - assert_equal(git.call_args, (('clone', path, 'repos/foo/bar.git'), {'bare': True})) - assert_true(repo.called) - - @patch_object(Repo, '__init__') - @patch_object(Git, '_call_process') - def test_fork_bare_with_options(self, git, repo): - git.return_value = None - repo.return_value = None - - self.repo.fork_bare("repos/foo/bar.git", **{'template': '/awesome'}) - - assert_true(git.called) - path = os.path.join(absolute_project_path(), '.git') - assert_equal(git.call_args, (('clone', path, 'repos/foo/bar.git'), - {'bare': True, 'template': '/awesome'})) - assert_true(repo.called) - - @patch_object(Git, '_call_process') - def test_diff(self, git): - self.repo.diff('master^', 'master') - - assert_true(git.called) - assert_equal(git.call_args, (('diff', 'master^', 'master', '--'), {})) - - self.repo.diff('master^', 'master', 'foo/bar') - - assert_true(git.called) - assert_equal(git.call_args, (('diff', 'master^', 'master', '--', 'foo/bar'), {})) - - self.repo.diff('master^', 'master', 'foo/bar', 'foo/baz') - - assert_true(git.called) - assert_equal(git.call_args, (('diff', 'master^', 'master', '--', 'foo/bar', 'foo/baz'), {})) - - @patch_object(Git, '_call_process') - def test_diff_with_parents(self, git): - git.return_value = fixture('diff_p') - - diffs = self.repo.commit_diff('master') - assert_equal(15, len(diffs)) - assert_true(git.called) - - def test_archive_tar(self): - assert self.repo.archive_tar() - - def test_archive_tar_gz(self): - assert self.repo.archive_tar_gz() - - @patch('git.utils.touch') - def test_enable_daemon_serve(self, touch): - self.repo.daemon_serve = False - assert_false(self.repo.daemon_serve) - - def test_disable_daemon_serve(self): - self.repo.daemon_serve = True - assert_true(self.repo.daemon_serve) + def test_disable_daemon_serve(self): + self.repo.daemon_serve = True + assert_true(self.repo.daemon_serve) - @patch_object(os.path, 'exists') - def test_alternates_no_file(self, os): - os.return_value = False - assert_equal([], self.repo.alternates) - - assert_true(os.called) - - @patch_object(os, 'remove') - def test_alternates_setter_empty(self, os): - self.repo.alternates = [] - assert_true(os.called) - - def test_repr(self): - path = os.path.join(os.path.abspath(GIT_REPO), '.git') - assert_equal('<git.Repo "%s">' % path, repr(self.repo)) - - @patch_object(Git, '_call_process') - def test_log(self, git): - git.return_value = fixture('rev_list') - assert_equal('4c8124ffcf4039d292442eeccabdeca5af5c5017', self.repo.log()[0].id) - assert_equal('ab25fd8483882c3bda8a458ad2965d2248654335', self.repo.log()[-1].id) - assert_true(git.called) - assert_equal(git.call_count, 2) - assert_equal(git.call_args, (('log', 'master', '--'), {'pretty': 'raw'})) - - @patch_object(Git, '_call_process') - def test_log_with_path_and_options(self, git): - git.return_value = fixture('rev_list') - self.repo.log('master', 'file.rb', **{'max_count': 1}) - assert_true(git.called) - assert_equal(git.call_args, (('log', 'master', '--', 'file.rb'), {'pretty': 'raw', 'max_count': 1})) - - def test_is_dirty_with_bare_repository(self): - self.repo.bare = True - assert_false(self.repo.is_dirty) - - @patch_object(Git, '_call_process') - def test_is_dirty_with_clean_working_dir(self, git): - self.repo.bare = False - git.return_value = '' - assert_false(self.repo.is_dirty) - assert_equal(git.call_args, (('diff', 'HEAD', '--'), {})) - - @patch_object(Git, '_call_process') - def test_is_dirty_with_dirty_working_dir(self, git): - self.repo.bare = False - git.return_value = '''-aaa\n+bbb''' - assert_true(self.repo.is_dirty) - assert_equal(git.call_args, (('diff', 'HEAD', '--'), {})) - - @patch_object(Git, '_call_process') - def test_active_branch(self, git): - git.return_value = 'refs/heads/major-refactoring' - assert_equal(self.repo.active_branch, 'major-refactoring') - assert_equal(git.call_args, (('symbolic_ref', 'HEAD'), {})) + @patch_object(os.path, 'exists') + def test_alternates_no_file(self, os): + os.return_value = False + assert_equal([], self.repo.alternates) + + assert_true(os.called) + + @patch_object(os, 'remove') + def test_alternates_setter_empty(self, os): + self.repo.alternates = [] + assert_true(os.called) + + def test_repr(self): + path = os.path.join(os.path.abspath(GIT_REPO), '.git') + assert_equal('<git.Repo "%s">' % path, repr(self.repo)) + + def test_is_dirty_with_bare_repository(self): + self.repo.bare = True + assert_false(self.repo.is_dirty) + + @patch_object(Git, '_call_process') + def test_is_dirty_with_clean_working_dir(self, git): + self.repo.bare = False + git.return_value = '' + assert_false(self.repo.is_dirty) + assert_equal(git.call_args, (('diff', 'HEAD', '--'), {})) + + @patch_object(Git, '_call_process') + def test_is_dirty_with_dirty_working_dir(self, git): + self.repo.bare = False + git.return_value = '''-aaa\n+bbb''' + assert_true(self.repo.is_dirty) + assert_equal(git.call_args, (('diff', 'HEAD', '--'), {})) + + @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(git.call_args, (('symbolic_ref', 'HEAD'), {})) + + @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') + assert_equal(13, len(b)) + assert_equal( 2, len(b[0]) ) + # assert_equal(25, reduce(lambda acc, x: acc + len(x[-1]), b)) + assert_equal(hash(b[0][0]), hash(b[9][0])) + c = b[0][0] + assert_true(git.called) + assert_equal(git.call_args, (('blame', 'master', '--', 'lib/git.py'), {'p': True})) + + assert_equal('634396b2f541a9f2d58b00be1a07f0c358b999b3', c.id) + assert_equal('Tom Preston-Werner', c.author.name) + assert_equal('tom@mojombo.com', c.author.email) + assert_equal(time.gmtime(1191997100), c.authored_date) + assert_equal('Tom Preston-Werner', c.committer.name) + assert_equal('tom@mojombo.com', c.committer.email) + assert_equal(time.gmtime(1191997100), c.committed_date) + assert_equal('initial grit setup', c.message) + + # test the 'lines per commit' entries + tlist = b[0][1] + assert_true( tlist ) + assert_true( isinstance( tlist[0], basestring ) ) + assert_true( len( tlist ) < sum( len(t) for t in tlist ) ) # test for single-char bug |