1 #include "clar_libgit2.h"
5 static git_repository
*repo
;
7 void test_refs_iterator__initialize(void)
9 repo
= cl_git_sandbox_init("testrepo.git");
12 void test_refs_iterator__cleanup(void)
14 cl_git_sandbox_cleanup();
17 static const char *refnames
[] = {
19 "refs/heads/cannot-fetch",
23 "refs/heads/not-good",
25 "refs/heads/packed-test",
26 "refs/heads/subtrees",
28 "refs/heads/track-local",
29 "refs/heads/trailing",
31 "refs/remotes/test/master",
32 "refs/tags/annotated_tag_to_blob",
35 "refs/tags/point_to_blob",
36 "refs/tags/taggerless",
38 "refs/tags/wrapped_tag",
42 static const char *refnames_with_symlink
[] = {
44 "refs/heads/cannot-fetch",
52 "refs/heads/not-good",
54 "refs/heads/packed-test",
55 "refs/heads/subtrees",
57 "refs/heads/track-local",
58 "refs/heads/trailing",
60 "refs/remotes/test/master",
61 "refs/tags/annotated_tag_to_blob",
64 "refs/tags/point_to_blob",
65 "refs/tags/taggerless",
67 "refs/tags/wrapped_tag",
71 static int refcmp_cb(const void *a
, const void *b
)
73 const git_reference
*refa
= (const git_reference
*)a
;
74 const git_reference
*refb
= (const git_reference
*)b
;
76 return strcmp(refa
->name
, refb
->name
);
79 static void assert_all_refnames_match(const char **expected
, git_vector
*names
)
84 git_vector_sort(names
);
86 git_vector_foreach(names
, i
, ref
) {
87 cl_assert(expected
[i
] != NULL
);
88 cl_assert_equal_s(expected
[i
], ref
->name
);
89 git_reference_free(ref
);
91 cl_assert(expected
[i
] == NULL
);
93 git_vector_free(names
);
96 void test_refs_iterator__list(void)
98 git_reference_iterator
*iter
;
102 cl_git_pass(git_vector_init(&output
, 32, &refcmp_cb
));
103 cl_git_pass(git_reference_iterator_new(&iter
, repo
));
106 int error
= git_reference_next(&ref
, iter
);
107 if (error
== GIT_ITEROVER
)
110 cl_git_pass(git_vector_insert(&output
, ref
));
113 git_reference_iterator_free(iter
);
115 assert_all_refnames_match(refnames
, &output
);
118 void test_refs_iterator__empty(void)
120 git_reference_iterator
*iter
;
123 git_repository
*empty
;
125 cl_git_pass(git_odb_new(&odb
));
126 cl_git_pass(git_repository_wrap_odb(&empty
, odb
));
128 cl_git_pass(git_reference_iterator_new(&iter
, empty
));
129 cl_assert_equal_i(GIT_ITEROVER
, git_reference_next(&ref
, iter
));
131 git_reference_iterator_free(iter
);
133 git_repository_free(empty
);
136 static int refs_foreach_cb(git_reference
*reference
, void *payload
)
138 git_vector
*output
= payload
;
139 cl_git_pass(git_vector_insert(output
, reference
));
143 void test_refs_iterator__foreach(void)
146 cl_git_pass(git_vector_init(&output
, 32, &refcmp_cb
));
147 cl_git_pass(git_reference_foreach(repo
, refs_foreach_cb
, &output
));
148 assert_all_refnames_match(refnames
, &output
);
151 void test_refs_iterator__foreach_through_symlink(void)
159 cl_git_pass(git_vector_init(&output
, 32, &refcmp_cb
));
161 cl_git_pass(p_mkdir("refs", 0777));
162 cl_git_mkfile("refs/a", "1234567890123456789012345678901234567890");
163 cl_git_mkfile("refs/b", "1234567890123456789012345678901234567890");
164 cl_git_mkfile("refs/c", "1234567890123456789012345678901234567890");
165 cl_git_mkfile("refs/d", "1234567890123456789012345678901234567890");
167 cl_git_pass(p_symlink("../../../refs", "testrepo.git/refs/heads/link"));
169 cl_git_pass(git_reference_foreach(repo
, refs_foreach_cb
, &output
));
170 assert_all_refnames_match(refnames_with_symlink
, &output
);
173 static int refs_foreach_cancel_cb(git_reference
*reference
, void *payload
)
175 int *cancel_after
= payload
;
177 git_reference_free(reference
);
185 void test_refs_iterator__foreach_can_cancel(void)
187 int cancel_after
= 3;
189 git_reference_foreach(repo
, refs_foreach_cancel_cb
, &cancel_after
),
191 cl_assert_equal_i(0, cancel_after
);
194 static int refs_foreach_name_cb(const char *name
, void *payload
)
196 git_vector
*output
= payload
;
197 cl_git_pass(git_vector_insert(output
, git__strdup(name
)));
201 void test_refs_iterator__foreach_name(void)
207 cl_git_pass(git_vector_init(&output
, 32, &git__strcmp_cb
));
209 git_reference_foreach_name(repo
, refs_foreach_name_cb
, &output
));
211 git_vector_sort(&output
);
213 git_vector_foreach(&output
, i
, name
) {
214 cl_assert(refnames
[i
] != NULL
);
215 cl_assert_equal_s(refnames
[i
], name
);
219 git_vector_free(&output
);
222 static int refs_foreach_name_cancel_cb(const char *name
, void *payload
)
224 int *cancel_after
= payload
;
232 void test_refs_iterator__foreach_name_can_cancel(void)
234 int cancel_after
= 5;
236 git_reference_foreach_name(
237 repo
, refs_foreach_name_cancel_cb
, &cancel_after
),
239 cl_assert_equal_i(0, cancel_after
);
242 void test_refs_iterator__concurrent_delete(void)
244 git_reference_iterator
*iter
;
245 size_t full_count
= 0, concurrent_count
= 0;
249 cl_git_sandbox_cleanup();
250 repo
= cl_git_sandbox_init("testrepo");
252 cl_git_pass(git_reference_iterator_new(&iter
, repo
));
253 while ((error
= git_reference_next_name(&name
, iter
)) == 0) {
257 git_reference_iterator_free(iter
);
258 cl_assert_equal_i(GIT_ITEROVER
, error
);
260 cl_git_pass(git_reference_iterator_new(&iter
, repo
));
261 while ((error
= git_reference_next_name(&name
, iter
)) == 0) {
262 cl_git_pass(git_reference_remove(repo
, name
));
266 git_reference_iterator_free(iter
);
267 cl_assert_equal_i(GIT_ITEROVER
, error
);
269 cl_assert_equal_i(full_count
, concurrent_count
);