mirror of
				https://git.proxmox.com/git/libgit2
				synced 2025-10-31 16:19:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			229 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			229 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #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_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;
 | |
| }
 | |
| 
 | |
| 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_list *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.notify_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, &exp));
 | |
| 
 | |
| 	cl_assert_equal_i(expected_diffed_files_count, exp.files);
 | |
| 
 | |
| 	git_diff_list_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_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_notify__notify_cb_can_abort_diff(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_notify__notify_cb_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);
 | |
| }
 | 
