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
[] = {
18 "refs/blobs/annotated_tag_to_blob",
20 "refs/heads/cannot-fetch",
24 "refs/heads/not-good",
26 "refs/heads/packed-test",
27 "refs/heads/subtrees",
29 "refs/heads/track-local",
30 "refs/heads/trailing",
32 "refs/remotes/test/master",
33 "refs/tags/annotated_tag_to_blob",
36 "refs/tags/point_to_blob",
37 "refs/tags/taggerless",
39 "refs/tags/wrapped_tag",
43 static const char *refnames_with_symlink
[] = {
44 "refs/blobs/annotated_tag_to_blob",
46 "refs/heads/cannot-fetch",
54 "refs/heads/not-good",
56 "refs/heads/packed-test",
57 "refs/heads/subtrees",
59 "refs/heads/track-local",
60 "refs/heads/trailing",
62 "refs/remotes/test/master",
63 "refs/tags/annotated_tag_to_blob",
66 "refs/tags/point_to_blob",
67 "refs/tags/taggerless",
69 "refs/tags/wrapped_tag",
73 static int refcmp_cb(const void *a
, const void *b
)
75 const git_reference
*refa
= (const git_reference
*)a
;
76 const git_reference
*refb
= (const git_reference
*)b
;
78 return strcmp(refa
->name
, refb
->name
);
81 static void assert_all_refnames_match(const char **expected
, git_vector
*names
)
86 git_vector_sort(names
);
88 git_vector_foreach(names
, i
, ref
) {
89 cl_assert(expected
[i
] != NULL
);
90 cl_assert_equal_s(expected
[i
], ref
->name
);
91 git_reference_free(ref
);
93 cl_assert(expected
[i
] == NULL
);
95 git_vector_free(names
);
98 void test_refs_iterator__list(void)
100 git_reference_iterator
*iter
;
104 cl_git_pass(git_vector_init(&output
, 33, &refcmp_cb
));
105 cl_git_pass(git_reference_iterator_new(&iter
, repo
));
108 int error
= git_reference_next(&ref
, iter
);
109 if (error
== GIT_ITEROVER
)
112 cl_git_pass(git_vector_insert(&output
, ref
));
115 git_reference_iterator_free(iter
);
117 assert_all_refnames_match(refnames
, &output
);
120 void test_refs_iterator__empty(void)
122 git_reference_iterator
*iter
;
125 git_repository
*empty
;
127 cl_git_pass(git_odb_new(&odb
));
128 cl_git_pass(git_repository_wrap_odb(&empty
, odb
));
130 cl_git_pass(git_reference_iterator_new(&iter
, empty
));
131 cl_assert_equal_i(GIT_ITEROVER
, git_reference_next(&ref
, iter
));
133 git_reference_iterator_free(iter
);
135 git_repository_free(empty
);
138 static int refs_foreach_cb(git_reference
*reference
, void *payload
)
140 git_vector
*output
= payload
;
141 cl_git_pass(git_vector_insert(output
, reference
));
145 void test_refs_iterator__foreach(void)
148 cl_git_pass(git_vector_init(&output
, 33, &refcmp_cb
));
149 cl_git_pass(git_reference_foreach(repo
, refs_foreach_cb
, &output
));
150 assert_all_refnames_match(refnames
, &output
);
153 void test_refs_iterator__foreach_through_symlink(void)
161 cl_git_pass(git_vector_init(&output
, 32, &refcmp_cb
));
163 cl_git_pass(p_mkdir("refs", 0777));
164 cl_git_mkfile("refs/a", "1234567890123456789012345678901234567890");
165 cl_git_mkfile("refs/b", "1234567890123456789012345678901234567890");
166 cl_git_mkfile("refs/c", "1234567890123456789012345678901234567890");
167 cl_git_mkfile("refs/d", "1234567890123456789012345678901234567890");
169 cl_git_pass(p_symlink("../../../refs", "testrepo.git/refs/heads/link"));
171 cl_git_pass(git_reference_foreach(repo
, refs_foreach_cb
, &output
));
172 assert_all_refnames_match(refnames_with_symlink
, &output
);
175 static int refs_foreach_cancel_cb(git_reference
*reference
, void *payload
)
177 int *cancel_after
= payload
;
179 git_reference_free(reference
);
187 void test_refs_iterator__foreach_can_cancel(void)
189 int cancel_after
= 3;
191 git_reference_foreach(repo
, refs_foreach_cancel_cb
, &cancel_after
),
193 cl_assert_equal_i(0, cancel_after
);
196 static int refs_foreach_name_cb(const char *name
, void *payload
)
198 git_vector
*output
= payload
;
199 cl_git_pass(git_vector_insert(output
, git__strdup(name
)));
203 void test_refs_iterator__foreach_name(void)
209 cl_git_pass(git_vector_init(&output
, 32, &git__strcmp_cb
));
211 git_reference_foreach_name(repo
, refs_foreach_name_cb
, &output
));
213 git_vector_sort(&output
);
215 git_vector_foreach(&output
, i
, name
) {
216 cl_assert(refnames
[i
] != NULL
);
217 cl_assert_equal_s(refnames
[i
], name
);
221 git_vector_free(&output
);
224 static int refs_foreach_name_cancel_cb(const char *name
, void *payload
)
226 int *cancel_after
= payload
;
234 void test_refs_iterator__foreach_name_can_cancel(void)
236 int cancel_after
= 5;
238 git_reference_foreach_name(
239 repo
, refs_foreach_name_cancel_cb
, &cancel_after
),
241 cl_assert_equal_i(0, cancel_after
);
244 void test_refs_iterator__concurrent_delete(void)
246 git_reference_iterator
*iter
;
247 size_t full_count
= 0, concurrent_count
= 0;
251 cl_git_sandbox_cleanup();
252 repo
= cl_git_sandbox_init("testrepo");
254 cl_git_pass(git_reference_iterator_new(&iter
, repo
));
255 while ((error
= git_reference_next_name(&name
, iter
)) == 0) {
259 git_reference_iterator_free(iter
);
260 cl_assert_equal_i(GIT_ITEROVER
, error
);
262 cl_git_pass(git_reference_iterator_new(&iter
, repo
));
263 while ((error
= git_reference_next_name(&name
, iter
)) == 0) {
264 cl_git_pass(git_reference_remove(repo
, name
));
268 git_reference_iterator_free(iter
);
269 cl_assert_equal_i(GIT_ITEROVER
, error
);
271 cl_assert_equal_i(full_count
, concurrent_count
);