diff options
Diffstat (limited to 'tests-clar/object')
-rw-r--r-- | tests-clar/object/blob/filter.c | 39 | ||||
-rw-r--r-- | tests-clar/object/blob/fromchunks.c | 87 | ||||
-rw-r--r-- | tests-clar/object/blob/write.c | 6 | ||||
-rw-r--r-- | tests-clar/object/commit/commitstagedfile.c | 16 | ||||
-rw-r--r-- | tests-clar/object/lookup.c | 4 | ||||
-rw-r--r-- | tests-clar/object/message.c | 67 | ||||
-rw-r--r-- | tests-clar/object/peel.c | 110 | ||||
-rw-r--r-- | tests-clar/object/raw/convert.c | 4 | ||||
-rw-r--r-- | tests-clar/object/raw/hash.c | 152 | ||||
-rw-r--r-- | tests-clar/object/raw/short.c | 2 | ||||
-rw-r--r-- | tests-clar/object/tag/list.c | 115 | ||||
-rw-r--r-- | tests-clar/object/tag/peel.c | 5 | ||||
-rw-r--r-- | tests-clar/object/tag/read.c | 170 | ||||
-rw-r--r-- | tests-clar/object/tag/write.c | 48 | ||||
-rw-r--r-- | tests-clar/object/tree/attributes.c | 114 | ||||
-rw-r--r-- | tests-clar/object/tree/duplicateentries.c | 157 | ||||
-rw-r--r-- | tests-clar/object/tree/frompath.c | 79 | ||||
-rw-r--r-- | tests-clar/object/tree/walk.c | 103 | ||||
-rw-r--r-- | tests-clar/object/tree/write.c | 190 |
19 files changed, 1223 insertions, 245 deletions
diff --git a/tests-clar/object/blob/filter.c b/tests-clar/object/blob/filter.c index 0b87b2b46..042bddab7 100644 --- a/tests-clar/object/blob/filter.c +++ b/tests-clar/object/blob/filter.c @@ -2,9 +2,10 @@ #include "posix.h" #include "blob.h" #include "filter.h" +#include "buf_text.h" static git_repository *g_repo = NULL; -#define NUM_TEST_OBJECTS 6 +#define NUM_TEST_OBJECTS 8 static git_oid g_oids[NUM_TEST_OBJECTS]; static const char *g_raw[NUM_TEST_OBJECTS] = { "", @@ -12,16 +13,20 @@ static const char *g_raw[NUM_TEST_OBJECTS] = { "foo\rbar\r", "foo\r\nbar\r\n", "foo\nbar\rboth\r\nreversed\n\ragain\nproblems\r", - "123\n\000\001\002\003\004abc\255\254\253\r\n" + "123\n\000\001\002\003\004abc\255\254\253\r\n", + "\xEF\xBB\xBFThis is UTF-8\n", + "\xFE\xFF\x00T\x00h\x00i\x00s\x00!" }; -static int g_len[NUM_TEST_OBJECTS] = { -1, -1, -1, -1, -1, 17 }; -static git_text_stats g_stats[NUM_TEST_OBJECTS] = { - { 0, 0, 0, 0, 0, 0 }, - { 0, 0, 2, 0, 6, 0 }, - { 0, 2, 0, 0, 6, 0 }, - { 0, 2, 2, 2, 6, 0 }, - { 0, 4, 4, 1, 31, 0 }, - { 1, 1, 2, 1, 9, 5 } +static git_off_t g_len[NUM_TEST_OBJECTS] = { -1, -1, -1, -1, -1, 17, -1, 12 }; +static git_buf_text_stats g_stats[NUM_TEST_OBJECTS] = { + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 2, 0, 6, 0 }, + { 0, 0, 2, 0, 0, 6, 0 }, + { 0, 0, 2, 2, 2, 6, 0 }, + { 0, 0, 4, 4, 1, 31, 0 }, + { 0, 1, 1, 2, 1, 9, 5 }, + { GIT_BOM_UTF8, 0, 0, 1, 0, 16, 0 }, + { GIT_BOM_UTF16_BE, 5, 0, 0, 0, 7, 5 }, }; static git_buf g_crlf_filtered[NUM_TEST_OBJECTS] = { { "", 0, 0 }, @@ -29,7 +34,9 @@ static git_buf g_crlf_filtered[NUM_TEST_OBJECTS] = { { "foo\rbar\r", 0, 8 }, { "foo\nbar\n", 0, 8 }, { "foo\nbar\rboth\nreversed\n\ragain\nproblems\r", 0, 38 }, - { "123\n\000\001\002\003\004abc\255\254\253\n", 0, 16 } + { "123\n\000\001\002\003\004abc\255\254\253\n", 0, 16 }, + { "\xEF\xBB\xBFThis is UTF-8\n", 0, 17 }, + { "\xFE\xFF\x00T\x00h\x00i\x00s\x00!", 0, 12 } }; void test_object_blob_filter__initialize(void) @@ -43,7 +50,7 @@ void test_object_blob_filter__initialize(void) for (i = 0; i < NUM_TEST_OBJECTS; i++) { size_t len = (g_len[i] < 0) ? strlen(g_raw[i]) : (size_t)g_len[i]; - g_len[i] = (int)len; + g_len[i] = (git_off_t)len; cl_git_pass( git_blob_create_frombuffer(&g_oids[i], g_repo, g_raw[i], len) @@ -65,8 +72,8 @@ void test_object_blob_filter__unfiltered(void) for (i = 0; i < NUM_TEST_OBJECTS; i++) { cl_git_pass(git_blob_lookup(&blob, g_repo, &g_oids[i])); - cl_assert((size_t)g_len[i] == git_blob_rawsize(blob)); - cl_assert(memcmp(git_blob_rawcontent(blob), g_raw[i], g_len[i]) == 0); + cl_assert(g_len[i] == git_blob_rawsize(blob)); + cl_assert(memcmp(git_blob_rawcontent(blob), g_raw[i], (size_t)g_len[i]) == 0); git_blob_free(blob); } } @@ -76,12 +83,12 @@ void test_object_blob_filter__stats(void) int i; git_blob *blob; git_buf buf = GIT_BUF_INIT; - git_text_stats stats; + git_buf_text_stats stats; for (i = 0; i < NUM_TEST_OBJECTS; i++) { cl_git_pass(git_blob_lookup(&blob, g_repo, &g_oids[i])); cl_git_pass(git_blob__getbuf(&buf, blob)); - git_text_gather_stats(&stats, &buf); + git_buf_text_gather_stats(&stats, &buf, false); cl_assert(memcmp(&g_stats[i], &stats, sizeof(stats)) == 0); git_blob_free(blob); } diff --git a/tests-clar/object/blob/fromchunks.c b/tests-clar/object/blob/fromchunks.c new file mode 100644 index 000000000..dc57d4fbe --- /dev/null +++ b/tests-clar/object/blob/fromchunks.c @@ -0,0 +1,87 @@ +#include "clar_libgit2.h" +#include "buffer.h" +#include "posix.h" +#include "path.h" +#include "fileops.h" + +static git_repository *repo; +static char textual_content[] = "libgit2\n\r\n\0"; + +void test_object_blob_fromchunks__initialize(void) +{ + repo = cl_git_sandbox_init("testrepo.git"); +} + +void test_object_blob_fromchunks__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +static int text_chunked_source_cb(char *content, size_t max_length, void *payload) +{ + int *count; + + GIT_UNUSED(max_length); + + count = (int *)payload; + (*count)--; + + if (*count == 0) + return 0; + + strcpy(content, textual_content); + return (int)strlen(textual_content); +} + +void test_object_blob_fromchunks__can_create_a_blob_from_a_in_memory_chunk_provider(void) +{ + git_oid expected_oid, oid; + git_object *blob; + int howmany = 7; + + cl_git_pass(git_oid_fromstr(&expected_oid, "321cbdf08803c744082332332838df6bd160f8f9")); + + cl_git_fail(git_object_lookup(&blob, repo, &expected_oid, GIT_OBJ_ANY)); + + cl_git_pass(git_blob_create_fromchunks(&oid, repo, NULL, text_chunked_source_cb, &howmany)); + + cl_git_pass(git_object_lookup(&blob, repo, &expected_oid, GIT_OBJ_ANY)); + git_object_free(blob); +} + +#define GITATTR "* text=auto\n" \ + "*.txt text\n" \ + "*.data binary\n" + +static void write_attributes(git_repository *repo) +{ + git_buf buf = GIT_BUF_INIT; + + cl_git_pass(git_buf_joinpath(&buf, git_repository_path(repo), "info")); + cl_git_pass(git_buf_joinpath(&buf, git_buf_cstr(&buf), "attributes")); + + cl_git_pass(git_futils_mkpath2file(git_buf_cstr(&buf), 0777)); + cl_git_rewritefile(git_buf_cstr(&buf), GITATTR); + + git_buf_free(&buf); +} + +static void assert_named_chunked_blob(const char *expected_sha, const char *fake_name) +{ + git_oid expected_oid, oid; + int howmany = 7; + + cl_git_pass(git_oid_fromstr(&expected_oid, expected_sha)); + + cl_git_pass(git_blob_create_fromchunks(&oid, repo, fake_name, text_chunked_source_cb, &howmany)); + cl_assert(git_oid_cmp(&expected_oid, &oid) == 0); +} + +void test_object_blob_fromchunks__creating_a_blob_from_chunks_honors_the_attributes_directives(void) +{ + write_attributes(repo); + + assert_named_chunked_blob("321cbdf08803c744082332332838df6bd160f8f9", "dummy.data"); + assert_named_chunked_blob("e9671e138a780833cb689753570fd10a55be84fb", "dummy.txt"); + assert_named_chunked_blob("e9671e138a780833cb689753570fd10a55be84fb", "dummy.dunno"); +} diff --git a/tests-clar/object/blob/write.c b/tests-clar/object/blob/write.c index 722c7b956..203bc67c1 100644 --- a/tests-clar/object/blob/write.c +++ b/tests-clar/object/blob/write.c @@ -33,7 +33,7 @@ void test_object_blob_write__can_create_a_blob_in_a_standard_repo_from_a_file_lo { repo = cl_git_sandbox_init(WORKDIR); - assert_blob_creation(WORKDIR "/test.txt", "test.txt", &git_blob_create_fromfile); + assert_blob_creation(WORKDIR "/test.txt", "test.txt", &git_blob_create_fromworkdir); } void test_object_blob_write__can_create_a_blob_in_a_standard_repo_from_a_absolute_filepath_pointing_outside_of_the_working_directory(void) @@ -49,7 +49,7 @@ void test_object_blob_write__can_create_a_blob_in_a_standard_repo_from_a_absolut assert_blob_creation(ELSEWHERE "/test.txt", git_buf_cstr(&full_path), &git_blob_create_fromdisk); git_buf_free(&full_path); - cl_must_pass(git_futils_rmdir_r(ELSEWHERE, GIT_DIRREMOVAL_FILES_AND_DIRS)); + cl_must_pass(git_futils_rmdir_r(ELSEWHERE, NULL, GIT_RMDIR_REMOVE_FILES)); } void test_object_blob_write__can_create_a_blob_in_a_bare_repo_from_a_absolute_filepath(void) @@ -65,5 +65,5 @@ void test_object_blob_write__can_create_a_blob_in_a_bare_repo_from_a_absolute_fi assert_blob_creation(ELSEWHERE "/test.txt", git_buf_cstr(&full_path), &git_blob_create_fromdisk); git_buf_free(&full_path); - cl_must_pass(git_futils_rmdir_r(ELSEWHERE, GIT_DIRREMOVAL_FILES_AND_DIRS)); + cl_must_pass(git_futils_rmdir_r(ELSEWHERE, NULL, GIT_RMDIR_REMOVE_FILES)); } diff --git a/tests-clar/object/commit/commitstagedfile.c b/tests-clar/object/commit/commitstagedfile.c index a852458f4..9867ab418 100644 --- a/tests-clar/object/commit/commitstagedfile.c +++ b/tests-clar/object/commit/commitstagedfile.c @@ -13,16 +13,19 @@ void test_object_commit_commitstagedfile__initialize(void) void test_object_commit_commitstagedfile__cleanup(void) { git_repository_free(repo); + repo = NULL; + cl_fixture_cleanup("treebuilder"); } void test_object_commit_commitstagedfile__generate_predictable_object_ids(void) { git_index *index; - git_index_entry *entry; + const git_index_entry *entry; git_oid expected_blob_oid, tree_oid, expected_tree_oid, commit_oid, expected_commit_oid; git_signature *signature; git_tree *tree; + char buffer[128]; /* * The test below replicates the following git scenario @@ -70,9 +73,9 @@ void test_object_commit_commitstagedfile__generate_predictable_object_ids(void) */ cl_git_mkfile("treebuilder/test.txt", "test\n"); cl_git_pass(git_repository_index(&index, repo)); - cl_git_pass(git_index_add(index, "test.txt", 0)); + cl_git_pass(git_index_add_bypath(index, "test.txt")); - entry = git_index_get(index, 0); + entry = git_index_get_byindex(index, 0); cl_assert(git_oid_cmp(&expected_blob_oid, &entry->oid) == 0); @@ -98,7 +101,7 @@ void test_object_commit_commitstagedfile__generate_predictable_object_ids(void) /* * Build the tree from the index */ - cl_git_pass(git_tree_create_fromindex(&tree_oid, index)); + cl_git_pass(git_index_write_tree(&tree_oid, index)); cl_assert(git_oid_cmp(&expected_tree_oid, &tree_oid) == 0); @@ -107,6 +110,9 @@ void test_object_commit_commitstagedfile__generate_predictable_object_ids(void) */ cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas@gmail.com", 1323847743, 60)); cl_git_pass(git_tree_lookup(&tree, repo, &tree_oid)); + + cl_assert_equal_i(16, git_message_prettify(buffer, 128, "Initial commit", 0)); + cl_git_pass(git_commit_create_v( &commit_oid, repo, @@ -114,7 +120,7 @@ void test_object_commit_commitstagedfile__generate_predictable_object_ids(void) signature, signature, NULL, - "Initial commit", + buffer, tree, 0)); diff --git a/tests-clar/object/lookup.c b/tests-clar/object/lookup.c index 7cbcc6140..cfa6d4678 100644 --- a/tests-clar/object/lookup.c +++ b/tests-clar/object/lookup.c @@ -11,7 +11,8 @@ void test_object_lookup__initialize(void) void test_object_lookup__cleanup(void) { - git_repository_free(g_repo); + git_repository_free(g_repo); + g_repo = NULL; } void test_object_lookup__lookup_wrong_type_returns_enotfound(void) @@ -61,3 +62,4 @@ void test_object_lookup__lookup_wrong_type_eventually_returns_enotfound(void) cl_assert_equal_i( GIT_ENOTFOUND, git_object_lookup(&object, g_repo, &oid, GIT_OBJ_TAG)); } + diff --git a/tests-clar/object/message.c b/tests-clar/object/message.c index cbdc80a64..7ef6374b3 100644 --- a/tests-clar/object/message.c +++ b/tests-clar/object/message.c @@ -6,7 +6,7 @@ static void assert_message_prettifying(char *expected_output, char *input, int s { git_buf prettified_message = GIT_BUF_INIT; - git_message_prettify(&prettified_message, input, strip_comments); + git_message__prettify(&prettified_message, input, strip_comments); cl_assert_equal_s(expected_output, git_buf_cstr(&prettified_message)); git_buf_free(&prettified_message); @@ -169,3 +169,68 @@ void test_object_message__keep_comments(void) assert_message_prettifying("# comment\n" ttt "\n", "# comment\n" ttt "\n", 0); assert_message_prettifying(ttt "\n" "# comment\n" ttt "\n", ttt "\n" "# comment\n" ttt "\n", 0); } + +void test_object_message__message_prettify(void) +{ + char buffer[100]; + + cl_assert(git_message_prettify(buffer, sizeof(buffer), "", 0) == 1); + cl_assert_equal_s(buffer, ""); + cl_assert(git_message_prettify(buffer, sizeof(buffer), "", 1) == 1); + cl_assert_equal_s(buffer, ""); + + cl_assert_equal_i(7, git_message_prettify(buffer, sizeof(buffer), "Short", 0)); + cl_assert_equal_s("Short\n", buffer); + cl_assert_equal_i(7, git_message_prettify(buffer, sizeof(buffer), "Short", 1)); + cl_assert_equal_s("Short\n", buffer); + + cl_assert(git_message_prettify(buffer, sizeof(buffer), "This is longer\nAnd multiline\n# with some comments still in\n", 0) > 0); + cl_assert_equal_s(buffer, "This is longer\nAnd multiline\n# with some comments still in\n"); + + cl_assert(git_message_prettify(buffer, sizeof(buffer), "This is longer\nAnd multiline\n# with some comments still in\n", 1) > 0); + cl_assert_equal_s(buffer, "This is longer\nAnd multiline\n"); + + /* try out overflow */ + cl_assert(git_message_prettify(buffer, sizeof(buffer), + "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" + "1234567890" "1234567890" "1234567890" "1234567890" "12345678", + 0) > 0); + cl_assert_equal_s(buffer, + "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" + "1234567890" "1234567890" "1234567890" "1234567890" "12345678\n"); + + cl_assert(git_message_prettify(buffer, sizeof(buffer), + "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" + "1234567890" "1234567890" "1234567890" "1234567890" "12345678\n", + 0) > 0); + cl_assert_equal_s(buffer, + "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" + "1234567890" "1234567890" "1234567890" "1234567890" "12345678\n"); + + cl_git_fail(git_message_prettify(buffer, sizeof(buffer), + "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" + "1234567890" "1234567890" "1234567890" "1234567890" "123456789", + 0)); + cl_git_fail(git_message_prettify(buffer, sizeof(buffer), + "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" + "1234567890" "1234567890" "1234567890" "1234567890" "123456789\n", + 0)); + cl_git_fail(git_message_prettify(buffer, sizeof(buffer), + "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" + "1234567890" "1234567890" "1234567890" "1234567890" "1234567890", + 0)); + cl_git_fail(git_message_prettify(buffer, sizeof(buffer), + "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" + "1234567890" "1234567890" "1234567890" "1234567890" "1234567890""x", + 0)); + + cl_assert(git_message_prettify(buffer, sizeof(buffer), + "1234567890" "1234567890" "1234567890" "1234567890" "1234567890\n" + "# 1234567890" "1234567890" "1234567890" "1234567890" "1234567890\n" + "1234567890", + 1) > 0); + + cl_assert(git_message_prettify(NULL, 0, "", 0) == 1); + cl_assert(git_message_prettify(NULL, 0, "Short test", 0) == 12); + cl_assert(git_message_prettify(NULL, 0, "Test\n# with\nComments", 1) == 15); +} diff --git a/tests-clar/object/peel.c b/tests-clar/object/peel.c new file mode 100644 index 000000000..bb0bbd096 --- /dev/null +++ b/tests-clar/object/peel.c @@ -0,0 +1,110 @@ +#include "clar_libgit2.h" + +static git_repository *g_repo; + +void test_object_peel__initialize(void) +{ + cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git"))); +} + +void test_object_peel__cleanup(void) +{ + git_repository_free(g_repo); + g_repo = NULL; +} + +static void assert_peel( + const char *sha, + git_otype requested_type, + const char* expected_sha, + git_otype expected_type) +{ + git_oid oid, expected_oid; + git_object *obj; + git_object *peeled; + + cl_git_pass(git_oid_fromstr(&oid, sha)); + cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY)); + + cl_git_pass(git_object_peel(&peeled, obj, requested_type)); + + cl_git_pass(git_oid_fromstr(&expected_oid, expected_sha)); + cl_assert_equal_i(0, git_oid_cmp(&expected_oid, git_object_id(peeled))); + + cl_assert_equal_i(expected_type, git_object_type(peeled)); + + git_object_free(peeled); + git_object_free(obj); +} + +static void assert_peel_error(int error, const char *sha, git_otype requested_type) +{ + git_oid oid; + git_object *obj; + git_object *peeled; + + cl_git_pass(git_oid_fromstr(&oid, sha)); + cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY)); + + cl_assert_equal_i(error, git_object_peel(&peeled, obj, requested_type)); + + git_object_free(obj); +} + +void test_object_peel__peeling_an_object_into_its_own_type_returns_another_instance_of_it(void) +{ + assert_peel("e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_COMMIT, + "e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_COMMIT); + assert_peel("7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJ_TAG, + "7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJ_TAG); + assert_peel("53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_TREE, + "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_TREE); + assert_peel("0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJ_BLOB, + "0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJ_BLOB); +} + +void test_object_peel__can_peel_a_tag(void) +{ + assert_peel("7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJ_COMMIT, + "e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_COMMIT); + assert_peel("7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJ_TREE, + "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_TREE); +} + +void test_object_peel__can_peel_a_commit(void) +{ + assert_peel("e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_TREE, + "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_TREE); +} + +void test_object_peel__cannot_peel_a_tree(void) +{ + assert_peel_error(GIT_EAMBIGUOUS, "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_BLOB); +} + +void test_object_peel__cannot_peel_a_blob(void) +{ + assert_peel_error(GIT_ENOTFOUND, "0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJ_COMMIT); +} + +void test_object_peel__target_any_object_for_type_change(void) +{ + /* tag to commit */ + assert_peel("7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJ_ANY, + "e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_COMMIT); + + /* commit to tree */ + assert_peel("e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_ANY, + "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_TREE); + + /* fail to peel tree */ + assert_peel_error(GIT_EAMBIGUOUS, "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_ANY); + + /* fail to peel blob */ + assert_peel_error(GIT_ENOTFOUND, "0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJ_ANY); +} + +void test_object_peel__should_use_a_well_known_type(void) +{ + assert_peel_error(GIT_EINVALIDSPEC, "7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJ__EXT2); +} diff --git a/tests-clar/object/raw/convert.c b/tests-clar/object/raw/convert.c index 7f310ddf0..74442c153 100644 --- a/tests-clar/object/raw/convert.c +++ b/tests-clar/object/raw/convert.c @@ -21,9 +21,9 @@ void test_object_raw_convert__succeed_on_oid_to_string_conversion(void) str = git_oid_tostr(out, 0, &in); cl_assert(str && *str == '\0' && str != out); - /* NULL oid pointer, returns static empty string */ + /* NULL oid pointer, sets existing buffer to empty string */ str = git_oid_tostr(out, sizeof(out), NULL); - cl_assert(str && *str == '\0' && str != out); + cl_assert(str && *str == '\0' && str == out); /* n == 1, returns out as an empty string */ str = git_oid_tostr(out, 1, &in); diff --git a/tests-clar/object/raw/hash.c b/tests-clar/object/raw/hash.c index 4b8b1b74c..ede31e145 100644 --- a/tests-clar/object/raw/hash.c +++ b/tests-clar/object/raw/hash.c @@ -8,11 +8,11 @@ static void hash_object_pass(git_oid *oid, git_rawobj *obj) { - cl_git_pass(git_odb_hash(oid, obj->data, obj->len, obj->type)); + cl_git_pass(git_odb_hash(oid, obj->data, obj->len, obj->type)); } static void hash_object_fail(git_oid *oid, git_rawobj *obj) { - cl_git_fail(git_odb_hash(oid, obj->data, obj->len, obj->type)); + cl_git_fail(git_odb_hash(oid, obj->data, obj->len, obj->type)); } static char *hello_id = "22596363b3de40b06f981fb85d82312e8c0ed511"; @@ -23,144 +23,144 @@ static char *bye_text = "bye world\n"; void test_object_raw_hash__hash_by_blocks(void) { - git_hash_ctx *ctx; - git_oid id1, id2; + git_hash_ctx ctx; + git_oid id1, id2; - cl_assert((ctx = git_hash_new_ctx()) != NULL); + cl_git_pass(git_hash_ctx_init(&ctx)); /* should already be init'd */ - git_hash_update(ctx, hello_text, strlen(hello_text)); - git_hash_final(&id2, ctx); - cl_git_pass(git_oid_fromstr(&id1, hello_id)); - cl_assert(git_oid_cmp(&id1, &id2) == 0); + cl_git_pass(git_hash_update(&ctx, hello_text, strlen(hello_text))); + cl_git_pass(git_hash_final(&id2, &ctx)); + cl_git_pass(git_oid_fromstr(&id1, hello_id)); + cl_assert(git_oid_cmp(&id1, &id2) == 0); /* reinit should permit reuse */ - git_hash_init(ctx); - git_hash_update(ctx, bye_text, strlen(bye_text)); - git_hash_final(&id2, ctx); - cl_git_pass(git_oid_fromstr(&id1, bye_id)); - cl_assert(git_oid_cmp(&id1, &id2) == 0); + cl_git_pass(git_hash_init(&ctx)); + cl_git_pass(git_hash_update(&ctx, bye_text, strlen(bye_text))); + cl_git_pass(git_hash_final(&id2, &ctx)); + cl_git_pass(git_oid_fromstr(&id1, bye_id)); + cl_assert(git_oid_cmp(&id1, &id2) == 0); - git_hash_free_ctx(ctx); + git_hash_ctx_cleanup(&ctx); } void test_object_raw_hash__hash_buffer_in_single_call(void) { - git_oid id1, id2; + git_oid id1, id2; - cl_git_pass(git_oid_fromstr(&id1, hello_id)); - git_hash_buf(&id2, hello_text, strlen(hello_text)); - cl_assert(git_oid_cmp(&id1, &id2) == 0); + cl_git_pass(git_oid_fromstr(&id1, hello_id)); + git_hash_buf(&id2, hello_text, strlen(hello_text)); + cl_assert(git_oid_cmp(&id1, &id2) == 0); } void test_object_raw_hash__hash_vector(void) { - git_oid id1, id2; - git_buf_vec vec[2]; + git_oid id1, id2; + git_buf_vec vec[2]; - cl_git_pass(git_oid_fromstr(&id1, hello_id)); + cl_git_pass(git_oid_fromstr(&id1, hello_id)); - vec[0].data = hello_text; - vec[0].len = 4; - vec[1].data = hello_text+4; - vec[1].len = strlen(hello_text)-4; + vec[0].data = hello_text; + vec[0].len = 4; + vec[1].data = hello_text+4; + vec[1].len = strlen(hello_text)-4; - git_hash_vec(&id2, vec, 2); + git_hash_vec(&id2, vec, 2); - cl_assert(git_oid_cmp(&id1, &id2) == 0); + cl_assert(git_oid_cmp(&id1, &id2) == 0); } void test_object_raw_hash__hash_junk_data(void) { - git_oid id, id_zero; + git_oid id, id_zero; - cl_git_pass(git_oid_fromstr(&id_zero, zero_id)); + cl_git_pass(git_oid_fromstr(&id_zero, zero_id)); - /* invalid types: */ - junk_obj.data = some_data; - hash_object_fail(&id, &junk_obj); + /* invalid types: */ + junk_obj.data = some_data; + hash_object_fail(&id, &junk_obj); - junk_obj.type = GIT_OBJ__EXT1; - hash_object_fail(&id, &junk_obj); + junk_obj.type = GIT_OBJ__EXT1; + hash_object_fail(&id, &junk_obj); - junk_obj.type = GIT_OBJ__EXT2; - hash_object_fail(&id, &junk_obj); + junk_obj.type = GIT_OBJ__EXT2; + hash_object_fail(&id, &junk_obj); - junk_obj.type = GIT_OBJ_OFS_DELTA; - hash_object_fail(&id, &junk_obj); + junk_obj.type = GIT_OBJ_OFS_DELTA; + hash_object_fail(&id, &junk_obj); - junk_obj.type = GIT_OBJ_REF_DELTA; - hash_object_fail(&id, &junk_obj); + junk_obj.type = GIT_OBJ_REF_DELTA; + hash_object_fail(&id, &junk_obj); - /* data can be NULL only if len is zero: */ - junk_obj.type = GIT_OBJ_BLOB; - junk_obj.data = NULL; - hash_object_pass(&id, &junk_obj); - cl_assert(git_oid_cmp(&id, &id_zero) == 0); + /* data can be NULL only if len is zero: */ + junk_obj.type = GIT_OBJ_BLOB; + junk_obj.data = NULL; + hash_object_pass(&id, &junk_obj); + cl_assert(git_oid_cmp(&id, &id_zero) == 0); - junk_obj.len = 1; - hash_object_fail(&id, &junk_obj); + junk_obj.len = 1; + hash_object_fail(&id, &junk_obj); } void test_object_raw_hash__hash_commit_object(void) { - git_oid id1, id2; + git_oid id1, id2; - cl_git_pass(git_oid_fromstr(&id1, commit_id)); - hash_object_pass(&id2, &commit_obj); - cl_assert(git_oid_cmp(&id1, &id2) == 0); + cl_git_pass(git_oid_fromstr(&id1, commit_id)); + hash_object_pass(&id2, &commit_obj); + cl_assert(git_oid_cmp(&id1, &id2) == 0); } void test_object_raw_hash__hash_tree_object(void) { - git_oid id1, id2; + git_oid id1, id2; - cl_git_pass(git_oid_fromstr(&id1, tree_id)); - hash_object_pass(&id2, &tree_obj); - cl_assert(git_oid_cmp(&id1, &id2) == 0); + cl_git_pass(git_oid_fromstr(&id1, tree_id)); + hash_object_pass(&id2, &tree_obj); + cl_assert(git_oid_cmp(&id1, &id2) == 0); } void test_object_raw_hash__hash_tag_object(void) { - git_oid id1, id2; + git_oid id1, id2; - cl_git_pass(git_oid_fromstr(&id1, tag_id)); - hash_object_pass(&id2, &tag_obj); - cl_assert(git_oid_cmp(&id1, &id2) == 0); + cl_git_pass(git_oid_fromstr(&id1, tag_id)); + hash_object_pass(&id2, &tag_obj); + cl_assert(git_oid_cmp(&id1, &id2) == 0); } void test_object_raw_hash__hash_zero_length_object(void) { - git_oid id1, id2; + git_oid id1, id2; - cl_git_pass(git_oid_fromstr(&id1, zero_id)); - hash_object_pass(&id2, &zero_obj); - cl_assert(git_oid_cmp(&id1, &id2) == 0); + cl_git_pass(git_oid_fromstr(&id1, zero_id)); + hash_object_pass(&id2, &zero_obj); + cl_assert(git_oid_cmp(&id1, &id2) == 0); } void test_object_raw_hash__hash_one_byte_object(void) { - git_oid id1, id2; + git_oid id1, id2; - cl_git_pass(git_oid_fromstr(&id1, one_id)); - hash_object_pass(&id2, &one_obj); - cl_assert(git_oid_cmp(&id1, &id2) == 0); + cl_git_pass(git_oid_fromstr(&id1, one_id)); + hash_object_pass(&id2, &one_obj); + cl_assert(git_oid_cmp(&id1, &id2) == 0); } void test_object_raw_hash__hash_two_byte_object(void) { - git_oid id1, id2; + git_oid id1, id2; - cl_git_pass(git_oid_fromstr(&id1, two_id)); - hash_object_pass(&id2, &two_obj); - cl_assert(git_oid_cmp(&id1, &id2) == 0); + cl_git_pass(git_oid_fromstr(&id1, two_id)); + hash_object_pass(&id2, &two_obj); + cl_assert(git_oid_cmp(&id1, &id2) == 0); } void test_object_raw_hash__hash_multi_byte_object(void) { - git_oid id1, id2; + git_oid id1, id2; - cl_git_pass(git_oid_fromstr(&id1, some_id)); - hash_object_pass(&id2, &some_obj); - cl_assert(git_oid_cmp(&id1, &id2) == 0); + cl_git_pass(git_oid_fromstr(&id1, some_id)); + hash_object_pass(&id2, &some_obj); + cl_assert(git_oid_cmp(&id1, &id2) == 0); } diff --git a/tests-clar/object/raw/short.c b/tests-clar/object/raw/short.c index 14b1ae219..93c79b6a5 100644 --- a/tests-clar/object/raw/short.c +++ b/tests-clar/object/raw/short.c @@ -43,7 +43,7 @@ void test_object_raw_short__oid_shortener_stresstest_git_oid_shorten(void) for (i = 0; i < MAX_OIDS; ++i) { char *oid_text; - sprintf(number_buffer, "%u", (unsigned int)i); + p_snprintf(number_buffer, 16, "%u", (unsigned int)i); git_hash_buf(&oid, number_buffer, strlen(number_buffer)); oid_text = git__malloc(GIT_OID_HEXSZ + 1); diff --git a/tests-clar/object/tag/list.c b/tests-clar/object/tag/list.c new file mode 100644 index 000000000..6d5a24347 --- /dev/null +++ b/tests-clar/object/tag/list.c @@ -0,0 +1,115 @@ +#include "clar_libgit2.h" + +#include "tag.h" + +static git_repository *g_repo; + +#define MAX_USED_TAGS 6 + +struct pattern_match_t +{ + const char* pattern; + const size_t expected_matches; + const char* expected_results[MAX_USED_TAGS]; +}; + +// Helpers +static void ensure_tag_pattern_match(git_repository *repo, + const struct pattern_match_t* data) +{ + int already_found[MAX_USED_TAGS] = { 0 }; + git_strarray tag_list; + int error = 0; + size_t sucessfully_found = 0; + size_t i, j; + + cl_assert(data->expected_matches <= MAX_USED_TAGS); + + if ((error = git_tag_list_match(&tag_list, data->pattern, repo)) < 0) + goto exit; + + if (tag_list.count != data->expected_matches) + { + error = GIT_ERROR; + goto exit; + } + + // we have to be prepared that tags come in any order. + for (i = 0; i < tag_list.count; i++) + { + for (j = 0; j < data->expected_matches; j++) + { + if (!already_found[j] && !strcmp(data->expected_results[j], tag_list.strings[i])) + { + already_found[j] = 1; + sucessfully_found++; + break; + } + } + } + cl_assert_equal_i((int)sucessfully_found, (int)data->expected_matches); + +exit: + git_strarray_free(&tag_list); + cl_git_pass(error); +} + +// Fixture setup and teardown +void test_object_tag_list__initialize(void) +{ + g_repo = cl_git_sandbox_init("testrepo"); +} + +void test_object_tag_list__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +void test_object_tag_list__list_all(void) +{ + // list all tag names from the repository + git_strarray tag_list; + + cl_git_pass(git_tag_list(&tag_list, g_repo)); + + cl_assert_equal_i((int)tag_list.count, 6); + + git_strarray_free(&tag_list); +} + +static const struct pattern_match_t matches[] = { + // All tags, including a packed one and two namespaced ones. + { "", 6, { "e90810b", "point_to_blob", "test", "packed-tag", "foo/bar", "foo/foo/bar" } }, + + // beginning with + { "t*", 1, { "test" } }, + + // ending with + { "*b", 2, { "e90810b", "point_to_blob" } }, + + // exact match + { "e", 0 }, + { "e90810b", 1, { "e90810b" } }, + + // either or + { "e90810[ab]", 1, { "e90810b" } }, + + // glob in the middle + { "foo/*/bar", 1, { "foo/foo/bar" } }, + + // The matching of '*' is based on plain string matching analog to the regular expression ".*" + // => a '/' in the tag name has no special meaning. + // Compare to `git tag -l "*bar"` + { "*bar", 2, { "foo/bar", "foo/foo/bar" } }, + + // End of list + { NULL } +}; + +void test_object_tag_list__list_by_pattern(void) +{ + // list all tag names from the repository matching a specified pattern + size_t i = 0; + while (matches[i].pattern) + ensure_tag_pattern_match(g_repo, &matches[i++]); +} diff --git a/tests-clar/object/tag/peel.c b/tests-clar/object/tag/peel.c index 97c5a7dd3..e2cd8d6a8 100644 --- a/tests-clar/object/tag/peel.c +++ b/tests-clar/object/tag/peel.c @@ -14,8 +14,13 @@ void test_object_tag_peel__initialize(void) void test_object_tag_peel__cleanup(void) { git_tag_free(tag); + tag = NULL; + git_object_free(target); + target = NULL; + git_repository_free(repo); + repo = NULL; cl_fixture_cleanup("testrepo.git"); } diff --git a/tests-clar/object/tag/read.c b/tests-clar/object/tag/read.c index 6a0ad8a23..c9787a413 100644 --- a/tests-clar/object/tag/read.c +++ b/tests-clar/object/tag/read.c @@ -7,124 +7,136 @@ static const char *tag2_id = "7b4384978d2493e851f9cca7858815fac9b10980"; static const char *tagged_commit = "e90810b8df3e80c413d903f631643c716887138d"; static const char *bad_tag_id = "eda9f45a2a98d4c17a09d681d88569fa4ea91755"; static const char *badly_tagged_commit = "e90810b8df3e80c413d903f631643c716887138d"; +static const char *short_tag_id = "5da7760512a953e3c7c4e47e4392c7a4338fb729"; +static const char *short_tagged_commit = "4a5ed60bafcf4638b7c8356bd4ce1916bfede93c"; +static const char *taggerless = "4a23e2e65ad4e31c4c9db7dc746650bfad082679"; static git_repository *g_repo; - -// Helpers -static void ensure_tag_pattern_match(git_repository *repo, - const char *pattern, - const size_t expected_matches) -{ - git_strarray tag_list; - int error = 0; - - if ((error = git_tag_list_match(&tag_list, pattern, repo)) < 0) - goto exit; - - if (tag_list.count != expected_matches) - error = GIT_ERROR; - -exit: - git_strarray_free(&tag_list); - cl_git_pass(error); -} - - // Fixture setup and teardown void test_object_tag_read__initialize(void) { - g_repo = cl_git_sandbox_init("testrepo"); + g_repo = cl_git_sandbox_init("testrepo"); } void test_object_tag_read__cleanup(void) { - cl_git_sandbox_cleanup(); + cl_git_sandbox_cleanup(); } void test_object_tag_read__parse(void) { - // read and parse a tag from the repository - git_tag *tag1, *tag2; - git_commit *commit; - git_oid id1, id2, id_commit; + // read and parse a tag from the repository + git_tag *tag1, *tag2; + git_commit *commit; + git_oid id1, id2, id_commit; - git_oid_fromstr(&id1, tag1_id); - git_oid_fromstr(&id2, tag2_id); - git_oid_fromstr(&id_commit, tagged_commit); + git_oid_fromstr(&id1, tag1_id); + git_oid_fromstr(&id2, tag2_id); + git_oid_fromstr(&id_commit, tagged_commit); - cl_git_pass(git_tag_lookup(&tag1, g_repo, &id1)); + cl_git_pass(git_tag_lookup(&tag1, g_repo, &id1)); - cl_assert_equal_s(git_tag_name(tag1), "test"); - cl_assert(git_tag_type(tag1) == GIT_OBJ_TAG); + cl_assert_equal_s(git_tag_name(tag1), "test"); + cl_assert(git_tag_target_type(tag1) == GIT_OBJ_TAG); - cl_git_pass(git_tag_target((git_object **)&tag2, tag1)); - cl_assert(tag2 != NULL); + cl_git_pass(git_tag_target((git_object **)&tag2, tag1)); + cl_assert(tag2 != NULL); - cl_assert(git_oid_cmp(&id2, git_tag_id(tag2)) == 0); + cl_assert(git_oid_cmp(&id2, git_tag_id(tag2)) == 0); - cl_git_pass(git_tag_target((git_object **)&commit, tag2)); - cl_assert(commit != NULL); + cl_git_pass(git_tag_target((git_object **)&commit, tag2)); + cl_assert(commit != NULL); - cl_assert(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0); + cl_assert(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0); - git_tag_free(tag1); - git_tag_free(tag2); - git_commit_free(commit); + git_tag_free(tag1); + git_tag_free(tag2); + git_commit_free(commit); } -void test_object_tag_read__list(void) +void test_object_tag_read__parse_without_tagger(void) { - // list all tag names from the repository - git_strarray tag_list; + // read and parse a tag without a tagger field + git_repository *bad_tag_repo; + git_tag *bad_tag; + git_commit *commit; + git_oid id, id_commit; + + // TODO: This is a little messy + cl_git_pass(git_repository_open(&bad_tag_repo, cl_fixture("bad_tag.git"))); + + git_oid_fromstr(&id, bad_tag_id); + git_oid_fromstr(&id_commit, badly_tagged_commit); + + cl_git_pass(git_tag_lookup(&bad_tag, bad_tag_repo, &id)); + cl_assert(bad_tag != NULL); - cl_git_pass(git_tag_list(&tag_list, g_repo)); + cl_assert_equal_s(git_tag_name(bad_tag), "e90810b"); + cl_assert(git_oid_cmp(&id, git_tag_id(bad_tag)) == 0); + cl_assert(bad_tag->tagger == NULL); - cl_assert(tag_list.count == 3); + cl_git_pass(git_tag_target((git_object **)&commit, bad_tag)); + cl_assert(commit != NULL); - git_strarray_free(&tag_list); + cl_assert(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0); + + + git_tag_free(bad_tag); + git_commit_free(commit); + git_repository_free(bad_tag_repo); } -void test_object_tag_read__list_pattern(void) +void test_object_tag_read__parse_without_message(void) { - // list all tag names from the repository matching a specified pattern - ensure_tag_pattern_match(g_repo, "", 3); - ensure_tag_pattern_match(g_repo, "*", 3); - ensure_tag_pattern_match(g_repo, "t*", 1); - ensure_tag_pattern_match(g_repo, "*b", 2); - ensure_tag_pattern_match(g_repo, "e", 0); - ensure_tag_pattern_match(g_repo, "e90810b", 1); - ensure_tag_pattern_match(g_repo, "e90810[ab]", 1); + // read and parse a tag without a message field + git_repository *short_tag_repo; + git_tag *short_tag; + git_commit *commit; + git_oid id, id_commit; + + // TODO: This is a little messy + cl_git_pass(git_repository_open(&short_tag_repo, cl_fixture("short_tag.git"))); + + git_oid_fromstr(&id, short_tag_id); + git_oid_fromstr(&id_commit, short_tagged_commit); + + cl_git_pass(git_tag_lookup(&short_tag, short_tag_repo, &id)); + cl_assert(short_tag != NULL); + + cl_assert_equal_s(git_tag_name(short_tag), "no_description"); + cl_assert(git_oid_cmp(&id, git_tag_id(short_tag)) == 0); + cl_assert(short_tag->message == NULL); + + cl_git_pass(git_tag_target((git_object **)&commit, short_tag)); + cl_assert(commit != NULL); + + cl_assert(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0); + + git_tag_free(short_tag); + git_commit_free(commit); + git_repository_free(short_tag_repo); } -void test_object_tag_read__parse_without_tagger(void) +void test_object_tag_read__without_tagger_nor_message(void) { - // read and parse a tag without a tagger field - git_repository *bad_tag_repo; - git_tag *bad_tag; - git_commit *commit; - git_oid id, id_commit; - - // TODO: This is a little messy - cl_git_pass(git_repository_open(&bad_tag_repo, cl_fixture("bad_tag.git"))); + git_tag *tag; + git_oid id; + git_repository *repo; - git_oid_fromstr(&id, bad_tag_id); - git_oid_fromstr(&id_commit, badly_tagged_commit); + cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); - cl_git_pass(git_tag_lookup(&bad_tag, bad_tag_repo, &id)); - cl_assert(bad_tag != NULL); + cl_git_pass(git_oid_fromstr(&id, taggerless)); - cl_assert_equal_s(git_tag_name(bad_tag), "e90810b"); - cl_assert(git_oid_cmp(&id, git_tag_id(bad_tag)) == 0); - cl_assert(bad_tag->tagger == NULL); + cl_git_pass(git_tag_lookup(&tag, repo, &id)); - cl_git_pass(git_tag_target((git_object **)&commit, bad_tag)); - cl_assert(commit != NULL); + cl_assert_equal_s(git_tag_name(tag), "taggerless"); + cl_assert(git_tag_target_type(tag) == GIT_OBJ_COMMIT); - cl_assert(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0); + cl_assert(tag->message == NULL); + cl_assert(tag->tagger == NULL); - git_tag_free(bad_tag); - git_commit_free(commit); - git_repository_free(bad_tag_repo); + git_tag_free(tag); + git_repository_free(repo); } diff --git a/tests-clar/object/tag/write.c b/tests-clar/object/tag/write.c index cb196b64e..cd69bea89 100644 --- a/tests-clar/object/tag/write.c +++ b/tests-clar/object/tag/write.c @@ -45,7 +45,7 @@ void test_object_tag_write__basic(void) git_signature_free(tagger); cl_git_pass(git_tag_lookup(&tag, g_repo, &tag_id)); - cl_assert(git_oid_cmp(git_tag_target_oid(tag), &target_id) == 0); + cl_assert(git_oid_cmp(git_tag_target_id(tag), &target_id) == 0); /* Check attributes were set correctly */ tagger1 = git_tag_tagger(tag); @@ -58,8 +58,9 @@ void test_object_tag_write__basic(void) cl_assert_equal_s(git_tag_message(tag), tagger_message); cl_git_pass(git_reference_lookup(&ref_tag, g_repo, "refs/tags/the-tag")); - cl_assert(git_oid_cmp(git_reference_oid(ref_tag), &tag_id) == 0); + cl_assert(git_oid_cmp(git_reference_target(ref_tag), &tag_id) == 0); cl_git_pass(git_reference_delete(ref_tag)); + git_reference_free(ref_tag); git_tag_free(tag); } @@ -77,7 +78,7 @@ void test_object_tag_write__overwrite(void) /* create signature */ cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60)); - cl_git_fail(git_tag_create( + cl_assert_equal_i(GIT_EEXISTS, git_tag_create( &tag_id, /* out id */ g_repo, "e90810b", @@ -88,7 +89,6 @@ void test_object_tag_write__overwrite(void) git_object_free(target); git_signature_free(tagger); - } void test_object_tag_write__replace(void) @@ -103,7 +103,7 @@ void test_object_tag_write__replace(void) cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJ_COMMIT)); cl_git_pass(git_reference_lookup(&ref_tag, g_repo, "refs/tags/e90810b")); - git_oid_cpy(&old_tag_id, git_reference_oid(ref_tag)); + git_oid_cpy(&old_tag_id, git_reference_target(ref_tag)); git_reference_free(ref_tag); /* create signature */ @@ -122,8 +122,8 @@ void test_object_tag_write__replace(void) git_signature_free(tagger); cl_git_pass(git_reference_lookup(&ref_tag, g_repo, "refs/tags/e90810b")); - cl_assert(git_oid_cmp(git_reference_oid(ref_tag), &tag_id) == 0); - cl_assert(git_oid_cmp(git_reference_oid(ref_tag), &old_tag_id) != 0); + cl_assert(git_oid_cmp(git_reference_target(ref_tag), &tag_id) == 0); + cl_assert(git_oid_cmp(git_reference_target(ref_tag), &old_tag_id) != 0); git_reference_free(ref_tag); } @@ -150,7 +150,7 @@ void test_object_tag_write__lightweight(void) cl_assert(git_oid_cmp(&object_id, &target_id) == 0); cl_git_pass(git_reference_lookup(&ref_tag, g_repo, "refs/tags/light-tag")); - cl_assert(git_oid_cmp(git_reference_oid(ref_tag), &target_id) == 0); + cl_assert(git_oid_cmp(git_reference_target(ref_tag), &target_id) == 0); cl_git_pass(git_tag_delete(g_repo, "light-tag")); @@ -166,7 +166,7 @@ void test_object_tag_write__lightweight_over_existing(void) git_oid_fromstr(&target_id, tagged_commit); cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJ_COMMIT)); - cl_git_fail(git_tag_create_lightweight( + cl_assert_equal_i(GIT_EEXISTS, git_tag_create_lightweight( &object_id, g_repo, "e90810b", @@ -190,3 +190,33 @@ void test_object_tag_write__delete(void) git_reference_free(ref_tag); } + +void test_object_tag_write__creating_with_an_invalid_name_returns_EINVALIDSPEC(void) +{ + git_oid target_id, tag_id; + git_signature *tagger; + git_object *target; + + git_oid_fromstr(&target_id, tagged_commit); + cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJ_COMMIT)); + + cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60)); + + cl_assert_equal_i(GIT_EINVALIDSPEC, + git_tag_create(&tag_id, g_repo, + "Inv@{id", target, tagger, tagger_message, 0) + ); + + cl_assert_equal_i(GIT_EINVALIDSPEC, + git_tag_create_lightweight(&tag_id, g_repo, + "Inv@{id", target, 0) + ); + + git_object_free(target); + git_signature_free(tagger); +} + +void test_object_tag_write__deleting_with_an_invalid_name_returns_EINVALIDSPEC(void) +{ + cl_assert_equal_i(GIT_EINVALIDSPEC, git_tag_delete(g_repo, "Inv@{id")); +} diff --git a/tests-clar/object/tree/attributes.c b/tests-clar/object/tree/attributes.c new file mode 100644 index 000000000..cc93b45d2 --- /dev/null +++ b/tests-clar/object/tree/attributes.c @@ -0,0 +1,114 @@ +#include "clar_libgit2.h" +#include "tree.h" + +static const char *blob_oid = "3d0970ec547fc41ef8a5882dde99c6adce65b021"; +static const char *tree_oid = "1b05fdaa881ee45b48cbaa5e9b037d667a47745e"; + +void test_object_tree_attributes__ensure_correctness_of_attributes_on_insertion(void) +{ + git_treebuilder *builder; + git_oid oid; + + cl_git_pass(git_oid_fromstr(&oid, blob_oid)); + + cl_git_pass(git_treebuilder_create(&builder, NULL)); + + cl_git_fail(git_treebuilder_insert(NULL, builder, "one.txt", &oid, (git_filemode_t)0777777)); + cl_git_fail(git_treebuilder_insert(NULL, builder, "one.txt", &oid, (git_filemode_t)0100666)); + cl_git_fail(git_treebuilder_insert(NULL, builder, "one.txt", &oid, (git_filemode_t)0000001)); + + git_treebuilder_free(builder); +} + +void test_object_tree_attributes__group_writable_tree_entries_created_with_an_antique_git_version_can_still_be_accessed(void) +{ + git_repository *repo; + git_oid tid; + git_tree *tree; + const git_tree_entry *entry; + + cl_git_pass(git_repository_open(&repo, cl_fixture("deprecated-mode.git"))); + + cl_git_pass(git_oid_fromstr(&tid, tree_oid)); + cl_git_pass(git_tree_lookup(&tree, repo, &tid)); + + entry = git_tree_entry_byname(tree, "old_mode.txt"); + cl_assert_equal_i( + GIT_FILEMODE_BLOB, + git_tree_entry_filemode(entry)); + + git_tree_free(tree); + git_repository_free(repo); +} + +void test_object_tree_attributes__treebuilder_reject_invalid_filemode(void) +{ + git_treebuilder *builder; + git_oid bid; + const git_tree_entry *entry; + + cl_git_pass(git_oid_fromstr(&bid, blob_oid)); + cl_git_pass(git_treebuilder_create(&builder, NULL)); + + cl_git_fail(git_treebuilder_insert( + &entry, + builder, + "normalized.txt", + &bid, + GIT_FILEMODE_BLOB_GROUP_WRITABLE)); + + git_treebuilder_free(builder); +} + +void test_object_tree_attributes__normalize_attributes_when_creating_a_tree_from_an_existing_one(void) +{ + git_repository *repo; + git_treebuilder *builder; + git_oid tid, tid2; + git_tree *tree; + const git_tree_entry *entry; + + repo = cl_git_sandbox_init("deprecated-mode.git"); + + cl_git_pass(git_oid_fromstr(&tid, tree_oid)); + cl_git_pass(git_tree_lookup(&tree, repo, &tid)); + + cl_git_pass(git_treebuilder_create(&builder, tree)); + + entry = git_treebuilder_get(builder, "old_mode.txt"); + cl_assert_equal_i( + GIT_FILEMODE_BLOB, + git_tree_entry_filemode(entry)); + + cl_git_pass(git_treebuilder_write(&tid2, repo, builder)); + git_treebuilder_free(builder); + git_tree_free(tree); + + cl_git_pass(git_tree_lookup(&tree, repo, &tid2)); + entry = git_tree_entry_byname(tree, "old_mode.txt"); + cl_assert_equal_i( + GIT_FILEMODE_BLOB, + git_tree_entry_filemode(entry)); + + git_tree_free(tree); + cl_git_sandbox_cleanup(); +} + +void test_object_tree_attributes__normalize_600(void) +{ + git_oid id; + git_tree *tree; + git_repository *repo; + const git_tree_entry *entry; + + repo = cl_git_sandbox_init("deprecated-mode.git"); + + git_oid_fromstr(&id, "0810fb7818088ff5ac41ee49199b51473b1bd6c7"); + cl_git_pass(git_tree_lookup(&tree, repo, &id)); + + entry = git_tree_entry_byname(tree, "ListaTeste.xml"); + cl_assert_equal_i(entry->attr, GIT_FILEMODE_BLOB); + + git_tree_free(tree); + cl_git_sandbox_cleanup(); +} diff --git a/tests-clar/object/tree/duplicateentries.c b/tests-clar/object/tree/duplicateentries.c new file mode 100644 index 000000000..9262f9a1a --- /dev/null +++ b/tests-clar/object/tree/duplicateentries.c @@ -0,0 +1,157 @@ +#include "clar_libgit2.h" +#include "tree.h" + +static git_repository *_repo; + +void test_object_tree_duplicateentries__initialize(void) { + _repo = cl_git_sandbox_init("testrepo"); +} + +void test_object_tree_duplicateentries__cleanup(void) { + cl_git_sandbox_cleanup(); +} + +/* + * $ git show --format=raw refs/heads/dir + * commit 144344043ba4d4a405da03de3844aa829ae8be0e + * tree d52a8fe84ceedf260afe4f0287bbfca04a117e83 + * parent cf80f8de9f1185bf3a05f993f6121880dd0cfbc9 + * author Ben Straub <bstraub@github.com> 1343755506 -0700 + * committer Ben Straub <bstraub@github.com> 1343755506 -0700 + * + * Change a file mode + * + * diff --git a/a/b.txt b/a/b.txt + * old mode 100644 + * new mode 100755 + * + * $ git ls-tree d52a8fe84ceedf260afe4f0287bbfca04a117e83 + * 100644 blob a8233120f6ad708f843d861ce2b7228ec4e3dec6 README + * 040000 tree 4e0883eeeeebc1fb1735161cea82f7cb5fab7e63 a + * 100644 blob 45b983be36b73c0788dc9cbcb76cbb80fc7bb057 branch_file.txt + * 100644 blob a71586c1dfe8a71c6cbf6c129f404c5642ff31bd new.txt + */ + +static void tree_checker( + git_oid *tid, + const char *expected_sha, + git_filemode_t expected_filemode) +{ + git_tree *tree; + const git_tree_entry *entry; + git_oid oid; + + cl_git_pass(git_tree_lookup(&tree, _repo, tid)); + cl_assert_equal_i(1, (int)git_tree_entrycount(tree)); + entry = git_tree_entry_byindex(tree, 0); + + cl_git_pass(git_oid_fromstr(&oid, expected_sha)); + + cl_assert_equal_i(0, git_oid_cmp(&oid, git_tree_entry_id(entry))); + cl_assert_equal_i(expected_filemode, git_tree_entry_filemode(entry)); + + git_tree_free(tree); +} + +static void tree_creator(git_oid *out, void (*fn)(git_treebuilder *)) +{ + git_treebuilder *builder; + + cl_git_pass(git_treebuilder_create(&builder, NULL)); + + fn(builder); + + cl_git_pass(git_treebuilder_write(out, _repo, builder)); + git_treebuilder_free(builder); +} + +static void two_blobs(git_treebuilder *bld) +{ + git_oid oid; + const git_tree_entry *entry; + + cl_git_pass(git_oid_fromstr(&oid, + "a8233120f6ad708f843d861ce2b7228ec4e3dec6")); /* blob oid (README) */ + + cl_git_pass(git_treebuilder_insert( + &entry, bld, "duplicate", &oid, + GIT_FILEMODE_BLOB)); + + cl_git_pass(git_oid_fromstr(&oid, + "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd")); /* blob oid (new.txt) */ + + cl_git_pass(git_treebuilder_insert( + &entry, bld, "duplicate", &oid, + GIT_FILEMODE_BLOB)); +} + +static void one_blob_and_one_tree(git_treebuilder *bld) +{ + git_oid oid; + const git_tree_entry *entry; + + cl_git_pass(git_oid_fromstr(&oid, + "a8233120f6ad708f843d861ce2b7228ec4e3dec6")); /* blob oid (README) */ + + cl_git_pass(git_treebuilder_insert( + &entry, bld, "duplicate", &oid, + GIT_FILEMODE_BLOB)); + + cl_git_pass(git_oid_fromstr(&oid, + "4e0883eeeeebc1fb1735161cea82f7cb5fab7e63")); /* tree oid (a) */ + + cl_git_pass(git_treebuilder_insert( + &entry, bld, "duplicate", &oid, + GIT_FILEMODE_TREE)); +} + +void test_object_tree_duplicateentries__cannot_create_a_duplicate_entry_through_the_treebuilder(void) +{ + git_oid tid; + + tree_creator(&tid, two_blobs); + tree_checker(&tid, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd", GIT_FILEMODE_BLOB); + + tree_creator(&tid, one_blob_and_one_tree); + tree_checker(&tid, "4e0883eeeeebc1fb1735161cea82f7cb5fab7e63", GIT_FILEMODE_TREE); +} + +static void add_fake_conflicts(git_index *index) +{ + git_index_entry ancestor_entry, our_entry, their_entry; + + memset(&ancestor_entry, 0x0, sizeof(git_index_entry)); + memset(&our_entry, 0x0, sizeof(git_index_entry)); + memset(&their_entry, 0x0, sizeof(git_index_entry)); + + ancestor_entry.path = "duplicate"; + ancestor_entry.mode = GIT_FILEMODE_BLOB; + ancestor_entry.flags |= (1 << GIT_IDXENTRY_STAGESHIFT); + git_oid_fromstr(&ancestor_entry.oid, "a8233120f6ad708f843d861ce2b7228ec4e3dec6"); + + our_entry.path = "duplicate"; + our_entry.mode = GIT_FILEMODE_BLOB; + ancestor_entry.flags |= (2 << GIT_IDXENTRY_STAGESHIFT); + git_oid_fromstr(&our_entry.oid, "45b983be36b73c0788dc9cbcb76cbb80fc7bb057"); + + their_entry.path = "duplicate"; + their_entry.mode = GIT_FILEMODE_BLOB; + ancestor_entry.flags |= (3 << GIT_IDXENTRY_STAGESHIFT); + git_oid_fromstr(&their_entry.oid, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd"); + + cl_git_pass(git_index_conflict_add(index, &ancestor_entry, &our_entry, &their_entry)); +} + +void test_object_tree_duplicateentries__cannot_create_a_duplicate_entry_building_a_tree_from_a_index_with_conflicts(void) +{ + git_index *index; + git_oid tid; + + cl_git_pass(git_repository_index(&index, _repo)); + + add_fake_conflicts(index); + + cl_assert_equal_i(GIT_EUNMERGED, git_index_write_tree(&tid, index)); + + git_index_free(index); +} diff --git a/tests-clar/object/tree/frompath.c b/tests-clar/object/tree/frompath.c index 06c69ac08..86ca47e94 100644 --- a/tests-clar/object/tree/frompath.c +++ b/tests-clar/object/tree/frompath.c @@ -1,15 +1,14 @@ #include "clar_libgit2.h" static git_repository *repo; -const char *tree_with_subtrees_oid = "ae90f12eea699729ed24555e40b9fd669da12a12"; static git_tree *tree; void test_object_tree_frompath__initialize(void) { git_oid id; + const char *tree_with_subtrees_oid = "ae90f12eea699729ed24555e40b9fd669da12a12"; - cl_fixture_sandbox("testrepo.git"); - cl_git_pass(git_repository_open(&repo, "testrepo.git")); + cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); cl_assert(repo != NULL); cl_git_pass(git_oid_fromstr(&id, tree_with_subtrees_oid)); @@ -20,62 +19,50 @@ void test_object_tree_frompath__initialize(void) void test_object_tree_frompath__cleanup(void) { git_tree_free(tree); + tree = NULL; + git_repository_free(repo); - cl_fixture_cleanup("testrepo.git"); + repo = NULL; } -static void assert_tree_from_path(git_tree *root, const char *path, int expected_result, const char *expected_raw_oid) +static void assert_tree_from_path( + git_tree *root, + const char *path, + const char *expected_entry_name) { - git_tree *containing_tree = NULL; - - cl_assert(git_tree_get_subtree(&containing_tree, root, path) == expected_result); - - if (containing_tree == NULL && expected_result != 0) - return; - - cl_assert(containing_tree != NULL && expected_result == 0); - - cl_git_pass(git_oid_streq(git_object_id((const git_object *)containing_tree), expected_raw_oid)); + git_tree_entry *entry; - git_tree_free(containing_tree); -} - -static void assert_tree_from_path_klass(git_tree *root, const char *path, int expected_result, const char *expected_raw_oid) -{ - assert_tree_from_path(root, path, GIT_ERROR, expected_raw_oid); - cl_assert(giterr_last()->klass == expected_result); + cl_git_pass(git_tree_entry_bypath(&entry, root, path)); + cl_assert_equal_s(git_tree_entry_name(entry), expected_entry_name); + git_tree_entry_free(entry); } void test_object_tree_frompath__retrieve_tree_from_path_to_treeentry(void) { - /* Will return self if given a one path segment... */ - assert_tree_from_path(tree, "README", 0, tree_with_subtrees_oid); - - /* ...even one that lead to a non existent tree entry. */ - assert_tree_from_path(tree, "i-do-not-exist.txt", 0, tree_with_subtrees_oid); - - /* Will return fgh tree oid given this following path... */ - assert_tree_from_path(tree, "ab/de/fgh/1.txt", 0, "3259a6bd5b57fb9c1281bb7ed3167b50f224cb54"); - - /* ... and ab tree oid given this one. */ - assert_tree_from_path(tree, "ab/de", 0, "f1425cef211cc08caa31e7b545ffb232acb098c3"); + git_tree_entry *e; - /* Will succeed if given a valid path which leads to a tree entry which doesn't exist */ - assert_tree_from_path(tree, "ab/de/fgh/i-do-not-exist.txt", 0, "3259a6bd5b57fb9c1281bb7ed3167b50f224cb54"); -} + assert_tree_from_path(tree, "README", "README"); + assert_tree_from_path(tree, "ab/de/fgh/1.txt", "1.txt"); + assert_tree_from_path(tree, "ab/de/fgh", "fgh"); + assert_tree_from_path(tree, "ab/de/fgh/", "fgh"); + assert_tree_from_path(tree, "ab/de", "de"); + assert_tree_from_path(tree, "ab/", "ab"); + assert_tree_from_path(tree, "ab/de/", "de"); -void test_object_tree_frompath__fail_when_processing_an_unknown_tree_segment(void) -{ - assert_tree_from_path(tree, "nope/de/fgh/1.txt", GIT_ENOTFOUND, NULL); - assert_tree_from_path(tree, "ab/me-neither/fgh/2.txt", GIT_ENOTFOUND, NULL); + cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "i-do-not-exist.txt")); + cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "README/")); + cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "ab/de/fgh/i-do-not-exist.txt")); + cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "nope/de/fgh/1.txt")); + cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "ab/me-neither/fgh/2.txt")); + cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "ab/me-neither/fgh/2.txt/")); } void test_object_tree_frompath__fail_when_processing_an_invalid_path(void) { - assert_tree_from_path_klass(tree, "/", GITERR_INVALID, NULL); - assert_tree_from_path_klass(tree, "/ab", GITERR_INVALID, NULL); - assert_tree_from_path_klass(tree, "/ab/de", GITERR_INVALID, NULL); - assert_tree_from_path_klass(tree, "ab/", GITERR_INVALID, NULL); - assert_tree_from_path_klass(tree, "ab//de", GITERR_INVALID, NULL); - assert_tree_from_path_klass(tree, "ab/de/", GITERR_INVALID, NULL); + git_tree_entry *e; + + cl_must_fail(git_tree_entry_bypath(&e, tree, "/")); + cl_must_fail(git_tree_entry_bypath(&e, tree, "/ab")); + cl_must_fail(git_tree_entry_bypath(&e, tree, "/ab/de")); + cl_must_fail(git_tree_entry_bypath(&e, tree, "ab//de")); } diff --git a/tests-clar/object/tree/walk.c b/tests-clar/object/tree/walk.c new file mode 100644 index 000000000..b7af4924d --- /dev/null +++ b/tests-clar/object/tree/walk.c @@ -0,0 +1,103 @@ +#include "clar_libgit2.h" +#include "tree.h" + +static const char *tree_oid = "1810dff58d8a660512d4832e740f692884338ccd"; +static git_repository *g_repo; + +void test_object_tree_walk__initialize(void) +{ + g_repo = cl_git_sandbox_init("testrepo"); +} + +void test_object_tree_walk__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +static int treewalk_count_cb( + const char *root, const git_tree_entry *entry, void *payload) +{ + int *count = payload; + + GIT_UNUSED(root); + GIT_UNUSED(entry); + + (*count) += 1; + + return 0; +} + +void test_object_tree_walk__0(void) +{ + git_oid id; + git_tree *tree; + int ct; + + git_oid_fromstr(&id, tree_oid); + + cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); + + ct = 0; + cl_git_pass(git_tree_walk(tree, GIT_TREEWALK_PRE, treewalk_count_cb, &ct)); + cl_assert_equal_i(3, ct); + + ct = 0; + cl_git_pass(git_tree_walk(tree, GIT_TREEWALK_POST, treewalk_count_cb, &ct)); + cl_assert_equal_i(3, ct); + + git_tree_free(tree); +} + + +static int treewalk_stop_cb( + const char *root, const git_tree_entry *entry, void *payload) +{ + int *count = payload; + + GIT_UNUSED(root); + GIT_UNUSED(entry); + + (*count) += 1; + + return (*count == 2) ? -1 : 0; +} + +static int treewalk_stop_immediately_cb( + const char *root, const git_tree_entry *entry, void *payload) +{ + GIT_UNUSED(root); + GIT_UNUSED(entry); + GIT_UNUSED(payload); + return -100; +} + +void test_object_tree_walk__1(void) +{ + git_oid id; + git_tree *tree; + int ct; + + git_oid_fromstr(&id, tree_oid); + + cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); + + ct = 0; + cl_assert_equal_i( + GIT_EUSER, git_tree_walk(tree, GIT_TREEWALK_PRE, treewalk_stop_cb, &ct)); + cl_assert_equal_i(2, ct); + + ct = 0; + cl_assert_equal_i( + GIT_EUSER, git_tree_walk(tree, GIT_TREEWALK_POST, treewalk_stop_cb, &ct)); + cl_assert_equal_i(2, ct); + + cl_assert_equal_i( + GIT_EUSER, git_tree_walk( + tree, GIT_TREEWALK_PRE, treewalk_stop_immediately_cb, NULL)); + + cl_assert_equal_i( + GIT_EUSER, git_tree_walk( + tree, GIT_TREEWALK_POST, treewalk_stop_immediately_cb, NULL)); + + git_tree_free(tree); +} diff --git a/tests-clar/object/tree/write.c b/tests-clar/object/tree/write.c index 3911f6f0e..468c0ccd1 100644 --- a/tests-clar/object/tree/write.c +++ b/tests-clar/object/tree/write.c @@ -35,11 +35,22 @@ void test_object_tree_write__from_memory(void) cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); cl_git_pass(git_treebuilder_create(&builder, tree)); - cl_git_fail(git_treebuilder_insert(NULL, builder, "", &bid, 0100644)); - cl_git_fail(git_treebuilder_insert(NULL, builder, "/", &bid, 0100644)); - cl_git_fail(git_treebuilder_insert(NULL, builder, "folder/new.txt", &bid, 0100644)); + cl_git_fail(git_treebuilder_insert(NULL, builder, "", + &bid, GIT_FILEMODE_BLOB)); + cl_git_fail(git_treebuilder_insert(NULL, builder, "/", + &bid, GIT_FILEMODE_BLOB)); + cl_git_fail(git_treebuilder_insert(NULL, builder, ".git", + &bid, GIT_FILEMODE_BLOB)); + cl_git_fail(git_treebuilder_insert(NULL, builder, "..", + &bid, GIT_FILEMODE_BLOB)); + cl_git_fail(git_treebuilder_insert(NULL, builder, ".", + &bid, GIT_FILEMODE_BLOB)); + cl_git_fail(git_treebuilder_insert(NULL, builder, "folder/new.txt", + &bid, GIT_FILEMODE_BLOB)); + + cl_git_pass(git_treebuilder_insert( + NULL, builder, "new.txt", &bid, GIT_FILEMODE_BLOB)); - cl_git_pass(git_treebuilder_insert(NULL,builder,"new.txt",&bid,0100644)); cl_git_pass(git_treebuilder_write(&rid, g_repo, builder)); cl_assert(git_oid_cmp(&rid, &id2) == 0); @@ -63,14 +74,16 @@ void test_object_tree_write__subtree(void) //create subtree cl_git_pass(git_treebuilder_create(&builder, NULL)); - cl_git_pass(git_treebuilder_insert(NULL,builder,"new.txt",&bid,0100644)); + cl_git_pass(git_treebuilder_insert( + NULL, builder, "new.txt", &bid, GIT_FILEMODE_BLOB)); //-V536 cl_git_pass(git_treebuilder_write(&subtree_id, g_repo, builder)); git_treebuilder_free(builder); // create parent tree cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); cl_git_pass(git_treebuilder_create(&builder, tree)); - cl_git_pass(git_treebuilder_insert(NULL,builder,"new",&subtree_id,040000)); + cl_git_pass(git_treebuilder_insert( + NULL, builder, "new", &subtree_id, GIT_FILEMODE_TREE)); //-V536 cl_git_pass(git_treebuilder_write(&id_hiearar, g_repo, builder)); git_treebuilder_free(builder); git_tree_free(tree); @@ -82,3 +95,168 @@ void test_object_tree_write__subtree(void) cl_assert(2 == git_tree_entrycount(tree)); git_tree_free(tree); } + +/* + * And the Lord said: Is this tree properly sorted? + */ +void test_object_tree_write__sorted_subtrees(void) +{ + git_treebuilder *builder; + unsigned int i; + int position_c = -1, position_cake = -1, position_config = -1; + + struct { + unsigned int attr; + const char *filename; + } entries[] = { + { GIT_FILEMODE_BLOB, ".gitattributes" }, + { GIT_FILEMODE_BLOB, ".gitignore" }, + { GIT_FILEMODE_BLOB, ".htaccess" }, + { GIT_FILEMODE_BLOB, "Capfile" }, + { GIT_FILEMODE_BLOB, "Makefile"}, + { GIT_FILEMODE_BLOB, "README"}, + { GIT_FILEMODE_TREE, "app"}, + { GIT_FILEMODE_TREE, "cake"}, + { GIT_FILEMODE_TREE, "config"}, + { GIT_FILEMODE_BLOB, "c"}, + { GIT_FILEMODE_BLOB, "git_test.txt"}, + { GIT_FILEMODE_BLOB, "htaccess.htaccess"}, + { GIT_FILEMODE_BLOB, "index.php"}, + { GIT_FILEMODE_TREE, "plugins"}, + { GIT_FILEMODE_TREE, "schemas"}, + { GIT_FILEMODE_TREE, "ssl-certs"}, + { GIT_FILEMODE_TREE, "vendors"} + }; + + git_oid blank_oid, tree_oid; + + memset(&blank_oid, 0x0, sizeof(blank_oid)); + + cl_git_pass(git_treebuilder_create(&builder, NULL)); + + for (i = 0; i < ARRAY_SIZE(entries); ++i) { + cl_git_pass(git_treebuilder_insert(NULL, + builder, entries[i].filename, &blank_oid, entries[i].attr)); + } + + cl_git_pass(git_treebuilder_write(&tree_oid, g_repo, builder)); + + for (i = 0; i < builder->entries.length; ++i) { + git_tree_entry *entry = git_vector_get(&builder->entries, i); + + if (strcmp(entry->filename, "c") == 0) + position_c = i; + + if (strcmp(entry->filename, "cake") == 0) + position_cake = i; + + if (strcmp(entry->filename, "config") == 0) + position_config = i; + } + + cl_assert(position_c != -1); + cl_assert(position_cake != -1); + cl_assert(position_config != -1); + + cl_assert(position_c < position_cake); + cl_assert(position_cake < position_config); + + git_treebuilder_free(builder); +} + +void test_object_tree_write__removing_and_re_adding_in_treebuilder(void) +{ + git_treebuilder *builder; + int i, aardvark_i, apple_i, apple_after_i, apple_extra_i, last_i; + git_oid blank_oid, tree_oid; + git_tree *tree; + struct { + unsigned int attr; + const char *filename; + } entries[] = { + { GIT_FILEMODE_BLOB, "aardvark" }, + { GIT_FILEMODE_BLOB, ".first" }, + { GIT_FILEMODE_BLOB, "apple" }, + { GIT_FILEMODE_BLOB, "last"}, + { GIT_FILEMODE_BLOB, "apple_after"}, + { GIT_FILEMODE_BLOB, "after_aardvark"}, + { 0, NULL }, + }; + + memset(&blank_oid, 0x0, sizeof(blank_oid)); + + cl_git_pass(git_treebuilder_create(&builder, NULL)); + + cl_assert_equal_i(0, (int)git_treebuilder_entrycount(builder)); + + for (i = 0; entries[i].filename; ++i) + cl_git_pass(git_treebuilder_insert(NULL, + builder, entries[i].filename, &blank_oid, entries[i].attr)); + + cl_assert_equal_i(6, (int)git_treebuilder_entrycount(builder)); + + cl_git_pass(git_treebuilder_remove(builder, "apple")); + cl_assert_equal_i(5, (int)git_treebuilder_entrycount(builder)); + + cl_git_pass(git_treebuilder_remove(builder, "apple_after")); + cl_assert_equal_i(4, (int)git_treebuilder_entrycount(builder)); + + cl_git_pass(git_treebuilder_insert( + NULL, builder, "before_last", &blank_oid, GIT_FILEMODE_BLOB)); + cl_assert_equal_i(5, (int)git_treebuilder_entrycount(builder)); + + /* reinsert apple_after */ + cl_git_pass(git_treebuilder_insert( + NULL, builder, "apple_after", &blank_oid, GIT_FILEMODE_BLOB)); + cl_assert_equal_i(6, (int)git_treebuilder_entrycount(builder)); + + cl_git_pass(git_treebuilder_remove(builder, "last")); + cl_assert_equal_i(5, (int)git_treebuilder_entrycount(builder)); + + /* reinsert last */ + cl_git_pass(git_treebuilder_insert( + NULL, builder, "last", &blank_oid, GIT_FILEMODE_BLOB)); + cl_assert_equal_i(6, (int)git_treebuilder_entrycount(builder)); + + cl_git_pass(git_treebuilder_insert( + NULL, builder, "apple_extra", &blank_oid, GIT_FILEMODE_BLOB)); + cl_assert_equal_i(7, (int)git_treebuilder_entrycount(builder)); + + cl_git_pass(git_treebuilder_write(&tree_oid, g_repo, builder)); + + git_treebuilder_free(builder); + + cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_oid)); + + cl_assert_equal_i(7, (int)git_tree_entrycount(tree)); + + cl_assert(git_tree_entry_byname(tree, ".first") != NULL); + cl_assert(git_tree_entry_byname(tree, "apple") == NULL); + cl_assert(git_tree_entry_byname(tree, "apple_after") != NULL); + cl_assert(git_tree_entry_byname(tree, "apple_extra") != NULL); + cl_assert(git_tree_entry_byname(tree, "last") != NULL); + + aardvark_i = apple_i = apple_after_i = apple_extra_i = last_i = -1; + + for (i = 0; i < 7; ++i) { + const git_tree_entry *entry = git_tree_entry_byindex(tree, i); + + if (!strcmp(entry->filename, "aardvark")) + aardvark_i = i; + else if (!strcmp(entry->filename, "apple")) + apple_i = i; + else if (!strcmp(entry->filename, "apple_after")) + apple_after_i = i; + else if (!strcmp(entry->filename, "apple_extra")) + apple_extra_i = i; + else if (!strcmp(entry->filename, "last")) + last_i = i; + } + + cl_assert_equal_i(-1, apple_i); + cl_assert_equal_i(6, last_i); + cl_assert(aardvark_i < apple_after_i); + cl_assert(apple_after_i < apple_extra_i); + + git_tree_free(tree); +} |