summaryrefslogtreecommitdiff
path: root/tests-clar/diff/workdir.c
diff options
context:
space:
mode:
authoryorah <yoram.harmelin@gmail.com>2013-01-25 17:35:46 +0100
committeryorah <yoram.harmelin@gmail.com>2013-02-07 20:44:35 +0100
commit0d64ba48372f95ade17a27f1b11620638ca52d61 (patch)
treec713abaeb7e3629e221c09f4c9338e0878006e98 /tests-clar/diff/workdir.c
parent943700ecbbc2be4ef49c5c31d8e5c49353fd3d84 (diff)
downloadlibgit2-0d64ba48372f95ade17a27f1b11620638ca52d61.tar.gz
diff: add a notify callback to `git_diff__from_iterators`
The callback will be called for each file, just before the `git_delta_t` gets inserted into the diff list. When the callback: - returns < 0, the diff process will be aborted - returns > 0, the delta will not be inserted into the diff list, but the diff process continues - returns 0, the delta is inserted into the diff list, and the diff process continues
Diffstat (limited to 'tests-clar/diff/workdir.c')
-rw-r--r--tests-clar/diff/workdir.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/tests-clar/diff/workdir.c b/tests-clar/diff/workdir.c
index 21da63954..7e8915c4b 100644
--- a/tests-clar/diff/workdir.c
+++ b/tests-clar/diff/workdir.c
@@ -307,6 +307,169 @@ void test_diff_workdir__to_index_with_pathspec(void)
git_diff_list_free(diff);
}
+static int assert_called_notifications(
+ const git_diff_list *diff_so_far,
+ const git_diff_delta *delta_to_add,
+ const char *matched_pathspec,
+ void *payload)
+{
+ bool found = false;
+ notify_expected *exp = (notify_expected*)payload;
+ notify_expected *e;;
+
+ GIT_UNUSED(diff_so_far);
+
+ for (e = exp; e->path != NULL; e++) {
+ if (strcmp(e->path, delta_to_add->new_file.path))
+ continue;
+
+ cl_assert_equal_s(e->matched_pathspec, matched_pathspec);
+
+ found = true;
+ break;
+ }
+
+ cl_assert(found);
+ return 0;
+}
+
+void test_diff_workdir__to_index_notify(void)
+{
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+ git_diff_list *diff = NULL;
+ diff_expects exp;
+
+ char *searched_pathspecs_solo[] = {
+ "*_deleted",
+ };
+ notify_expected expected_matched_pathspecs_solo[] = {
+ { "file_deleted", "*_deleted" },
+ { "staged_changes_file_deleted", "*_deleted" },
+ { NULL, NULL }
+ };
+
+ char *searched_pathspecs_multiple[] = {
+ "staged_changes_cant_find_me",
+ "subdir/modified_cant_find_me",
+ "subdir/*",
+ "staged*"
+ };
+ notify_expected expected_matched_pathspecs_multiple[] = {
+ { "staged_changes_file_deleted", "staged*" },
+ { "staged_changes_modified_file", "staged*" },
+ { "staged_delete_modified_file", "staged*" },
+ { "staged_new_file_deleted_file", "staged*" },
+ { "staged_new_file_modified_file", "staged*" },
+ { "subdir/deleted_file", "subdir/*" },
+ { "subdir/modified_file", "subdir/*" },
+ { "subdir/new_file", "subdir/*" },
+ { NULL, NULL }
+ };
+
+ g_repo = cl_git_sandbox_init("status");
+
+ opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+ opts.notify_cb = assert_called_notifications;
+ opts.pathspec.strings = searched_pathspecs_solo;
+ opts.pathspec.count = 1;
+
+ opts.notify_payload = &expected_matched_pathspecs_solo;
+ memset(&exp, 0, sizeof(exp));
+
+ cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+ cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, &exp));
+
+ cl_assert_equal_i(2, exp.files);
+
+ git_diff_list_free(diff);
+
+ opts.pathspec.strings = searched_pathspecs_multiple;
+ opts.pathspec.count = 4;
+ opts.notify_payload = &expected_matched_pathspecs_multiple;
+ memset(&exp, 0, sizeof(exp));
+
+ cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+ cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, &exp));
+
+ cl_assert_equal_i(8, exp.files);
+
+ git_diff_list_free(diff);
+}
+
+static int abort_diff(
+ const git_diff_list *diff_so_far,
+ const git_diff_delta *delta_to_add,
+ const char *matched_pathspec,
+ void *payload)
+{
+ GIT_UNUSED(diff_so_far);
+ GIT_UNUSED(delta_to_add);
+ GIT_UNUSED(matched_pathspec);
+ GIT_UNUSED(payload);
+
+ return -42;
+}
+
+void test_diff_workdir__to_index_notify_can_be_aborted_by_callback(void)
+{
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+ git_diff_list *diff = NULL;
+ char *pathspec = NULL;
+
+ g_repo = cl_git_sandbox_init("status");
+
+ opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+ opts.notify_cb = abort_diff;
+ opts.pathspec.strings = &pathspec;
+ opts.pathspec.count = 1;
+
+ pathspec = "file_deleted";
+ cl_git_fail(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+ pathspec = "staged_changes_modified_file";
+ cl_git_fail(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+}
+
+static int filter_all(
+ const git_diff_list *diff_so_far,
+ const git_diff_delta *delta_to_add,
+ const char *matched_pathspec,
+ void *payload)
+{
+ GIT_UNUSED(diff_so_far);
+ GIT_UNUSED(delta_to_add);
+ GIT_UNUSED(matched_pathspec);
+ GIT_UNUSED(payload);
+
+ return 42;
+}
+
+void test_diff_workdir__to_index_notify_can_be_used_as_filtering_function(void)
+{
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+ git_diff_list *diff = NULL;
+ char *pathspec = NULL;
+ diff_expects exp;
+
+ g_repo = cl_git_sandbox_init("status");
+
+ opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+ opts.notify_cb = filter_all;
+ opts.pathspec.strings = &pathspec;
+ opts.pathspec.count = 1;
+
+ pathspec = "*_deleted";
+ memset(&exp, 0, sizeof(exp));
+
+ cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+ cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, &exp));
+
+ cl_assert_equal_i(0, exp.files);
+
+ git_diff_list_free(diff);
+}
+
+
void test_diff_workdir__filemode_changes(void)
{
git_config *cfg;