| #include "clar_libgit2.h" |
| #include "diff_helpers.h" |
| |
| static git_repository *g_repo = NULL; |
| |
| void test_diff_notify__initialize(void) |
| { |
| } |
| |
| void test_diff_notify__cleanup(void) |
| { |
| cl_git_sandbox_cleanup(); |
| } |
| |
| static int assert_called_notifications( |
| const git_diff *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; |
| } |
| |
| static void test_notify( |
| char **searched_pathspecs, |
| int pathspecs_count, |
| notify_expected *expected_matched_pathspecs, |
| int expected_diffed_files_count) |
| { |
| git_diff_options opts = GIT_DIFF_OPTIONS_INIT; |
| git_diff *diff = NULL; |
| diff_expects exp; |
| |
| 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; |
| opts.pathspec.count = pathspecs_count; |
| |
| opts.payload = expected_matched_pathspecs; |
| 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, NULL, &exp)); |
| |
| cl_assert_equal_i(expected_diffed_files_count, exp.files); |
| |
| git_diff_free(diff); |
| } |
| |
| void test_diff_notify__notify_single_pathspec(void) |
| { |
| char *searched_pathspecs[] = { |
| "*_deleted", |
| }; |
| notify_expected expected_matched_pathspecs[] = { |
| { "file_deleted", "*_deleted" }, |
| { "staged_changes_file_deleted", "*_deleted" }, |
| { NULL, NULL } |
| }; |
| |
| test_notify(searched_pathspecs, 1, expected_matched_pathspecs, 2); |
| } |
| |
| void test_diff_notify__notify_multiple_pathspec(void) |
| { |
| char *searched_pathspecs[] = { |
| "staged_changes_cant_find_me", |
| "subdir/modified_cant_find_me", |
| "subdir/*", |
| "staged*" |
| }; |
| notify_expected expected_matched_pathspecs[] = { |
| { "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 } |
| }; |
| |
| test_notify(searched_pathspecs, 4, expected_matched_pathspecs, 8); |
| } |
| |
| void test_diff_notify__notify_catchall_with_empty_pathspecs(void) |
| { |
| char *searched_pathspecs[] = { |
| "", |
| "" |
| }; |
| notify_expected expected_matched_pathspecs[] = { |
| { "file_deleted", NULL }, |
| { "ignored_file", NULL }, |
| { "modified_file", NULL }, |
| { "new_file", NULL }, |
| { "\xe8\xbf\x99", NULL }, |
| { "staged_changes_file_deleted", NULL }, |
| { "staged_changes_modified_file", NULL }, |
| { "staged_delete_modified_file", NULL }, |
| { "staged_new_file_deleted_file", NULL }, |
| { "staged_new_file_modified_file", NULL }, |
| { "subdir/deleted_file", NULL }, |
| { "subdir/modified_file", NULL }, |
| { "subdir/new_file", NULL }, |
| { NULL, NULL } |
| }; |
| |
| test_notify(searched_pathspecs, 1, expected_matched_pathspecs, 13); |
| } |
| |
| void test_diff_notify__notify_catchall(void) |
| { |
| char *searched_pathspecs[] = { |
| "*", |
| }; |
| notify_expected expected_matched_pathspecs[] = { |
| { "file_deleted", "*" }, |
| { "ignored_file", "*" }, |
| { "modified_file", "*" }, |
| { "new_file", "*" }, |
| { "\xe8\xbf\x99", "*" }, |
| { "staged_changes_file_deleted", "*" }, |
| { "staged_changes_modified_file", "*" }, |
| { "staged_delete_modified_file", "*" }, |
| { "staged_new_file_deleted_file", "*" }, |
| { "staged_new_file_modified_file", "*" }, |
| { "subdir/deleted_file", "*" }, |
| { "subdir/modified_file", "*" }, |
| { "subdir/new_file", "*" }, |
| { NULL, NULL } |
| }; |
| |
| test_notify(searched_pathspecs, 1, expected_matched_pathspecs, 13); |
| } |
| |
| static int abort_diff( |
| const git_diff *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_notify__notify_cb_can_abort_diff(void) |
| { |
| git_diff_options opts = GIT_DIFF_OPTIONS_INIT; |
| git_diff *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_with( |
| git_diff_index_to_workdir(&diff, g_repo, NULL, &opts), -42); |
| |
| pathspec = "staged_changes_modified_file"; |
| cl_git_fail_with( |
| git_diff_index_to_workdir(&diff, g_repo, NULL, &opts), -42); |
| } |
| |
| static int filter_all( |
| const git_diff *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_notify__notify_cb_can_be_used_as_filtering_function(void) |
| { |
| git_diff_options opts = GIT_DIFF_OPTIONS_INIT; |
| git_diff *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, NULL, &exp)); |
| |
| cl_assert_equal_i(0, exp.files); |
| |
| git_diff_free(diff); |
| } |
| |
| static int progress_abort_diff( |
| const git_diff *diff_so_far, |
| const char *old_path, |
| const char *new_path, |
| void *payload) |
| { |
| GIT_UNUSED(diff_so_far); |
| GIT_UNUSED(old_path); |
| GIT_UNUSED(new_path); |
| GIT_UNUSED(payload); |
| |
| return -42; |
| } |
| |
| void test_diff_notify__progress_cb_can_abort_diff(void) |
| { |
| git_diff_options opts = GIT_DIFF_OPTIONS_INIT; |
| git_diff *diff = NULL; |
| |
| g_repo = cl_git_sandbox_init("status"); |
| |
| opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED; |
| opts.progress_cb = progress_abort_diff; |
| |
| cl_git_fail_with( |
| git_diff_index_to_workdir(&diff, g_repo, NULL, &opts), -42); |
| } |