libgit2/tests-clar/core/dirent.c
Russell Belfer 854eccbb2d Clean up GIT_UNUSED macros on all platforms
It turns out that commit 31e9cfc4cbcaf1b38cdd3dbe3282a8f57e5366a5
did not fix the GIT_USUSED behavior on all platforms.  This commit
walks through and really cleans things up more thoroughly, getting
rid of the unnecessary stuff.

To remove the use of some GIT_UNUSED, I ended up adding a couple
of new iterators for hashtables that allow you to iterator just
over keys or just over values.

In making this change, I found a bug in the clar tests (where we
were doing *count++ but meant to do (*count)++ to increment the
value).  I fixed that but then found the test failing because it
was not really using an empty repo.  So, I took some of the code
that I wrote for iterator testing and moved it to clar_helpers.c,
then made use of that to make it easier to open fixtures on a
per test basis even within a single test file.
2012-03-02 15:51:55 -08:00

225 lines
3.8 KiB
C

#include "clar_libgit2.h"
#include "fileops.h"
typedef struct name_data {
int count; /* return count */
char *name; /* filename */
} name_data;
typedef struct walk_data {
char *sub; /* sub-directory name */
name_data *names; /* name state data */
git_buf path;
} walk_data;
static char *top_dir = "dir-walk";
static walk_data *state_loc;
static void setup(walk_data *d)
{
name_data *n;
cl_must_pass(p_mkdir(top_dir, 0777));
cl_must_pass(p_chdir(top_dir));
if (strcmp(d->sub, ".") != 0)
cl_must_pass(p_mkdir(d->sub, 0777));
cl_git_pass(git_buf_sets(&d->path, d->sub));
state_loc = d;
for (n = d->names; n->name; n++) {
git_file fd = p_creat(n->name, 0666);
cl_assert(fd >= 0);
p_close(fd);
n->count = 0;
}
}
static void dirent_cleanup__cb(void *_d)
{
walk_data *d = _d;
name_data *n;
for (n = d->names; n->name; n++) {
cl_must_pass(p_unlink(n->name));
}
if (strcmp(d->sub, ".") != 0)
cl_must_pass(p_rmdir(d->sub));
cl_must_pass(p_chdir(".."));
cl_must_pass(p_rmdir(top_dir));
git_buf_free(&d->path);
}
static void check_counts(walk_data *d)
{
name_data *n;
for (n = d->names; n->name; n++) {
cl_assert(n->count == 1);
}
}
static int one_entry(void *state, git_buf *path)
{
walk_data *d = (walk_data *) state;
name_data *n;
if (state != state_loc)
return GIT_ERROR;
if (path != &d->path)
return GIT_ERROR;
for (n = d->names; n->name; n++) {
if (!strcmp(n->name, path->ptr)) {
n->count++;
return 0;
}
}
return GIT_ERROR;
}
static int dont_call_me(void *state, git_buf *path)
{
GIT_UNUSED(state);
GIT_UNUSED(path);
return GIT_ERROR;
}
static name_data dot_names[] = {
{ 0, "./a" },
{ 0, "./asdf" },
{ 0, "./pack-foo.pack" },
{ 0, NULL }
};
static walk_data dot = {
".",
dot_names,
GIT_BUF_INIT
};
/* make sure that the '.' folder is not traversed */
void test_core_dirent__dont_traverse_dot(void)
{
cl_set_cleanup(&dirent_cleanup__cb, &dot);
setup(&dot);
cl_git_pass(git_path_direach(&dot.path,
one_entry,
&dot));
check_counts(&dot);
}
static name_data sub_names[] = {
{ 0, "sub/a" },
{ 0, "sub/asdf" },
{ 0, "sub/pack-foo.pack" },
{ 0, NULL }
};
static walk_data sub = {
"sub",
sub_names,
GIT_BUF_INIT
};
/* traverse a subfolder */
void test_core_dirent__traverse_subfolder(void)
{
cl_set_cleanup(&dirent_cleanup__cb, &sub);
setup(&sub);
cl_git_pass(git_path_direach(&sub.path,
one_entry,
&sub));
check_counts(&sub);
}
static walk_data sub_slash = {
"sub/",
sub_names,
GIT_BUF_INIT
};
/* traverse a slash-terminated subfolder */
void test_core_dirent__traverse_slash_terminated_folder(void)
{
cl_set_cleanup(&dirent_cleanup__cb, &sub_slash);
setup(&sub_slash);
cl_git_pass(git_path_direach(&sub_slash.path,
one_entry,
&sub_slash));
check_counts(&sub_slash);
}
static name_data empty_names[] = {
{ 0, NULL }
};
static walk_data empty = {
"empty",
empty_names,
GIT_BUF_INIT
};
/* make sure that empty folders are not traversed */
void test_core_dirent__dont_traverse_empty_folders(void)
{
cl_set_cleanup(&dirent_cleanup__cb, &empty);
setup(&empty);
cl_git_pass(git_path_direach(&empty.path,
one_entry,
&empty));
check_counts(&empty);
/* make sure callback not called */
cl_git_pass(git_path_direach(&empty.path,
dont_call_me,
&empty));
}
static name_data odd_names[] = {
{ 0, "odd/.a" },
{ 0, "odd/..c" },
/* the following don't work on cygwin/win32 */
/* { 0, "odd/.b." }, */
/* { 0, "odd/..d.." }, */
{ 0, NULL }
};
static walk_data odd = {
"odd",
odd_names,
GIT_BUF_INIT
};
/* make sure that strange looking filenames ('..c') are traversed */
void test_core_dirent__traverse_weird_filenames(void)
{
cl_set_cleanup(&dirent_cleanup__cb, &odd);
setup(&odd);
cl_git_pass(git_path_direach(&odd.path,
one_entry,
&odd));
check_counts(&odd);
}