summaryrefslogtreecommitdiff
path: root/tests-clar
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2012-08-03 17:08:01 -0700
committerRussell Belfer <rb@github.com>2012-08-03 17:08:01 -0700
commit5dca201072724e4230141796d7c9f8836a277de8 (patch)
tree7eb6b8f3e08c8abc608ee43c0ddc32d4d043a2c6 /tests-clar
parent2031760c626711cc69b4d63ac9798ff333583ca0 (diff)
downloadlibgit2-5dca201072724e4230141796d7c9f8836a277de8.tar.gz
Update iterators for consistency across library
This updates all the `foreach()` type functions across the library that take callbacks from the user to have a consistent behavior. The rules are: * A callback terminates the loop by returning any non-zero value * Once the callback returns non-zero, it will not be called again (i.e. the loop stops all iteration regardless of state) * If the callback returns non-zero, the parent fn returns GIT_EUSER * Although the parent returns GIT_EUSER, no error will be set in the library and `giterr_last()` will return NULL if called. This commit makes those changes across the library and adds tests for most of the iteration APIs to make sure that they follow the above rules.
Diffstat (limited to 'tests-clar')
-rw-r--r--tests-clar/attr/repo.c22
-rw-r--r--tests-clar/config/read.c2
-rw-r--r--tests-clar/diff/index.c50
-rw-r--r--tests-clar/notes/notes.c30
-rw-r--r--tests-clar/odb/foreach.c18
-rw-r--r--tests-clar/refs/branches/foreach.c25
-rw-r--r--tests-clar/refs/foreachglob.c22
-rw-r--r--tests-clar/status/worktree.c33
8 files changed, 196 insertions, 6 deletions
diff --git a/tests-clar/attr/repo.c b/tests-clar/attr/repo.c
index c37ff544a..4a317e4f3 100644
--- a/tests-clar/attr/repo.c
+++ b/tests-clar/attr/repo.c
@@ -113,6 +113,22 @@ static int count_attrs(
return 0;
}
+static int cancel_iteration(
+ const char *name,
+ const char *value,
+ void *payload)
+{
+ GIT_UNUSED(name);
+ GIT_UNUSED(value);
+
+ *((int *)payload) -= 1;
+
+ if (*((int *)payload) < 0)
+ return -1;
+
+ return 0;
+}
+
void test_attr_repo__foreach(void)
{
int count;
@@ -131,6 +147,12 @@ void test_attr_repo__foreach(void)
cl_git_pass(git_attr_foreach(g_repo, 0, "sub/subdir_test2.txt",
&count_attrs, &count));
cl_assert(count == 6); /* repoattr, rootattr, subattr, reposub, negattr, another */
+
+ count = 2;
+ cl_assert_equal_i(
+ GIT_EUSER, git_attr_foreach(
+ g_repo, 0, "sub/subdir_test1", &cancel_iteration, &count)
+ );
}
void test_attr_repo__manpage_example(void)
diff --git a/tests-clar/config/read.c b/tests-clar/config/read.c
index a8504da02..574ff8196 100644
--- a/tests-clar/config/read.c
+++ b/tests-clar/config/read.c
@@ -226,7 +226,7 @@ void test_config_read__foreach(void)
count = 3;
cl_git_fail(ret = git_config_foreach(cfg, cfg_callback_countdown, &count));
- cl_assert_equal_i(-100, ret);
+ cl_assert_equal_i(GIT_EUSER, ret);
git_config_free(cfg);
}
diff --git a/tests-clar/diff/index.c b/tests-clar/diff/index.c
index 171815df5..89e65e3b7 100644
--- a/tests-clar/diff/index.c
+++ b/tests-clar/diff/index.c
@@ -90,3 +90,53 @@ void test_diff_index__0(void)
git_tree_free(a);
git_tree_free(b);
}
+
+static int diff_stop_after_2_files(
+ void *cb_data,
+ git_diff_delta *delta,
+ float progress)
+{
+ diff_expects *e = cb_data;
+
+ GIT_UNUSED(progress);
+ GIT_UNUSED(delta);
+
+ e->files++;
+
+ return (e->files == 2);
+}
+
+void test_diff_index__1(void)
+{
+ /* grabbed a couple of commit oids from the history of the attr repo */
+ const char *a_commit = "26a125ee1bf"; /* the current HEAD */
+ const char *b_commit = "0017bd4ab1ec3"; /* the start */
+ git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit);
+ git_tree *b = resolve_commit_oid_to_tree(g_repo, b_commit);
+ git_diff_options opts = {0};
+ git_diff_list *diff = NULL;
+ diff_expects exp;
+
+ cl_assert(a);
+ cl_assert(b);
+
+ opts.context_lines = 1;
+ opts.interhunk_lines = 1;
+
+ memset(&exp, 0, sizeof(exp));
+
+ cl_git_pass(git_diff_index_to_tree(g_repo, &opts, a, &diff));
+
+ cl_assert_equal_i(
+ GIT_EUSER,
+ git_diff_foreach(diff, &exp, diff_stop_after_2_files, NULL, NULL)
+ );
+
+ cl_assert(exp.files == 2);
+
+ git_diff_list_free(diff);
+ diff = NULL;
+
+ git_tree_free(a);
+ git_tree_free(b);
+}
diff --git a/tests-clar/notes/notes.c b/tests-clar/notes/notes.c
index e1387782e..dfd7f5231 100644
--- a/tests-clar/notes/notes.c
+++ b/tests-clar/notes/notes.c
@@ -95,11 +95,39 @@ void test_notes_notes__can_retrieve_a_list_of_notes_for_a_given_namespace(void)
create_note(&note_oid3, "refs/notes/i-can-see-dead-notes", "9fd738e8f7967c078dceed8190330fc8648ee56a", "I decorate 9fd7 and 4a20\n");
create_note(&note_oid4, "refs/notes/i-can-see-dead-notes", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "I decorate 9fd7 and 4a20\n");
- cl_git_pass(git_note_foreach(_repo, "refs/notes/i-can-see-dead-notes", note_list_cb, &retrieved_notes));
+ cl_git_pass(git_note_foreach
+(_repo, "refs/notes/i-can-see-dead-notes", note_list_cb, &retrieved_notes));
cl_assert_equal_i(4, retrieved_notes);
}
+static int note_cancel_cb(git_note_data *note_data, void *payload)
+{
+ unsigned int *count = (unsigned int *)payload;
+
+ GIT_UNUSED(note_data);
+
+ (*count)++;
+
+ return (*count > 2);
+}
+
+void test_notes_notes__can_cancel_foreach(void)
+{
+ git_oid note_oid1, note_oid2, note_oid3, note_oid4;
+ unsigned int retrieved_notes = 0;
+
+ create_note(&note_oid1, "refs/notes/i-can-see-dead-notes", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "I decorate a65f\n");
+ create_note(&note_oid2, "refs/notes/i-can-see-dead-notes", "c47800c7266a2be04c571c04d5a6614691ea99bd", "I decorate c478\n");
+ create_note(&note_oid3, "refs/notes/i-can-see-dead-notes", "9fd738e8f7967c078dceed8190330fc8648ee56a", "I decorate 9fd7 and 4a20\n");
+ create_note(&note_oid4, "refs/notes/i-can-see-dead-notes", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "I decorate 9fd7 and 4a20\n");
+
+ cl_assert_equal_i(
+ GIT_EUSER,
+ git_note_foreach(_repo, "refs/notes/i-can-see-dead-notes",
+ note_cancel_cb, &retrieved_notes));
+}
+
void test_notes_notes__retrieving_a_list_of_notes_for_an_unknown_namespace_returns_ENOTFOUND(void)
{
int error;
diff --git a/tests-clar/odb/foreach.c b/tests-clar/odb/foreach.c
index 525c70c09..e025fa210 100644
--- a/tests-clar/odb/foreach.c
+++ b/tests-clar/odb/foreach.c
@@ -31,6 +31,24 @@ static int foreach_cb(git_oid *oid, void *data)
void test_odb_foreach__foreach(void)
{
+ nobj = 0;
cl_git_pass(git_odb_foreach(_odb, foreach_cb, NULL));
cl_assert(nobj == 1683);
}
+
+static int foreach_stop_cb(git_oid *oid, void *data)
+{
+ GIT_UNUSED(data);
+ GIT_UNUSED(oid);
+
+ nobj++;
+
+ return (nobj == 1000);
+}
+
+void test_odb_foreach__interrupt_foreach(void)
+{
+ nobj = 0;
+ cl_assert_equal_i(GIT_EUSER, git_odb_foreach(_odb, foreach_stop_cb, NULL));
+ cl_assert(nobj == 1000);
+}
diff --git a/tests-clar/refs/branches/foreach.c b/tests-clar/refs/branches/foreach.c
index b6e973799..8b39b7dc8 100644
--- a/tests-clar/refs/branches/foreach.c
+++ b/tests-clar/refs/branches/foreach.c
@@ -126,3 +126,28 @@ void test_refs_branches_foreach__retrieve_remote_symbolic_HEAD_when_present(void
assert_branch_has_been_found(exp, "nulltoken/HEAD");
assert_branch_has_been_found(exp, "nulltoken/HEAD");
}
+
+static int branch_list_interrupt_cb(
+ const char *branch_name, git_branch_t branch_type, void *payload)
+{
+ int *count;
+
+ GIT_UNUSED(branch_type);
+ GIT_UNUSED(branch_name);
+
+ count = (int *)payload;
+ (*count)++;
+
+ return (*count == 5);
+}
+
+void test_refs_branches_foreach__can_cancel(void)
+{
+ int count = 0;
+
+ cl_assert_equal_i(GIT_EUSER,
+ git_branch_foreach(repo, GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE,
+ branch_list_interrupt_cb, &count));
+
+ cl_assert_equal_i(5, count);
+}
diff --git a/tests-clar/refs/foreachglob.c b/tests-clar/refs/foreachglob.c
index d1412a94b..7d514d461 100644
--- a/tests-clar/refs/foreachglob.c
+++ b/tests-clar/refs/foreachglob.c
@@ -68,3 +68,25 @@ void test_refs_foreachglob__retrieve_partially_named_references(void)
assert_retrieval("*test*", GIT_REF_LISTALL, 4);
}
+
+
+static int interrupt_cb(const char *reference_name, void *payload)
+{
+ int *count = (int *)payload;
+
+ GIT_UNUSED(reference_name);
+
+ (*count)++;
+
+ return (*count == 11);
+}
+
+void test_refs_foreachglob__can_cancel(void)
+{
+ int count = 0;
+
+ cl_assert_equal_i(GIT_EUSER, git_reference_foreach_glob(
+ repo, "*", GIT_REF_LISTALL, interrupt_cb, &count) );
+
+ cl_assert_equal_i(11, count);
+}
diff --git a/tests-clar/status/worktree.c b/tests-clar/status/worktree.c
index d84cb77ed..bfd257a3b 100644
--- a/tests-clar/status/worktree.c
+++ b/tests-clar/status/worktree.c
@@ -530,7 +530,7 @@ void test_status_worktree__bracket_in_filename(void)
cl_git_pass(git_repository_init(&repo, "with_bracket", 0));
cl_git_mkfile("with_bracket/" FILE_WITH_BRACKET, "I have a bracket in my name\n");
-
+
/* file is new to working directory */
memset(&result, 0, sizeof(result));
@@ -578,7 +578,7 @@ void test_status_worktree__bracket_in_filename(void)
cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET));
cl_assert(status_flags == GIT_STATUS_INDEX_NEW);
-
+
/* Create file without bracket */
cl_git_mkfile("with_bracket/" FILE_WITHOUT_BRACKET, "I have no bracket in my name!\n");
@@ -591,7 +591,7 @@ void test_status_worktree__bracket_in_filename(void)
error = git_status_file(&status_flags, repo, FILE_WITH_BRACKET);
cl_git_fail(error);
- cl_assert(error == GIT_EAMBIGUOUS);
+ cl_assert_equal_i(GIT_EAMBIGUOUS, error);
git_index_free(index);
git_repository_free(repo);
@@ -769,6 +769,31 @@ void test_status_worktree__disable_pathspec_match(void)
cl_git_pass(
git_status_foreach_ext(repo, &opts, cb_status__expected_path, NULL)
);
-
+
git_repository_free(repo);
}
+
+
+static int cb_status__interrupt(const char *p, unsigned int s, void *payload)
+{
+ volatile int *count = (int *)payload;
+
+ GIT_UNUSED(p);
+ GIT_UNUSED(s);
+
+ (*count)++;
+
+ return (*count == 8);
+}
+
+void test_status_worktree__interruptable_foreach(void)
+{
+ int count = 0;
+ git_repository *repo = cl_git_sandbox_init("status");
+
+ cl_assert_equal_i(
+ GIT_EUSER, git_status_foreach(repo, cb_status__interrupt, &count)
+ );
+
+ cl_assert_equal_i(8, count);
+}