fix blame argument handling

The argument handling for the new Repository_blame had several problems:

- The call to PyArg_ParseTupleAndKeywords was missing &path, so none
  of the optional arguments got parsed correctly.
- newest_commit and oldest_commit were missing type validation
  against OidType.
- The opts structure was discarded rather than passed to git_blame_file.

This commit fixes these issues and adds a test case.
This commit is contained in:
Adam Spiers 2013-12-09 11:42:13 +00:00
parent 82ac7c83af
commit 749810ac77
2 changed files with 33 additions and 4 deletions

@ -46,6 +46,7 @@ extern PyTypeObject IndexType;
extern PyTypeObject WalkerType;
extern PyTypeObject SignatureType;
extern PyTypeObject ObjectType;
extern PyTypeObject OidType;
extern PyTypeObject CommitType;
extern PyTypeObject TreeType;
extern PyTypeObject TreeBuilderType;
@ -1477,13 +1478,14 @@ Repository_blame(Repository *self, PyObject *args, PyObject *kwds)
PyObject *value1 = NULL;
PyObject *value2 = NULL;
int err;
char *keywords[] = {"flags", "min_match_characters", "newest_commit",
char *keywords[] = {"path", "flags", "min_match_characters", "newest_commit",
"oldest_commit", "min_line", "max_line", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|IHOOII", keywords,
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|IHO!O!II", keywords,
&path, &opts.flags,
&opts.min_match_characters,
&value1, &value2,
&OidType, &value1,
&OidType, &value2,
&opts.min_line, &opts.max_line))
return NULL;
@ -1498,7 +1500,7 @@ Repository_blame(Repository *self, PyObject *args, PyObject *kwds)
return NULL;
}
err = git_blame_file(&blame, self->repo, path, NULL);
err = git_blame_file(&blame, self->repo, path, &opts);
if (err < 0)
return Error_set(err);

@ -111,5 +111,32 @@ class BlameTest(utils.RepoTestCase):
self.assertRaises(IndexError, test)
def test_blame_newest(self):
repo = self.repo
revs = [
( 'master^2', 3 ),
( 'master^2^', 2 ),
( 'master^2^^', 1 ),
]
for rev, num_commits in revs:
commit = repo.revparse_single(rev)
blame = repo.blame(PATH, newest_commit=commit.oid)
self.assertEqual(len(blame), num_commits)
for i, hunk in enumerate(tuple(blame)[:num_commits]):
self.assertEqual(hunk.lines_in_hunk, 1)
self.assertEqual(HUNKS[i][0], hunk.final_commit_id)
self.assertEqual(HUNKS[i][1], hunk.final_start_line_number)
self.assertEqualSignature(HUNKS[i][2], hunk.final_committer)
self.assertEqual(hunk.orig_commit_id,
'0000000000000000000000000000000000000000')
self.assertEqual(hunk.orig_path, PATH)
self.assertEqual(HUNKS[i][1], hunk.orig_start_line_number)
self.assertTrue(hunk.orig_committer is None)
self.assertEqual(HUNKS[i][3], hunk.boundary)
if __name__ == '__main__':
unittest.main()