diff --git a/include/git2/oid.h b/include/git2/oid.h index f9636d1fc..b9824b887 100644 --- a/include/git2/oid.h +++ b/include/git2/oid.h @@ -149,6 +149,16 @@ GIT_EXTERN(int) git_oid_cmp(const git_oid *a, const git_oid *b); */ GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, unsigned int len); +/** + * Check if an oid equals an hex formatted object id. + * + * @param a oid structure. + * @param str input hex string of an object id. + * @return GIT_ENOTOID if str is not a valid hex string, + * GIT_SUCCESS in case of a match, GIT_ERROR otherwise. + */ +GIT_EXTERN(int) git_oid_streq(const git_oid *a, const char *str); + /** * OID Shortener object */ diff --git a/src/oid.c b/src/oid.c index b47fa2c77..bbf19ea20 100644 --- a/src/oid.c +++ b/src/oid.c @@ -197,6 +197,17 @@ int git_oid_ncmp(const git_oid *oid_a, const git_oid *oid_b, unsigned int len) return 0; } +int git_oid_streq(const git_oid *a, const char *str) +{ + git_oid id; + int error; + + if ((error = git_oid_fromstr(&id, str)) < GIT_SUCCESS) + return git__rethrow(error, "Failed to convert '%s' to oid.", str); + + return git_oid_cmp(a, &id) == 0 ? GIT_SUCCESS : GIT_ERROR; +} + typedef short node_index; typedef union { diff --git a/tests-clay/clay.h b/tests-clay/clay.h index 184635e14..7e653cfcc 100644 --- a/tests-clay/clay.h +++ b/tests-clay/clay.h @@ -57,17 +57,6 @@ void cl_fixture_cleanup(const char *fixture_name); /** * Test method declarations */ -extern void test_status_single__hash_single_file(void); -extern void test_status_worktree__initialize(void); -extern void test_status_worktree__cleanup(void); -extern void test_status_worktree__whole_repository(void); -extern void test_status_worktree__empty_repository(void); -extern void test_network_remotes__initialize(void); -extern void test_network_remotes__cleanup(void); -extern void test_network_remotes__parsing(void); -extern void test_network_remotes__refspec_parsing(void); -extern void test_network_remotes__fnmatch(void); -extern void test_network_remotes__transform(void); extern void test_core_dirent__dont_traverse_dot(void); extern void test_core_dirent__traverse_subfolder(void); extern void test_core_dirent__traverse_slash_terminated_folder(void); @@ -76,6 +65,8 @@ extern void test_core_dirent__traverse_weird_filenames(void); extern void test_core_filebuf__0(void); extern void test_core_filebuf__1(void); extern void test_core_filebuf__2(void); +extern void test_core_oid__initialize(void); +extern void test_core_oid__streq(void); extern void test_core_path__0(void); extern void test_core_path__1(void); extern void test_core_path__2(void); @@ -91,5 +82,16 @@ extern void test_core_strtol__int64(void); extern void test_core_vector__0(void); extern void test_core_vector__1(void); extern void test_core_vector__2(void); +extern void test_network_remotes__initialize(void); +extern void test_network_remotes__cleanup(void); +extern void test_network_remotes__parsing(void); +extern void test_network_remotes__refspec_parsing(void); +extern void test_network_remotes__fnmatch(void); +extern void test_network_remotes__transform(void); +extern void test_status_single__hash_single_file(void); +extern void test_status_worktree__initialize(void); +extern void test_status_worktree__cleanup(void); +extern void test_status_worktree__whole_repository(void); +extern void test_status_worktree__empty_repository(void); #endif diff --git a/tests-clay/clay_main.c b/tests-clay/clay_main.c index cca23f422..dcd9ae842 100644 --- a/tests-clay/clay_main.c +++ b/tests-clay/clay_main.c @@ -660,107 +660,114 @@ cl_fs_cleanup(void) static const struct clay_func _all_callbacks[] = { - {"hash_single_file", &test_status_single__hash_single_file, 0}, - {"whole_repository", &test_status_worktree__whole_repository, 1}, - {"empty_repository", &test_status_worktree__empty_repository, 1}, - {"parsing", &test_network_remotes__parsing, 2}, - {"refspec_parsing", &test_network_remotes__refspec_parsing, 2}, - {"fnmatch", &test_network_remotes__fnmatch, 2}, - {"transform", &test_network_remotes__transform, 2}, - {"dont_traverse_dot", &test_core_dirent__dont_traverse_dot, 3}, - {"traverse_subfolder", &test_core_dirent__traverse_subfolder, 3}, - {"traverse_slash_terminated_folder", &test_core_dirent__traverse_slash_terminated_folder, 3}, - {"dont_traverse_empty_folders", &test_core_dirent__dont_traverse_empty_folders, 3}, - {"traverse_weird_filenames", &test_core_dirent__traverse_weird_filenames, 3}, - {"0", &test_core_filebuf__0, 4}, - {"1", &test_core_filebuf__1, 4}, - {"2", &test_core_filebuf__2, 4}, - {"0", &test_core_path__0, 5}, - {"1", &test_core_path__1, 5}, - {"2", &test_core_path__2, 5}, - {"5", &test_core_path__5, 5}, - {"6", &test_core_path__6, 5}, - {"delete_recursive", &test_core_rmdir__delete_recursive, 6}, - {"fail_to_delete_non_empty_dir", &test_core_rmdir__fail_to_delete_non_empty_dir, 6}, - {"0", &test_core_string__0, 7}, - {"1", &test_core_string__1, 7}, - {"int32", &test_core_strtol__int32, 8}, - {"int64", &test_core_strtol__int64, 8}, - {"0", &test_core_vector__0, 9}, - {"1", &test_core_vector__1, 9}, - {"2", &test_core_vector__2, 9} + {"dont_traverse_dot", &test_core_dirent__dont_traverse_dot, 0}, + {"traverse_subfolder", &test_core_dirent__traverse_subfolder, 0}, + {"traverse_slash_terminated_folder", &test_core_dirent__traverse_slash_terminated_folder, 0}, + {"dont_traverse_empty_folders", &test_core_dirent__dont_traverse_empty_folders, 0}, + {"traverse_weird_filenames", &test_core_dirent__traverse_weird_filenames, 0}, + {"0", &test_core_filebuf__0, 1}, + {"1", &test_core_filebuf__1, 1}, + {"2", &test_core_filebuf__2, 1}, + {"streq", &test_core_oid__streq, 2}, + {"0", &test_core_path__0, 3}, + {"1", &test_core_path__1, 3}, + {"2", &test_core_path__2, 3}, + {"5", &test_core_path__5, 3}, + {"6", &test_core_path__6, 3}, + {"delete_recursive", &test_core_rmdir__delete_recursive, 4}, + {"fail_to_delete_non_empty_dir", &test_core_rmdir__fail_to_delete_non_empty_dir, 4}, + {"0", &test_core_string__0, 5}, + {"1", &test_core_string__1, 5}, + {"int32", &test_core_strtol__int32, 6}, + {"int64", &test_core_strtol__int64, 6}, + {"0", &test_core_vector__0, 7}, + {"1", &test_core_vector__1, 7}, + {"2", &test_core_vector__2, 7}, + {"parsing", &test_network_remotes__parsing, 8}, + {"refspec_parsing", &test_network_remotes__refspec_parsing, 8}, + {"fnmatch", &test_network_remotes__fnmatch, 8}, + {"transform", &test_network_remotes__transform, 8}, + {"hash_single_file", &test_status_single__hash_single_file, 9}, + {"whole_repository", &test_status_worktree__whole_repository, 10}, + {"empty_repository", &test_status_worktree__empty_repository, 10} }; static const struct clay_suite _all_suites[] = { { - "status::single", - {NULL, NULL, 0}, - {NULL, NULL, 0}, - &_all_callbacks[0], 1 - }, - { - "status::worktree", - {"initialize", &test_status_worktree__initialize, 1}, - {"cleanup", &test_status_worktree__cleanup, 1}, - &_all_callbacks[1], 2 - }, - { - "network::remotes", - {"initialize", &test_network_remotes__initialize, 2}, - {"cleanup", &test_network_remotes__cleanup, 2}, - &_all_callbacks[3], 4 - }, - { "core::dirent", {NULL, NULL, 0}, {NULL, NULL, 0}, - &_all_callbacks[7], 5 + &_all_callbacks[0], 5 }, { "core::filebuf", {NULL, NULL, 0}, {NULL, NULL, 0}, - &_all_callbacks[12], 3 + &_all_callbacks[5], 3 + }, + { + "core::oid", + {"initialize", &test_core_oid__initialize, 2}, + {NULL, NULL, 0}, + &_all_callbacks[8], 1 }, { "core::path", {NULL, NULL, 0}, {NULL, NULL, 0}, - &_all_callbacks[15], 5 + &_all_callbacks[9], 5 }, { "core::rmdir", - {"initialize", &test_core_rmdir__initialize, 6}, + {"initialize", &test_core_rmdir__initialize, 4}, {NULL, NULL, 0}, - &_all_callbacks[20], 2 + &_all_callbacks[14], 2 }, { "core::string", {NULL, NULL, 0}, {NULL, NULL, 0}, - &_all_callbacks[22], 2 + &_all_callbacks[16], 2 }, { "core::strtol", {NULL, NULL, 0}, {NULL, NULL, 0}, - &_all_callbacks[24], 2 + &_all_callbacks[18], 2 }, { "core::vector", {NULL, NULL, 0}, {NULL, NULL, 0}, - &_all_callbacks[26], 3 + &_all_callbacks[20], 3 + }, + { + "network::remotes", + {"initialize", &test_network_remotes__initialize, 8}, + {"cleanup", &test_network_remotes__cleanup, 8}, + &_all_callbacks[23], 4 + }, + { + "status::single", + {NULL, NULL, 0}, + {NULL, NULL, 0}, + &_all_callbacks[27], 1 + }, + { + "status::worktree", + {"initialize", &test_status_worktree__initialize, 10}, + {"cleanup", &test_status_worktree__cleanup, 10}, + &_all_callbacks[28], 2 } }; -static const char _suites_str[] = "status::single, status::worktree, network::remotes, core::dirent, core::filebuf, core::path, core::rmdir, core::string, core::strtol, core::vector"; +static const char _suites_str[] = "core::dirent, core::filebuf, core::oid, core::path, core::rmdir, core::string, core::strtol, core::vector, network::remotes, status::single, status::worktree"; int _MAIN_CC main(int argc, char *argv[]) { return clay_test( argc, argv, _suites_str, - _all_callbacks, 29, - _all_suites, 10 + _all_callbacks, 30, + _all_suites, 11 ); } diff --git a/tests-clay/core/oid.c b/tests-clay/core/oid.c new file mode 100644 index 000000000..44597c5ae --- /dev/null +++ b/tests-clay/core/oid.c @@ -0,0 +1,18 @@ +#include "clay_libgit2.h" + +static git_oid id; +const char *str_oid = "ae90f12eea699729ed24555e40b9fd669da12a12"; + +void test_core_oid__initialize(void) +{ + cl_git_pass(git_oid_fromstr(&id, str_oid)); +} + +void test_core_oid__streq(void) +{ + cl_assert(git_oid_streq(&id, str_oid) == GIT_SUCCESS); + cl_assert(git_oid_streq(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") == GIT_ERROR); + + cl_assert(git_oid_streq(&id, "deadbeef") == GIT_ENOTOID); + cl_assert(git_oid_streq(&id, "I'm not an oid.... :)") == GIT_ENOTOID); +} \ No newline at end of file