libgit2/tests-clar/diff/iterator.c
Russell Belfer da337c8064 Iterator improvements from diff implementation
This makes two changes to iterator behavior: first, advance
can optionally do the work of returning the new current value.
This is such a common pattern that it really cleans up usage.

Second, for workdir iterators, this removes automatically
iterating into directories.  That seemed like a good idea,
but when an entirely new directory hierarchy is introduced
into the workdir, there is no reason to iterate into it if
there are no corresponding entries in the tree/index that it
is being compared to.

This second change actually wasn't a lot of code because not
descending into directories was already the behavior for
ignored directories.  This just extends that to all directories.
2012-02-22 11:22:33 -08:00

365 lines
8.1 KiB
C

#include "clar_libgit2.h"
#include "diff_helpers.h"
#include "iterator.h"
static git_repository *g_repo = NULL;
static const char *g_sandbox = NULL;
static void setup_sandbox(const char *sandbox)
{
cl_fixture_sandbox(sandbox);
g_sandbox = sandbox;
p_chdir(sandbox);
cl_git_pass(p_rename(".gitted", ".git"));
if (p_access("gitattributes", F_OK) == 0)
cl_git_pass(p_rename("gitattributes", ".gitattributes"));
if (p_access("gitignore", F_OK) == 0)
cl_git_pass(p_rename("gitignore", ".gitignore"));
p_chdir("..");
cl_git_pass(git_repository_open(&g_repo, sandbox));
}
static void cleanup_sandbox(void)
{
if (g_repo) {
git_repository_free(g_repo);
g_repo = NULL;
}
if (g_sandbox) {
cl_fixture_cleanup(g_sandbox);
g_sandbox = NULL;
}
}
void test_diff_iterator__initialize(void)
{
/* since we are doing tests with different sandboxes, defer setup
* to the actual tests. cleanup will still be done in the global
* cleanup function so that assertion failures don't result in a
* missed cleanup.
*/
}
void test_diff_iterator__cleanup(void)
{
cleanup_sandbox();
}
/* -- TREE ITERATOR TESTS -- */
static void tree_iterator_test(
const char *sandbox,
const char *treeish,
int expected_count,
const char **expected_values)
{
git_tree *t;
git_iterator *i;
const git_index_entry *entry;
int count = 0;
setup_sandbox(sandbox);
cl_assert(t = resolve_commit_oid_to_tree(g_repo, treeish));
cl_git_pass(git_iterator_for_tree(g_repo, t, &i));
cl_git_pass(git_iterator_current(i, &entry));
while (entry != NULL) {
if (expected_values != NULL)
cl_assert_strequal(expected_values[count], entry->path);
count++;
cl_git_pass(git_iterator_advance(i, &entry));
}
git_iterator_free(i);
cl_assert(expected_count == count);
git_tree_free(t);
}
/* results of: git ls-tree -r --name-only 605812a */
const char *expected_tree_0[] = {
".gitattributes",
"attr0",
"attr1",
"attr2",
"attr3",
"binfile",
"macro_test",
"root_test1",
"root_test2",
"root_test3",
"root_test4.txt",
"subdir/.gitattributes",
"subdir/abc",
"subdir/subdir_test1",
"subdir/subdir_test2.txt",
"subdir2/subdir2_test1",
NULL
};
void test_diff_iterator__tree_0(void)
{
tree_iterator_test("attr", "605812a", 16, expected_tree_0);
}
/* results of: git ls-tree -r --name-only 6bab5c79 */
const char *expected_tree_1[] = {
".gitattributes",
"attr0",
"attr1",
"attr2",
"attr3",
"root_test1",
"root_test2",
"root_test3",
"root_test4.txt",
"subdir/.gitattributes",
"subdir/subdir_test1",
"subdir/subdir_test2.txt",
"subdir2/subdir2_test1",
NULL
};
void test_diff_iterator__tree_1(void)
{
tree_iterator_test("attr", "6bab5c79cd5", 13, expected_tree_1);
}
/* results of: git ls-tree -r --name-only 26a125ee1 */
const char *expected_tree_2[] = {
"current_file",
"file_deleted",
"modified_file",
"staged_changes",
"staged_changes_file_deleted",
"staged_changes_modified_file",
"staged_delete_file_deleted",
"staged_delete_modified_file",
"subdir.txt",
"subdir/current_file",
"subdir/deleted_file",
"subdir/modified_file",
NULL
};
void test_diff_iterator__tree_2(void)
{
tree_iterator_test("status", "26a125ee1", 12, expected_tree_2);
}
/* $ git ls-tree -r --name-only 0017bd4ab1e */
const char *expected_tree_3[] = {
"current_file",
"file_deleted",
"modified_file",
"staged_changes",
"staged_changes_file_deleted",
"staged_changes_modified_file",
"staged_delete_file_deleted",
"staged_delete_modified_file"
};
void test_diff_iterator__tree_3(void)
{
tree_iterator_test("status", "0017bd4ab1e", 8, expected_tree_3);
}
/* -- INDEX ITERATOR TESTS -- */
static void index_iterator_test(
const char *sandbox,
int expected_count,
const char **expected_names,
const char **expected_oids)
{
git_iterator *i;
const git_index_entry *entry;
int count = 0;
setup_sandbox(sandbox);
cl_git_pass(git_iterator_for_index(g_repo, &i));
cl_git_pass(git_iterator_current(i, &entry));
while (entry != NULL) {
if (expected_names != NULL)
cl_assert_strequal(expected_names[count], entry->path);
if (expected_oids != NULL) {
git_oid oid;
cl_git_pass(git_oid_fromstr(&oid, expected_oids[count]));
cl_assert(git_oid_cmp(&oid, &entry->oid) == 0);
}
count++;
cl_git_pass(git_iterator_advance(i, &entry));
}
git_iterator_free(i);
cl_assert(count == expected_count);
}
static const char *expected_index_0[] = {
"attr0",
"attr1",
"attr2",
"attr3",
"binfile",
"gitattributes",
"macro_bad",
"macro_test",
"root_test1",
"root_test2",
"root_test3",
"root_test4.txt",
"subdir/.gitattributes",
"subdir/abc",
"subdir/subdir_test1",
"subdir/subdir_test2.txt",
"subdir2/subdir2_test1",
};
static const char *expected_index_oids_0[] = {
"556f8c827b8e4a02ad5cab77dca2bcb3e226b0b3",
"3b74db7ab381105dc0d28f8295a77f6a82989292",
"2c66e14f77196ea763fb1e41612c1aa2bc2d8ed2",
"c485abe35abd4aa6fd83b076a78bbea9e2e7e06c",
"d800886d9c86731ae5c4a62b0b77c437015e00d2",
"2b40c5aca159b04ea8d20ffe36cdf8b09369b14a",
"5819a185d77b03325aaf87cafc771db36f6ddca7",
"ff69f8639ce2e6010b3f33a74160aad98b48da2b",
"45141a79a77842c59a63229403220a4e4be74e3d",
"45141a79a77842c59a63229403220a4e4be74e3d",
"45141a79a77842c59a63229403220a4e4be74e3d",
"fb5067b1aef3ac1ada4b379dbcb7d17255df7d78",
"99eae476896f4907224978b88e5ecaa6c5bb67a9",
"3e42ffc54a663f9401cc25843d6c0e71a33e4249",
"e563cf4758f0d646f1b14b76016aa17fa9e549a4",
"fb5067b1aef3ac1ada4b379dbcb7d17255df7d78",
"dccada462d3df8ac6de596fb8c896aba9344f941"
};
void test_diff_iterator__index_0(void)
{
index_iterator_test("attr", 17, expected_index_0, expected_index_oids_0);
}
static const char *expected_index_1[] = {
"current_file",
"file_deleted",
"modified_file",
"staged_changes",
"staged_changes_file_deleted",
"staged_changes_modified_file",
"staged_new_file",
"staged_new_file_deleted_file",
"staged_new_file_modified_file",
"subdir.txt",
"subdir/current_file",
"subdir/deleted_file",
"subdir/modified_file",
};
static const char* expected_index_oids_1[] = {
"a0de7e0ac200c489c41c59dfa910154a70264e6e",
"5452d32f1dd538eb0405e8a83cc185f79e25e80f",
"452e4244b5d083ddf0460acf1ecc74db9dcfa11a",
"55d316c9ba708999f1918e9677d01dfcae69c6b9",
"a6be623522ce87a1d862128ac42672604f7b468b",
"906ee7711f4f4928ddcb2a5f8fbc500deba0d2a8",
"529a16e8e762d4acb7b9636ff540a00831f9155a",
"90b8c29d8ba39434d1c63e1b093daaa26e5bd972",
"ed062903b8f6f3dccb2fa81117ba6590944ef9bd",
"e8ee89e15bbe9b20137715232387b3de5b28972e",
"53ace0d1cc1145a5f4fe4f78a186a60263190733",
"1888c805345ba265b0ee9449b8877b6064592058",
"a6191982709b746d5650e93c2acf34ef74e11504"
};
void test_diff_iterator__index_1(void)
{
index_iterator_test("status", 13, expected_index_1, expected_index_oids_1);
}
/* -- WORKDIR ITERATOR TESTS -- */
static void workdir_iterator_test(
const char *sandbox,
int expected_count,
int expected_ignores,
const char **expected_names,
const char *an_ignored_name)
{
git_iterator *i;
const git_index_entry *entry;
int count = 0, count_all = 0;
setup_sandbox(sandbox);
cl_git_pass(git_iterator_for_workdir(g_repo, &i));
cl_git_pass(git_iterator_current(i, &entry));
while (entry != NULL) {
int ignored = git_iterator_current_is_ignored(i);
if (!ignored && S_ISDIR(entry->mode)) {
cl_git_pass(git_iterator_advance_into_directory(i, &entry));
continue;
}
if (expected_names != NULL)
cl_assert_strequal(expected_names[count_all], entry->path);
if (an_ignored_name && strcmp(an_ignored_name,entry->path)==0)
cl_assert(ignored);
if (!ignored)
count++;
count_all++;
cl_git_pass(git_iterator_advance(i, &entry));
}
git_iterator_free(i);
cl_assert(count == expected_count);
cl_assert(count_all == expected_count + expected_ignores);
}
void test_diff_iterator__workdir_0(void)
{
workdir_iterator_test("attr", 15, 4, NULL, "ign");
}
static const char *status_paths[] = {
"current_file",
"ignored_file",
"modified_file",
"new_file",
"staged_changes",
"staged_changes_modified_file",
"staged_delete_modified_file",
"staged_new_file",
"staged_new_file_modified_file",
"subdir/current_file",
"subdir/modified_file",
"subdir/new_file",
"subdir.txt",
NULL
};
void test_diff_iterator__workdir_1(void)
{
workdir_iterator_test("status", 12, 1, status_paths, "ignored_file");
}