diff options
Diffstat (limited to 'tests-clar/object/tree')
-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 |
5 files changed, 591 insertions, 52 deletions
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); +} |