]>
Commit | Line | Data |
---|---|---|
3fd1520c | 1 | #include "clar_libgit2.h" |
22a2d3d5 | 2 | #include "futils.h" |
e579e0f7 MB |
3 | #include "fs_path.h" |
4 | ||
5 | static char *path_save; | |
6 | ||
7 | void test_core_path__initialize(void) | |
8 | { | |
9 | path_save = cl_getenv("PATH"); | |
10 | } | |
11 | ||
12 | void test_core_path__cleanup(void) | |
13 | { | |
14 | cl_setenv("PATH", path_save); | |
15 | git__free(path_save); | |
16 | path_save = NULL; | |
17 | } | |
f1558d9b VM |
18 | |
19 | static void | |
20 | check_dirname(const char *A, const char *B) | |
21 | { | |
e579e0f7 | 22 | git_str dir = GIT_STR_INIT; |
97769280 | 23 | char *dir2; |
f1558d9b | 24 | |
e579e0f7 | 25 | cl_assert(git_fs_path_dirname_r(&dir, A) >= 0); |
1a6e8f8a | 26 | cl_assert_equal_s(B, dir.ptr); |
e579e0f7 | 27 | git_str_dispose(&dir); |
f1558d9b | 28 | |
e579e0f7 | 29 | cl_assert((dir2 = git_fs_path_dirname(A)) != NULL); |
1a6e8f8a | 30 | cl_assert_equal_s(B, dir2); |
3286c408 | 31 | git__free(dir2); |
f1558d9b VM |
32 | } |
33 | ||
34 | static void | |
35 | check_basename(const char *A, const char *B) | |
36 | { | |
e579e0f7 | 37 | git_str base = GIT_STR_INIT; |
97769280 | 38 | char *base2; |
f1558d9b | 39 | |
e579e0f7 | 40 | cl_assert(git_fs_path_basename_r(&base, A) >= 0); |
1a6e8f8a | 41 | cl_assert_equal_s(B, base.ptr); |
e579e0f7 | 42 | git_str_dispose(&base); |
f1558d9b | 43 | |
e579e0f7 | 44 | cl_assert((base2 = git_fs_path_basename(A)) != NULL); |
1a6e8f8a | 45 | cl_assert_equal_s(B, base2); |
3286c408 | 46 | git__free(base2); |
f1558d9b VM |
47 | } |
48 | ||
f1558d9b VM |
49 | static void |
50 | check_joinpath(const char *path_a, const char *path_b, const char *expected_path) | |
51 | { | |
e579e0f7 | 52 | git_str joined_path = GIT_STR_INIT; |
f1558d9b | 53 | |
e579e0f7 | 54 | cl_git_pass(git_str_joinpath(&joined_path, path_a, path_b)); |
1a6e8f8a | 55 | cl_assert_equal_s(expected_path, joined_path.ptr); |
97769280 | 56 | |
e579e0f7 | 57 | git_str_dispose(&joined_path); |
f1558d9b VM |
58 | } |
59 | ||
60 | static void | |
61 | check_joinpath_n( | |
62 | const char *path_a, | |
63 | const char *path_b, | |
64 | const char *path_c, | |
65 | const char *path_d, | |
66 | const char *expected_path) | |
67 | { | |
e579e0f7 | 68 | git_str joined_path = GIT_STR_INIT; |
97769280 | 69 | |
e579e0f7 | 70 | cl_git_pass(git_str_join_n(&joined_path, '/', 4, |
97769280 | 71 | path_a, path_b, path_c, path_d)); |
1a6e8f8a | 72 | cl_assert_equal_s(expected_path, joined_path.ptr); |
f1558d9b | 73 | |
e579e0f7 | 74 | git_str_dispose(&joined_path); |
f1558d9b VM |
75 | } |
76 | ||
e579e0f7 MB |
77 | static void check_setenv(const char* name, const char* value) |
78 | { | |
79 | char* check; | |
80 | ||
81 | cl_git_pass(cl_setenv(name, value)); | |
82 | check = cl_getenv(name); | |
83 | ||
84 | if (value) | |
85 | cl_assert_equal_s(value, check); | |
86 | else | |
87 | cl_assert(check == NULL); | |
88 | ||
89 | git__free(check); | |
90 | } | |
f1558d9b VM |
91 | |
92 | /* get the dirname of a path */ | |
2017a15d | 93 | void test_core_path__00_dirname(void) |
f1558d9b | 94 | { |
f1558d9b VM |
95 | check_dirname(NULL, "."); |
96 | check_dirname("", "."); | |
97 | check_dirname("a", "."); | |
98 | check_dirname("/", "/"); | |
99 | check_dirname("/usr", "/"); | |
100 | check_dirname("/usr/", "/"); | |
101 | check_dirname("/usr/lib", "/usr"); | |
102 | check_dirname("/usr/lib/", "/usr"); | |
103 | check_dirname("/usr/lib//", "/usr"); | |
104 | check_dirname("usr/lib", "usr"); | |
105 | check_dirname("usr/lib/", "usr"); | |
106 | check_dirname("usr/lib//", "usr"); | |
107 | check_dirname(".git/", "."); | |
97769280 RB |
108 | |
109 | check_dirname(REP16("/abc"), REP15("/abc")); | |
34b6f05f | 110 | |
111 | #ifdef GIT_WIN32 | |
5d59520c | 112 | check_dirname("C:/", "C:/"); |
9e8d75c7 | 113 | check_dirname("C:", "C:/"); |
34b6f05f | 114 | check_dirname("C:/path/", "C:/"); |
115 | check_dirname("C:/path", "C:/"); | |
5d59520c | 116 | check_dirname("//computername/", "//computername/"); |
9e8d75c7 | 117 | check_dirname("//computername", "//computername/"); |
50a762a5 | 118 | check_dirname("//computername/path/", "//computername/"); |
119 | check_dirname("//computername/path", "//computername/"); | |
120 | check_dirname("//computername/sub/path/", "//computername/sub"); | |
121 | check_dirname("//computername/sub/path", "//computername/sub"); | |
34b6f05f | 122 | #endif |
f1558d9b VM |
123 | } |
124 | ||
125 | /* get the base name of a path */ | |
2017a15d | 126 | void test_core_path__01_basename(void) |
f1558d9b VM |
127 | { |
128 | check_basename(NULL, "."); | |
129 | check_basename("", "."); | |
130 | check_basename("a", "a"); | |
131 | check_basename("/", "/"); | |
132 | check_basename("/usr", "usr"); | |
133 | check_basename("/usr/", "usr"); | |
134 | check_basename("/usr/lib", "lib"); | |
135 | check_basename("/usr/lib//", "lib"); | |
136 | check_basename("usr/lib", "lib"); | |
97769280 RB |
137 | |
138 | check_basename(REP16("/abc"), "abc"); | |
139 | check_basename(REP1024("/abc"), "abc"); | |
f1558d9b VM |
140 | } |
141 | ||
f1558d9b | 142 | /* properly join path components */ |
2017a15d | 143 | void test_core_path__05_joins(void) |
f1558d9b VM |
144 | { |
145 | check_joinpath("", "", ""); | |
146 | check_joinpath("", "a", "a"); | |
147 | check_joinpath("", "/a", "/a"); | |
148 | check_joinpath("a", "", "a/"); | |
149 | check_joinpath("a", "/", "a/"); | |
150 | check_joinpath("a", "b", "a/b"); | |
151 | check_joinpath("/", "a", "/a"); | |
152 | check_joinpath("/", "", "/"); | |
153 | check_joinpath("/a", "/b", "/a/b"); | |
154 | check_joinpath("/a", "/b/", "/a/b/"); | |
155 | check_joinpath("/a/", "b/", "/a/b/"); | |
156 | check_joinpath("/a/", "/b/", "/a/b/"); | |
97769280 RB |
157 | |
158 | check_joinpath("/abcd", "/defg", "/abcd/defg"); | |
159 | check_joinpath("/abcd", "/defg/", "/abcd/defg/"); | |
160 | check_joinpath("/abcd/", "defg/", "/abcd/defg/"); | |
161 | check_joinpath("/abcd/", "/defg/", "/abcd/defg/"); | |
162 | ||
163 | check_joinpath("/abcdefgh", "/12345678", "/abcdefgh/12345678"); | |
164 | check_joinpath("/abcdefgh", "/12345678/", "/abcdefgh/12345678/"); | |
165 | check_joinpath("/abcdefgh/", "12345678/", "/abcdefgh/12345678/"); | |
166 | ||
b5daae68 RB |
167 | check_joinpath(REP1024("aaaa"), "", REP1024("aaaa") "/"); |
168 | check_joinpath(REP1024("aaaa/"), "", REP1024("aaaa/")); | |
169 | check_joinpath(REP1024("/aaaa"), "", REP1024("/aaaa") "/"); | |
170 | ||
97769280 RB |
171 | check_joinpath(REP1024("aaaa"), REP1024("bbbb"), |
172 | REP1024("aaaa") "/" REP1024("bbbb")); | |
173 | check_joinpath(REP1024("/aaaa"), REP1024("/bbbb"), | |
174 | REP1024("/aaaa") REP1024("/bbbb")); | |
f1558d9b VM |
175 | } |
176 | ||
177 | /* properly join path components for more than one path */ | |
2017a15d | 178 | void test_core_path__06_long_joins(void) |
f1558d9b VM |
179 | { |
180 | check_joinpath_n("", "", "", "", ""); | |
181 | check_joinpath_n("", "a", "", "", "a/"); | |
182 | check_joinpath_n("a", "", "", "", "a/"); | |
183 | check_joinpath_n("", "", "", "a", "a"); | |
184 | check_joinpath_n("a", "b", "", "/c/d/", "a/b/c/d/"); | |
185 | check_joinpath_n("a", "b", "", "/c/d", "a/b/c/d"); | |
97769280 RB |
186 | check_joinpath_n("abcd", "efgh", "ijkl", "mnop", "abcd/efgh/ijkl/mnop"); |
187 | check_joinpath_n("abcd/", "efgh/", "ijkl/", "mnop/", "abcd/efgh/ijkl/mnop/"); | |
188 | check_joinpath_n("/abcd/", "/efgh/", "/ijkl/", "/mnop/", "/abcd/efgh/ijkl/mnop/"); | |
189 | ||
190 | check_joinpath_n(REP1024("a"), REP1024("b"), REP1024("c"), REP1024("d"), | |
191 | REP1024("a") "/" REP1024("b") "/" | |
192 | REP1024("c") "/" REP1024("d")); | |
193 | check_joinpath_n(REP1024("/a"), REP1024("/b"), REP1024("/c"), REP1024("/d"), | |
194 | REP1024("/a") REP1024("/b") | |
195 | REP1024("/c") REP1024("/d")); | |
196 | } | |
197 | ||
198 | ||
199 | static void | |
200 | check_path_to_dir( | |
201 | const char* path, | |
202 | const char* expected) | |
203 | { | |
e579e0f7 | 204 | git_str tgt = GIT_STR_INIT; |
97769280 | 205 | |
e579e0f7 MB |
206 | git_str_sets(&tgt, path); |
207 | cl_git_pass(git_fs_path_to_dir(&tgt)); | |
1a6e8f8a | 208 | cl_assert_equal_s(expected, tgt.ptr); |
97769280 | 209 | |
e579e0f7 | 210 | git_str_dispose(&tgt); |
97769280 RB |
211 | } |
212 | ||
213 | static void | |
214 | check_string_to_dir( | |
215 | const char* path, | |
1a6e8f8a | 216 | size_t maxlen, |
97769280 RB |
217 | const char* expected) |
218 | { | |
1a6e8f8a | 219 | size_t len = strlen(path); |
97769280 | 220 | char *buf = git__malloc(len + 2); |
1a6e8f8a RB |
221 | cl_assert(buf); |
222 | ||
97769280 RB |
223 | strncpy(buf, path, len + 2); |
224 | ||
e579e0f7 | 225 | git_fs_path_string_to_dir(buf, maxlen); |
97769280 | 226 | |
1a6e8f8a | 227 | cl_assert_equal_s(expected, buf); |
97769280 RB |
228 | |
229 | git__free(buf); | |
230 | } | |
231 | ||
232 | /* convert paths to dirs */ | |
2017a15d | 233 | void test_core_path__07_path_to_dir(void) |
97769280 RB |
234 | { |
235 | check_path_to_dir("", ""); | |
236 | check_path_to_dir(".", "./"); | |
237 | check_path_to_dir("./", "./"); | |
238 | check_path_to_dir("a/", "a/"); | |
239 | check_path_to_dir("ab", "ab/"); | |
240 | /* make sure we try just under and just over an expansion that will | |
241 | * require a realloc | |
242 | */ | |
243 | check_path_to_dir("abcdef", "abcdef/"); | |
244 | check_path_to_dir("abcdefg", "abcdefg/"); | |
245 | check_path_to_dir("abcdefgh", "abcdefgh/"); | |
246 | check_path_to_dir("abcdefghi", "abcdefghi/"); | |
247 | check_path_to_dir(REP1024("abcd") "/", REP1024("abcd") "/"); | |
248 | check_path_to_dir(REP1024("abcd"), REP1024("abcd") "/"); | |
249 | ||
250 | check_string_to_dir("", 1, ""); | |
251 | check_string_to_dir(".", 1, "."); | |
252 | check_string_to_dir(".", 2, "./"); | |
253 | check_string_to_dir(".", 3, "./"); | |
254 | check_string_to_dir("abcd", 3, "abcd"); | |
255 | check_string_to_dir("abcd", 4, "abcd"); | |
256 | check_string_to_dir("abcd", 5, "abcd/"); | |
257 | check_string_to_dir("abcd", 6, "abcd/"); | |
f1558d9b | 258 | } |
b5daae68 RB |
259 | |
260 | /* join path to itself */ | |
2017a15d | 261 | void test_core_path__08_self_join(void) |
b5daae68 | 262 | { |
e579e0f7 | 263 | git_str path = GIT_STR_INIT; |
13224ea4 | 264 | size_t asize = 0; |
b5daae68 RB |
265 | |
266 | asize = path.asize; | |
e579e0f7 | 267 | cl_git_pass(git_str_sets(&path, "/foo")); |
1a6e8f8a | 268 | cl_assert_equal_s(path.ptr, "/foo"); |
b5daae68 RB |
269 | cl_assert(asize < path.asize); |
270 | ||
271 | asize = path.asize; | |
e579e0f7 | 272 | cl_git_pass(git_str_joinpath(&path, path.ptr, "this is a new string")); |
1a6e8f8a | 273 | cl_assert_equal_s(path.ptr, "/foo/this is a new string"); |
b5daae68 RB |
274 | cl_assert(asize < path.asize); |
275 | ||
276 | asize = path.asize; | |
e579e0f7 | 277 | cl_git_pass(git_str_joinpath(&path, path.ptr, "/grow the buffer, grow the buffer, grow the buffer")); |
1a6e8f8a | 278 | cl_assert_equal_s(path.ptr, "/foo/this is a new string/grow the buffer, grow the buffer, grow the buffer"); |
b5daae68 RB |
279 | cl_assert(asize < path.asize); |
280 | ||
e579e0f7 MB |
281 | git_str_dispose(&path); |
282 | cl_git_pass(git_str_sets(&path, "/foo/bar")); | |
b5daae68 | 283 | |
e579e0f7 | 284 | cl_git_pass(git_str_joinpath(&path, path.ptr + 4, "baz")); |
1a6e8f8a | 285 | cl_assert_equal_s(path.ptr, "/bar/baz"); |
b5daae68 RB |
286 | |
287 | asize = path.asize; | |
e579e0f7 | 288 | cl_git_pass(git_str_joinpath(&path, path.ptr + 4, "somethinglongenoughtorealloc")); |
1a6e8f8a | 289 | cl_assert_equal_s(path.ptr, "/baz/somethinglongenoughtorealloc"); |
b5daae68 | 290 | cl_assert(asize < path.asize); |
c25aa7cd | 291 | |
e579e0f7 | 292 | git_str_dispose(&path); |
b5daae68 | 293 | } |
459e2dcd | 294 | |
295 | static void check_percent_decoding(const char *expected_result, const char *input) | |
296 | { | |
e579e0f7 | 297 | git_str buf = GIT_STR_INIT; |
459e2dcd | 298 | |
299 | cl_git_pass(git__percent_decode(&buf, input)); | |
e579e0f7 | 300 | cl_assert_equal_s(expected_result, git_str_cstr(&buf)); |
459e2dcd | 301 | |
e579e0f7 | 302 | git_str_dispose(&buf); |
459e2dcd | 303 | } |
304 | ||
2017a15d | 305 | void test_core_path__09_percent_decode(void) |
459e2dcd | 306 | { |
307 | check_percent_decoding("abcd", "abcd"); | |
308 | check_percent_decoding("a2%", "a2%"); | |
309 | check_percent_decoding("a2%3", "a2%3"); | |
310 | check_percent_decoding("a2%%3", "a2%%3"); | |
311 | check_percent_decoding("a2%3z", "a2%3z"); | |
312 | check_percent_decoding("a,", "a%2c"); | |
313 | check_percent_decoding("a21", "a2%31"); | |
314 | check_percent_decoding("a2%1", "a2%%31"); | |
315 | check_percent_decoding("a bc ", "a%20bc%20"); | |
316 | check_percent_decoding("Vicent Mart" "\355", "Vicent%20Mart%ED"); | |
317 | } | |
2017a15d | 318 | |
319 | static void check_fromurl(const char *expected_result, const char *input, int should_fail) | |
320 | { | |
e579e0f7 | 321 | git_str buf = GIT_STR_INIT; |
2017a15d | 322 | |
323 | assert(should_fail || expected_result); | |
324 | ||
325 | if (!should_fail) { | |
e579e0f7 MB |
326 | cl_git_pass(git_fs_path_fromurl(&buf, input)); |
327 | cl_assert_equal_s(expected_result, git_str_cstr(&buf)); | |
2017a15d | 328 | } else |
e579e0f7 | 329 | cl_git_fail(git_fs_path_fromurl(&buf, input)); |
2017a15d | 330 | |
e579e0f7 | 331 | git_str_dispose(&buf); |
2017a15d | 332 | } |
333 | ||
8c29dca6 | 334 | #ifdef GIT_WIN32 |
2017a15d | 335 | #define ABS_PATH_MARKER "" |
336 | #else | |
337 | #define ABS_PATH_MARKER "/" | |
338 | #endif | |
339 | ||
340 | void test_core_path__10_fromurl(void) | |
341 | { | |
342 | /* Failing cases */ | |
343 | check_fromurl(NULL, "a", 1); | |
344 | check_fromurl(NULL, "http:///c:/Temp%20folder/note.txt", 1); | |
345 | check_fromurl(NULL, "file://c:/Temp%20folder/note.txt", 1); | |
346 | check_fromurl(NULL, "file:////c:/Temp%20folder/note.txt", 1); | |
347 | check_fromurl(NULL, "file:///", 1); | |
348 | check_fromurl(NULL, "file:////", 1); | |
349 | check_fromurl(NULL, "file://servername/c:/Temp%20folder/note.txt", 1); | |
350 | ||
351 | /* Passing cases */ | |
352 | check_fromurl(ABS_PATH_MARKER "c:/Temp folder/note.txt", "file:///c:/Temp%20folder/note.txt", 0); | |
353 | check_fromurl(ABS_PATH_MARKER "c:/Temp folder/note.txt", "file://localhost/c:/Temp%20folder/note.txt", 0); | |
354 | check_fromurl(ABS_PATH_MARKER "c:/Temp+folder/note.txt", "file:///c:/Temp+folder/note.txt", 0); | |
355 | check_fromurl(ABS_PATH_MARKER "a", "file:///a", 0); | |
356 | } | |
df743c7d | 357 | |
0cfcff5d RB |
358 | typedef struct { |
359 | int expect_idx; | |
dab89f9b | 360 | int cancel_after; |
0cfcff5d RB |
361 | char **expect; |
362 | } check_walkup_info; | |
363 | ||
25e0b157 RB |
364 | #define CANCEL_VALUE 1234 |
365 | ||
bbb988a5 | 366 | static int check_one_walkup_step(void *ref, const char *path) |
0cfcff5d RB |
367 | { |
368 | check_walkup_info *info = (check_walkup_info *)ref; | |
dab89f9b RB |
369 | |
370 | if (!info->cancel_after) { | |
371 | cl_assert_equal_s(info->expect[info->expect_idx], "[CANCEL]"); | |
25e0b157 | 372 | return CANCEL_VALUE; |
dab89f9b RB |
373 | } |
374 | info->cancel_after--; | |
375 | ||
0cfcff5d | 376 | cl_assert(info->expect[info->expect_idx] != NULL); |
bbb988a5 | 377 | cl_assert_equal_s(info->expect[info->expect_idx], path); |
0cfcff5d | 378 | info->expect_idx++; |
dab89f9b | 379 | |
0d0fa7c3 | 380 | return 0; |
0cfcff5d RB |
381 | } |
382 | ||
df743c7d RB |
383 | void test_core_path__11_walkup(void) |
384 | { | |
e579e0f7 | 385 | git_str p = GIT_STR_INIT; |
bbb988a5 | 386 | |
df743c7d | 387 | char *expect[] = { |
bbb988a5 T |
388 | /* 1 */ "/a/b/c/d/e/", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL, |
389 | /* 2 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL, | |
390 | /* 3 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL, | |
391 | /* 4 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL, | |
392 | /* 5 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", NULL, | |
393 | /* 6 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", NULL, | |
394 | /* 7 */ "this_is_a_path", "", NULL, | |
395 | /* 8 */ "this_is_a_path/", "", NULL, | |
396 | /* 9 */ "///a///b///c///d///e///", "///a///b///c///d///", "///a///b///c///", "///a///b///", "///a///", "///", NULL, | |
397 | /* 10 */ "a/b/c/", "a/b/", "a/", "", NULL, | |
398 | /* 11 */ "a/b/c", "a/b/", "a/", "", NULL, | |
399 | /* 12 */ "a/b/c/", "a/b/", "a/", NULL, | |
400 | /* 13 */ "", NULL, | |
401 | /* 14 */ "/", NULL, | |
402 | /* 15 */ NULL | |
403 | }; | |
404 | ||
405 | char *root[] = { | |
406 | /* 1 */ NULL, | |
407 | /* 2 */ NULL, | |
408 | /* 3 */ "/", | |
409 | /* 4 */ "", | |
410 | /* 5 */ "/a/b", | |
411 | /* 6 */ "/a/b/", | |
412 | /* 7 */ NULL, | |
413 | /* 8 */ NULL, | |
414 | /* 9 */ NULL, | |
415 | /* 10 */ NULL, | |
416 | /* 11 */ NULL, | |
417 | /* 12 */ "a/", | |
418 | /* 13 */ NULL, | |
419 | /* 14 */ NULL, | |
df743c7d | 420 | }; |
bbb988a5 | 421 | |
df743c7d | 422 | int i, j; |
0cfcff5d RB |
423 | check_walkup_info info; |
424 | ||
425 | info.expect = expect; | |
dab89f9b | 426 | info.cancel_after = -1; |
df743c7d RB |
427 | |
428 | for (i = 0, j = 0; expect[i] != NULL; i++, j++) { | |
df743c7d | 429 | |
e579e0f7 | 430 | git_str_sets(&p, expect[i]); |
df743c7d | 431 | |
0cfcff5d RB |
432 | info.expect_idx = i; |
433 | cl_git_pass( | |
e579e0f7 | 434 | git_fs_path_walk_up(&p, root[j], check_one_walkup_step, &info) |
0cfcff5d | 435 | ); |
df743c7d | 436 | |
1a6e8f8a | 437 | cl_assert_equal_s(p.ptr, expect[i]); |
bbb988a5 T |
438 | cl_assert(expect[info.expect_idx] == NULL); |
439 | i = info.expect_idx; | |
dab89f9b RB |
440 | } |
441 | ||
e579e0f7 | 442 | git_str_dispose(&p); |
dab89f9b RB |
443 | } |
444 | ||
445 | void test_core_path__11a_walkup_cancel(void) | |
446 | { | |
e579e0f7 | 447 | git_str p = GIT_STR_INIT; |
dab89f9b RB |
448 | int cancel[] = { 3, 2, 1, 0 }; |
449 | char *expect[] = { | |
450 | "/a/b/c/d/e/", "/a/b/c/d/", "/a/b/c/", "[CANCEL]", NULL, | |
451 | "/a/b/c/d/e", "/a/b/c/d/", "[CANCEL]", NULL, | |
452 | "/a/b/c/d/e", "[CANCEL]", NULL, | |
453 | "[CANCEL]", NULL, | |
454 | NULL | |
455 | }; | |
456 | char *root[] = { NULL, NULL, "/", "", NULL }; | |
457 | int i, j; | |
458 | check_walkup_info info; | |
459 | ||
460 | info.expect = expect; | |
461 | ||
462 | for (i = 0, j = 0; expect[i] != NULL; i++, j++) { | |
463 | ||
e579e0f7 | 464 | git_str_sets(&p, expect[i]); |
dab89f9b RB |
465 | |
466 | info.cancel_after = cancel[j]; | |
467 | info.expect_idx = i; | |
468 | ||
469 | cl_assert_equal_i( | |
25e0b157 | 470 | CANCEL_VALUE, |
e579e0f7 | 471 | git_fs_path_walk_up(&p, root[j], check_one_walkup_step, &info) |
dab89f9b RB |
472 | ); |
473 | ||
df743c7d RB |
474 | /* skip to next run of expectations */ |
475 | while (expect[i] != NULL) i++; | |
476 | } | |
477 | ||
e579e0f7 | 478 | git_str_dispose(&p); |
df743c7d | 479 | } |
7b93079b | 480 | |
481 | void test_core_path__12_offset_to_path_root(void) | |
482 | { | |
e579e0f7 MB |
483 | cl_assert(git_fs_path_root("non/rooted/path") == -1); |
484 | cl_assert(git_fs_path_root("/rooted/path") == 0); | |
7b93079b | 485 | |
486 | #ifdef GIT_WIN32 | |
487 | /* Windows specific tests */ | |
e579e0f7 MB |
488 | cl_assert(git_fs_path_root("C:non/rooted/path") == -1); |
489 | cl_assert(git_fs_path_root("C:/rooted/path") == 2); | |
490 | cl_assert(git_fs_path_root("//computername/sharefolder/resource") == 14); | |
491 | cl_assert(git_fs_path_root("//computername/sharefolder") == 14); | |
492 | cl_assert(git_fs_path_root("//computername") == -1); | |
7b93079b | 493 | #endif |
494 | } | |
9abb5bca | 495 | |
496 | #define NON_EXISTING_FILEPATH "i_hope_i_do_not_exist" | |
497 | ||
498 | void test_core_path__13_cannot_prettify_a_non_existing_file(void) | |
499 | { | |
e579e0f7 | 500 | git_str p = GIT_STR_INIT; |
9abb5bca | 501 | |
e579e0f7 MB |
502 | cl_assert_equal_b(git_fs_path_exists(NON_EXISTING_FILEPATH), false); |
503 | cl_assert_equal_i(GIT_ENOTFOUND, git_fs_path_prettify(&p, NON_EXISTING_FILEPATH, NULL)); | |
504 | cl_assert_equal_i(GIT_ENOTFOUND, git_fs_path_prettify(&p, NON_EXISTING_FILEPATH "/so-do-i", NULL)); | |
9abb5bca | 505 | |
e579e0f7 | 506 | git_str_dispose(&p); |
9abb5bca | 507 | } |
b0fe1129 RB |
508 | |
509 | void test_core_path__14_apply_relative(void) | |
510 | { | |
e579e0f7 | 511 | git_str p = GIT_STR_INIT; |
b0fe1129 | 512 | |
e579e0f7 | 513 | cl_git_pass(git_str_sets(&p, "/this/is/a/base")); |
b0fe1129 | 514 | |
e579e0f7 | 515 | cl_git_pass(git_fs_path_apply_relative(&p, "../test")); |
b0fe1129 RB |
516 | cl_assert_equal_s("/this/is/a/test", p.ptr); |
517 | ||
e579e0f7 | 518 | cl_git_pass(git_fs_path_apply_relative(&p, "../../the/./end")); |
b0fe1129 RB |
519 | cl_assert_equal_s("/this/is/the/end", p.ptr); |
520 | ||
e579e0f7 | 521 | cl_git_pass(git_fs_path_apply_relative(&p, "./of/this/../the/string")); |
b0fe1129 RB |
522 | cl_assert_equal_s("/this/is/the/end/of/the/string", p.ptr); |
523 | ||
e579e0f7 | 524 | cl_git_pass(git_fs_path_apply_relative(&p, "../../../../../..")); |
b0fe1129 RB |
525 | cl_assert_equal_s("/this/", p.ptr); |
526 | ||
e579e0f7 | 527 | cl_git_pass(git_fs_path_apply_relative(&p, "../")); |
b0fe1129 RB |
528 | cl_assert_equal_s("/", p.ptr); |
529 | ||
e579e0f7 | 530 | cl_git_fail(git_fs_path_apply_relative(&p, "../../..")); |
b0fe1129 RB |
531 | |
532 | ||
e579e0f7 | 533 | cl_git_pass(git_str_sets(&p, "d:/another/test")); |
b0fe1129 | 534 | |
e579e0f7 | 535 | cl_git_pass(git_fs_path_apply_relative(&p, "../..")); |
b0fe1129 RB |
536 | cl_assert_equal_s("d:/", p.ptr); |
537 | ||
e579e0f7 | 538 | cl_git_pass(git_fs_path_apply_relative(&p, "from/here/to/../and/./back/.")); |
b0fe1129 RB |
539 | cl_assert_equal_s("d:/from/here/and/back/", p.ptr); |
540 | ||
541 | ||
e579e0f7 | 542 | cl_git_pass(git_str_sets(&p, "https://my.url.com/test.git")); |
b0fe1129 | 543 | |
e579e0f7 | 544 | cl_git_pass(git_fs_path_apply_relative(&p, "../another.git")); |
b0fe1129 RB |
545 | cl_assert_equal_s("https://my.url.com/another.git", p.ptr); |
546 | ||
e579e0f7 | 547 | cl_git_pass(git_fs_path_apply_relative(&p, "../full/path/url.patch")); |
b0fe1129 RB |
548 | cl_assert_equal_s("https://my.url.com/full/path/url.patch", p.ptr); |
549 | ||
e579e0f7 | 550 | cl_git_pass(git_fs_path_apply_relative(&p, "..")); |
b0fe1129 RB |
551 | cl_assert_equal_s("https://my.url.com/full/path/", p.ptr); |
552 | ||
e579e0f7 | 553 | cl_git_pass(git_fs_path_apply_relative(&p, "../../../")); |
b0fe1129 RB |
554 | cl_assert_equal_s("https://", p.ptr); |
555 | ||
6d9a6c5c | 556 | |
e579e0f7 | 557 | cl_git_pass(git_str_sets(&p, "../../this/is/relative")); |
6d9a6c5c | 558 | |
e579e0f7 | 559 | cl_git_pass(git_fs_path_apply_relative(&p, "../../preserves/the/prefix")); |
6d9a6c5c NV |
560 | cl_assert_equal_s("../../this/preserves/the/prefix", p.ptr); |
561 | ||
e579e0f7 | 562 | cl_git_pass(git_fs_path_apply_relative(&p, "../../../../that")); |
6d9a6c5c NV |
563 | cl_assert_equal_s("../../that", p.ptr); |
564 | ||
e579e0f7 | 565 | cl_git_pass(git_fs_path_apply_relative(&p, "../there")); |
6d9a6c5c | 566 | cl_assert_equal_s("../../there", p.ptr); |
e579e0f7 | 567 | git_str_dispose(&p); |
b0fe1129 | 568 | } |
6d9a6c5c | 569 | |
0d1af399 | 570 | static void assert_resolve_relative( |
e579e0f7 | 571 | git_str *buf, const char *expected, const char *path) |
6d9a6c5c | 572 | { |
e579e0f7 MB |
573 | cl_git_pass(git_str_sets(buf, path)); |
574 | cl_git_pass(git_fs_path_resolve_relative(buf, 0)); | |
6d9a6c5c NV |
575 | cl_assert_equal_s(expected, buf->ptr); |
576 | } | |
577 | ||
578 | void test_core_path__15_resolve_relative(void) | |
579 | { | |
e579e0f7 | 580 | git_str buf = GIT_STR_INIT; |
6d9a6c5c NV |
581 | |
582 | assert_resolve_relative(&buf, "", ""); | |
583 | assert_resolve_relative(&buf, "", "."); | |
584 | assert_resolve_relative(&buf, "", "./"); | |
585 | assert_resolve_relative(&buf, "..", ".."); | |
586 | assert_resolve_relative(&buf, "../", "../"); | |
587 | assert_resolve_relative(&buf, "..", "./.."); | |
588 | assert_resolve_relative(&buf, "../", "./../"); | |
589 | assert_resolve_relative(&buf, "../", "../."); | |
590 | assert_resolve_relative(&buf, "../", ".././"); | |
591 | assert_resolve_relative(&buf, "../..", "../.."); | |
592 | assert_resolve_relative(&buf, "../../", "../../"); | |
593 | ||
594 | assert_resolve_relative(&buf, "/", "/"); | |
595 | assert_resolve_relative(&buf, "/", "/."); | |
596 | ||
597 | assert_resolve_relative(&buf, "", "a/.."); | |
598 | assert_resolve_relative(&buf, "", "a/../"); | |
599 | assert_resolve_relative(&buf, "", "a/../."); | |
600 | ||
601 | assert_resolve_relative(&buf, "/a", "/a"); | |
602 | assert_resolve_relative(&buf, "/a/", "/a/."); | |
603 | assert_resolve_relative(&buf, "/", "/a/../"); | |
604 | assert_resolve_relative(&buf, "/", "/a/../."); | |
605 | assert_resolve_relative(&buf, "/", "/a/.././"); | |
606 | ||
607 | assert_resolve_relative(&buf, "a", "a"); | |
608 | assert_resolve_relative(&buf, "a/", "a/"); | |
609 | assert_resolve_relative(&buf, "a/", "a/."); | |
610 | assert_resolve_relative(&buf, "a/", "a/./"); | |
611 | ||
612 | assert_resolve_relative(&buf, "a/b", "a//b"); | |
613 | assert_resolve_relative(&buf, "a/b/c", "a/b/c"); | |
614 | assert_resolve_relative(&buf, "b/c", "./b/c"); | |
615 | assert_resolve_relative(&buf, "a/c", "a/./c"); | |
616 | assert_resolve_relative(&buf, "a/b/", "a/b/."); | |
617 | ||
618 | assert_resolve_relative(&buf, "/a/b/c", "///a/b/c"); | |
6d9a6c5c NV |
619 | assert_resolve_relative(&buf, "/", "////"); |
620 | assert_resolve_relative(&buf, "/a", "///a"); | |
621 | assert_resolve_relative(&buf, "/", "///."); | |
622 | assert_resolve_relative(&buf, "/", "///a/.."); | |
623 | ||
624 | assert_resolve_relative(&buf, "../../path", "../../test//../././path"); | |
625 | assert_resolve_relative(&buf, "../d", "a/b/../../../c/../d"); | |
626 | ||
e579e0f7 MB |
627 | cl_git_pass(git_str_sets(&buf, "/..")); |
628 | cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); | |
6d9a6c5c | 629 | |
e579e0f7 MB |
630 | cl_git_pass(git_str_sets(&buf, "/./..")); |
631 | cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); | |
6d9a6c5c | 632 | |
e579e0f7 MB |
633 | cl_git_pass(git_str_sets(&buf, "/.//..")); |
634 | cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); | |
6d9a6c5c | 635 | |
e579e0f7 MB |
636 | cl_git_pass(git_str_sets(&buf, "/../.")); |
637 | cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); | |
6d9a6c5c | 638 | |
e579e0f7 MB |
639 | cl_git_pass(git_str_sets(&buf, "/../.././../a")); |
640 | cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); | |
6d9a6c5c | 641 | |
e579e0f7 MB |
642 | cl_git_pass(git_str_sets(&buf, "////..")); |
643 | cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); | |
6d9a6c5c | 644 | |
cae52938 RB |
645 | /* things that start with Windows network paths */ |
646 | #ifdef GIT_WIN32 | |
647 | assert_resolve_relative(&buf, "//a/b/c", "//a/b/c"); | |
648 | assert_resolve_relative(&buf, "//a/", "//a/b/.."); | |
649 | assert_resolve_relative(&buf, "//a/b/c", "//a/Q/../b/x/y/../../c"); | |
650 | ||
e579e0f7 MB |
651 | cl_git_pass(git_str_sets(&buf, "//a/b/../..")); |
652 | cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); | |
cae52938 RB |
653 | #else |
654 | assert_resolve_relative(&buf, "/a/b/c", "//a/b/c"); | |
655 | assert_resolve_relative(&buf, "/a/", "//a/b/.."); | |
656 | assert_resolve_relative(&buf, "/a/b/c", "//a/Q/../b/x/y/../../c"); | |
657 | assert_resolve_relative(&buf, "/", "//a/b/../.."); | |
658 | #endif | |
659 | ||
e579e0f7 | 660 | git_str_dispose(&buf); |
6d9a6c5c | 661 | } |
ba6f86eb ET |
662 | |
663 | #define assert_common_dirlen(i, p, q) \ | |
e579e0f7 | 664 | cl_assert_equal_i((i), git_fs_path_common_dirlen((p), (q))); |
ba6f86eb ET |
665 | |
666 | void test_core_path__16_resolve_relative(void) | |
667 | { | |
668 | assert_common_dirlen(0, "", ""); | |
669 | assert_common_dirlen(0, "", "bar.txt"); | |
670 | assert_common_dirlen(0, "foo.txt", "bar.txt"); | |
671 | assert_common_dirlen(0, "foo.txt", ""); | |
672 | assert_common_dirlen(0, "foo/bar.txt", "bar/foo.txt"); | |
673 | assert_common_dirlen(0, "foo/bar.txt", "../foo.txt"); | |
674 | ||
675 | assert_common_dirlen(1, "/one.txt", "/two.txt"); | |
676 | assert_common_dirlen(4, "foo/one.txt", "foo/two.txt"); | |
677 | assert_common_dirlen(5, "/foo/one.txt", "/foo/two.txt"); | |
678 | ||
679 | assert_common_dirlen(6, "a/b/c/foo.txt", "a/b/c/d/e/bar.txt"); | |
680 | assert_common_dirlen(7, "/a/b/c/foo.txt", "/a/b/c/d/e/bar.txt"); | |
681 | } | |
ac3d33df | 682 | |
e579e0f7 MB |
683 | static void fix_path(git_str *s) |
684 | { | |
685 | #ifndef GIT_WIN32 | |
686 | GIT_UNUSED(s); | |
687 | #else | |
688 | char* c; | |
689 | ||
690 | for (c = s->ptr; *c; c++) { | |
691 | if (*c == '/') | |
692 | *c = '\\'; | |
693 | } | |
694 | #endif | |
695 | } | |
696 | ||
697 | void test_core_path__find_exe_in_path(void) | |
698 | { | |
699 | char *orig_path; | |
700 | git_str sandbox_path = GIT_STR_INIT; | |
701 | git_str new_path = GIT_STR_INIT, full_path = GIT_STR_INIT, | |
702 | dummy_path = GIT_STR_INIT; | |
703 | ||
704 | #ifdef GIT_WIN32 | |
705 | static const char *bogus_path_1 = "c:\\does\\not\\exist\\"; | |
706 | static const char *bogus_path_2 = "e:\\non\\existent"; | |
707 | #else | |
708 | static const char *bogus_path_1 = "/this/path/does/not/exist/"; | |
709 | static const char *bogus_path_2 = "/non/existent"; | |
710 | #endif | |
711 | ||
712 | orig_path = cl_getenv("PATH"); | |
713 | ||
714 | git_str_puts(&sandbox_path, clar_sandbox_path()); | |
715 | git_str_joinpath(&dummy_path, sandbox_path.ptr, "dummmmmmmy_libgit2_file"); | |
716 | cl_git_rewritefile(dummy_path.ptr, "this is a dummy file"); | |
717 | ||
718 | fix_path(&sandbox_path); | |
719 | fix_path(&dummy_path); | |
720 | ||
721 | cl_git_pass(git_str_printf(&new_path, "%s%c%s%c%s%c%s", | |
722 | bogus_path_1, GIT_PATH_LIST_SEPARATOR, | |
723 | orig_path, GIT_PATH_LIST_SEPARATOR, | |
724 | sandbox_path.ptr, GIT_PATH_LIST_SEPARATOR, | |
725 | bogus_path_2)); | |
726 | ||
727 | check_setenv("PATH", new_path.ptr); | |
728 | ||
729 | cl_git_fail_with(GIT_ENOTFOUND, git_fs_path_find_executable(&full_path, "this_file_does_not_exist")); | |
730 | cl_git_pass(git_fs_path_find_executable(&full_path, "dummmmmmmy_libgit2_file")); | |
731 | ||
732 | cl_assert_equal_s(full_path.ptr, dummy_path.ptr); | |
733 | ||
734 | git_str_dispose(&full_path); | |
735 | git_str_dispose(&new_path); | |
736 | git_str_dispose(&dummy_path); | |
737 | git_str_dispose(&sandbox_path); | |
738 | git__free(orig_path); | |
739 | } | |
740 | ||
741 | void test_core_path__validate_current_user_ownership(void) | |
ac3d33df | 742 | { |
e579e0f7 MB |
743 | bool is_cur; |
744 | ||
745 | cl_must_pass(p_mkdir("testdir", 0777)); | |
746 | cl_git_pass(git_fs_path_owner_is_current_user(&is_cur, "testdir")); | |
747 | cl_assert_equal_i(is_cur, 1); | |
748 | ||
749 | cl_git_rewritefile("testfile", "This is a test file."); | |
750 | cl_git_pass(git_fs_path_owner_is_current_user(&is_cur, "testfile")); | |
751 | cl_assert_equal_i(is_cur, 1); | |
752 | ||
753 | #ifdef GIT_WIN32 | |
754 | cl_git_pass(git_fs_path_owner_is_current_user(&is_cur, "C:\\")); | |
755 | cl_assert_equal_i(is_cur, 0); | |
756 | ||
757 | cl_git_fail(git_fs_path_owner_is_current_user(&is_cur, "c:\\path\\does\\not\\exist")); | |
758 | #else | |
759 | cl_git_pass(git_fs_path_owner_is_current_user(&is_cur, "/")); | |
760 | cl_assert_equal_i(is_cur, 0); | |
761 | ||
762 | cl_git_fail(git_fs_path_owner_is_current_user(&is_cur, "/path/does/not/exist")); | |
763 | #endif | |
ac3d33df | 764 | } |