summaryrefslogtreecommitdiff
path: root/tests-clar/diff/tree.c
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2012-09-13 13:17:38 -0700
committerRussell Belfer <rb@github.com>2012-09-13 13:17:38 -0700
commit49d34c1c0c706eea09380b2165bb3ad4e506dc30 (patch)
treec5fa356a6e5836bce911d4ab893ebabdd6453a6a /tests-clar/diff/tree.c
parent9be2261eaae74552aaa9d568e663292f4382e141 (diff)
downloadlibgit2-49d34c1c0c706eea09380b2165bb3ad4e506dc30.tar.gz
Fix problems in diff iterator record chaining
There is a bug in building the linked list of line records in the diff iterator and also an off by one element error in the hunk counts. This fixes both of these, adds some test data with more complex sets of hunk and line diffs to exercise this code better.
Diffstat (limited to 'tests-clar/diff/tree.c')
-rw-r--r--tests-clar/diff/tree.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/tests-clar/diff/tree.c b/tests-clar/diff/tree.c
index 3003374a5..f5e72cadc 100644
--- a/tests-clar/diff/tree.c
+++ b/tests-clar/diff/tree.c
@@ -256,3 +256,85 @@ void test_diff_tree__merge(void)
git_diff_list_free(diff1);
}
+
+void test_diff_tree__larger_hunks(void)
+{
+ const char *a_commit = "d70d245ed97ed2aa596dd1af6536e4bfdb047b69";
+ const char *b_commit = "7a9e0b02e63179929fed24f0a3e0f19168114d10";
+ git_tree *a, *b;
+ git_diff_options opts = {0};
+ git_diff_list *diff = NULL;
+ git_diff_iterator *iter = NULL;
+ git_diff_delta *delta;
+ diff_expects exp;
+ int error, num_files = 0;
+
+ g_repo = cl_git_sandbox_init("diff");
+
+ cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
+ cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);
+
+ opts.context_lines = 1;
+ opts.interhunk_lines = 0;
+
+ memset(&exp, 0, sizeof(exp));
+
+ cl_git_pass(git_diff_tree_to_tree(g_repo, &opts, a, b, &diff));
+ cl_git_pass(git_diff_iterator_new(&iter, diff));
+
+ /* this should be exact */
+ cl_assert(git_diff_iterator_progress(iter) == 0.0f);
+
+ /* You wouldn't actually structure an iterator loop this way, but
+ * I have here for testing purposes of the return value
+ */
+ while (!(error = git_diff_iterator_next_file(&delta, iter))) {
+ git_diff_range *range;
+ const char *header;
+ size_t header_len;
+ int actual_hunks = 0, num_hunks;
+ float expected_progress;
+
+ num_files++;
+
+ expected_progress = (float)num_files / 2.0f;
+ cl_assert(expected_progress == git_diff_iterator_progress(iter));
+
+ num_hunks = git_diff_iterator_num_hunks_in_file(iter);
+
+ while (!(error = git_diff_iterator_next_hunk(
+ &range, &header, &header_len, iter)))
+ {
+ int actual_lines = 0;
+ int num_lines = git_diff_iterator_num_lines_in_hunk(iter);
+ char origin;
+ const char *line;
+ size_t line_len;
+
+ while (!(error = git_diff_iterator_next_line(
+ &origin, &line, &line_len, iter)))
+ {
+ actual_lines++;
+ }
+
+ cl_assert_equal_i(GIT_ITEROVER, error);
+ cl_assert_equal_i(actual_lines, num_lines);
+
+ actual_hunks++;
+ }
+
+ cl_assert_equal_i(GIT_ITEROVER, error);
+ cl_assert_equal_i(actual_hunks, num_hunks);
+ }
+
+ cl_assert_equal_i(GIT_ITEROVER, error);
+ cl_assert_equal_i(2, num_files);
+ cl_assert(git_diff_iterator_progress(iter) == 1.0f);
+
+ git_diff_iterator_free(iter);
+ git_diff_list_free(diff);
+ diff = NULL;
+
+ git_tree_free(a);
+ git_tree_free(b);
+}