3 #include "testing/testing.h"
20 char path[
FILE_MAX] =
"/a/./b/./c/./";
22 EXPECT_STREQ(
"/a/b/c/", path);
28 EXPECT_STREQ(
"/", path);
34 EXPECT_STREQ(
"/a/b/", path);
41 EXPECT_STREQ(
"a/", path);
48 EXPECT_STREQ(
"./a/", path);
53 char path[
FILE_MAX] =
"/a/b/c/../../../";
55 EXPECT_STREQ(
"/", path);
59 char path[
FILE_MAX] =
"/a/../a/b/../b/c/../c/";
61 EXPECT_STREQ(
"/a/b/c/", path);
67 EXPECT_STREQ(
"/a/b/", path);
72 #define AT_INDEX(str_input, index_input, str_expect) \
74 char path[] = str_input; \
75 const char *expect = str_expect; \
76 int index_output, len_output; \
77 const bool ret = BLI_path_name_at_index(path, index_input, &index_output, &len_output); \
78 if (expect == NULL) { \
83 EXPECT_EQ(strlen(expect), len_output); \
84 path[index_output + len_output] = '\0'; \
85 EXPECT_STREQ(&path[index_output], expect); \
91 TEST(path_util, NameAtIndex_Single)
104 TEST(path_util, NameAtIndex_SingleNeg)
118 TEST(path_util, NameAtIndex_Double)
132 TEST(path_util, NameAtIndex_DoublNeg)
146 TEST(path_util, NameAtIndex_Misc)
148 AT_INDEX(
"/how/now/brown/cow", 0,
"how");
149 AT_INDEX(
"/how/now/brown/cow", 1,
"now");
150 AT_INDEX(
"/how/now/brown/cow", 2,
"brown");
151 AT_INDEX(
"/how/now/brown/cow", 3,
"cow");
152 AT_INDEX(
"/how/now/brown/cow", 4,
nullptr);
153 AT_INDEX(
"/how/now/brown/cow/", 4,
nullptr);
156 TEST(path_util, NameAtIndex_MiscNeg)
158 AT_INDEX(
"/how/now/brown/cow", 0,
"how");
159 AT_INDEX(
"/how/now/brown/cow", 1,
"now");
160 AT_INDEX(
"/how/now/brown/cow", 2,
"brown");
161 AT_INDEX(
"/how/now/brown/cow", 3,
"cow");
162 AT_INDEX(
"/how/now/brown/cow", 4,
nullptr);
163 AT_INDEX(
"/how/now/brown/cow/", 4,
nullptr);
166 TEST(path_util, NameAtIndex_MiscComplex)
168 AT_INDEX(
"how//now/brown/cow", 0,
"how");
169 AT_INDEX(
"//how///now\\/brown/cow", 1,
"now");
170 AT_INDEX(
"/how/now\\//brown\\/cow", 2,
"brown");
171 AT_INDEX(
"/how/now/brown/cow//\\", 3,
"cow");
172 AT_INDEX(
"/how/now/brown/\\cow", 4,
nullptr);
173 AT_INDEX(
"how/now/brown/\\cow\\", 4,
nullptr);
176 TEST(path_util, NameAtIndex_MiscComplexNeg)
178 AT_INDEX(
"how//now/brown/cow", -4,
"how");
179 AT_INDEX(
"//how///now\\/brown/cow", -3,
"now");
180 AT_INDEX(
"/how/now\\//brown\\/cow", -2,
"brown");
181 AT_INDEX(
"/how/now/brown/cow//\\", -1,
"cow");
182 AT_INDEX(
"/how/now/brown/\\cow", -5,
nullptr);
183 AT_INDEX(
"how/now/brown/\\cow\\", -5,
nullptr);
186 TEST(path_util, NameAtIndex_NoneComplex)
194 TEST(path_util, NameAtIndex_NoneComplexNeg)
204 #define JOIN(str_expect, out_size, ...) \
206 const char *expect = str_expect; \
207 char result[(out_size) + 1024]; \
209 result[out_size] = '\0'; \
210 BLI_path_join(result, out_size, __VA_ARGS__, NULL); \
212 BLI_str_replace_char(result, '\\', '/'); \
213 EXPECT_STREQ(result, expect); \
214 EXPECT_EQ(result[out_size], '\0'); \
222 JOIN(
"", 100,
"",
"");
223 JOIN(
"", 100,
"",
"",
"");
224 JOIN(
"/", 100,
"/",
"",
"");
225 JOIN(
"/", 100,
"/",
"/");
226 JOIN(
"/", 100,
"/",
"",
"/");
227 JOIN(
"/", 100,
"/",
"",
"/",
"");
232 JOIN(
"test", 100,
"test");
235 JOIN(
"/a", 100,
"/a");
236 JOIN(
"a/", 100,
"a/");
237 JOIN(
"/a/", 100,
"/a/");
238 JOIN(
"/a/", 100,
"/a//");
239 JOIN(
"//a/", 100,
"//a//");
244 JOIN(
"/a/b/c", 100,
"/a",
"b",
"c");
245 JOIN(
"/a/b/c", 100,
"/a/",
"/b/",
"/c");
246 JOIN(
"/a/b/c", 100,
"/a/b/",
"/c");
247 JOIN(
"/a/b/c", 100,
"/a/b/c");
248 JOIN(
"/a/b/c", 100,
"/",
"a/b/c");
250 JOIN(
"/a/b/c/", 100,
"/a/",
"/b/",
"/c/");
251 JOIN(
"/a/b/c/", 100,
"/a/b/c/");
252 JOIN(
"/a/b/c/", 100,
"/a/b/",
"/c/");
253 JOIN(
"/a/b/c/", 100,
"/a/b/c",
"/");
254 JOIN(
"/a/b/c/", 100,
"/",
"a/b/c",
"/");
257 TEST(path_util, JoinTruncateShort)
261 JOIN(
"a", 2,
"",
"aa");
262 JOIN(
"a", 2,
"",
"a/");
263 JOIN(
"a/b", 4,
"a",
"bc");
264 JOIN(
"ab/", 4,
"ab",
"c");
265 JOIN(
"/a/", 4,
"/a",
"b");
266 JOIN(
"/a/", 4,
"/a/",
"b/");
267 JOIN(
"/a/", 4,
"/a",
"/b/");
268 JOIN(
"/a/", 4,
"/",
"a/b/");
269 JOIN(
"//a", 4,
"//",
"a/b/");
271 JOIN(
"/a/b", 5,
"/a",
"b",
"c");
274 TEST(path_util, JoinTruncateLong)
276 JOIN(
"", 1,
"//",
"//longer",
"path");
277 JOIN(
"/", 2,
"//",
"//longer",
"path");
278 JOIN(
"//", 3,
"//",
"//longer",
"path");
279 JOIN(
"//l", 4,
"//",
"//longer",
"path");
281 JOIN(
"//longe", 8,
"//",
"//longer",
"path");
282 JOIN(
"//longer", 9,
"//",
"//longer",
"path");
283 JOIN(
"//longer/", 10,
"//",
"//longer",
"path");
284 JOIN(
"//longer/p", 11,
"//",
"//longer",
"path");
285 JOIN(
"//longer/pa", 12,
"//",
"//longer",
"path");
286 JOIN(
"//longer/pat", 13,
"//",
"//longer",
"path");
287 JOIN(
"//longer/path", 14,
"//",
"//longer",
"path");
288 JOIN(
"//longer/path", 14,
"//",
"//longer",
"path/");
289 JOIN(
"//longer/path/", 15,
"//",
"//longer",
"path/");
290 JOIN(
"//longer/path/", 15,
"//",
"//longer",
"path/",
"trunc");
291 JOIN(
"//longer/path/t", 16,
"//",
"//longer",
"path/",
"trunc");
296 JOIN(
"/a/b/c/d/e/f/g/", 100,
"/",
"\\a/b",
"//////c/d",
"",
"e\\\\",
"f",
"g//");
297 JOIN(
"/aa/bb/cc/dd/ee/ff/gg/", 100,
"/",
"\\aa/bb",
"//////cc/dd",
"",
"ee\\\\",
"ff",
"gg//");
298 JOIN(
"1/2/3/", 100,
"1",
"////////",
"",
"2",
"3\\");
312 EXPECT_STREQ(
"123", path);
319 EXPECT_STREQ(
"000000000123", path);
326 EXPECT_STREQ(
"test_123", path);
333 EXPECT_STREQ(
"test_000000000001", path);
337 char path[
FILE_MAX] =
"test_############";
340 EXPECT_STREQ(
"test_000000000001", path);
344 char path[
FILE_MAX] =
"test_#_#_middle";
347 EXPECT_STREQ(
"test_#_123_middle", path);
355 EXPECT_STREQ(
"", path);
359 char path[
FILE_MAX] =
"test_middle";
362 EXPECT_STREQ(
"test_middle", path);
370 EXPECT_STREQ(
"test_-0001", path);
376 EXPECT_STREQ(
"test_-0100", path);
384 const char *path =
"";
387 EXPECT_STREQ(
"", dir);
388 EXPECT_STREQ(
"",
file);
392 const char *path =
"/";
395 EXPECT_STREQ(
"/", dir);
396 EXPECT_STREQ(
"",
file);
400 const char *path =
"fileonly";
403 EXPECT_STREQ(
"", dir);
404 EXPECT_STREQ(
"fileonly",
file);
408 const char *path =
"dironly/";
411 EXPECT_STREQ(
"dironly/", dir);
412 EXPECT_STREQ(
"",
file);
416 const char *path =
"/a/b";
419 EXPECT_STREQ(
"/a/", dir);
420 EXPECT_STREQ(
"b",
file);
424 const char *path =
"/dirtoobig/filetoobig";
425 char dir[5],
file[5];
427 EXPECT_STREQ(
"/dir", dir);
428 EXPECT_STREQ(
"file",
file);
431 EXPECT_STREQ(
"", dir);
432 EXPECT_STREQ(
"",
file);
436 #define PATH_FRAME_STRIP(input_path, expect_path, expect_ext) \
438 char path[FILE_MAX]; \
439 char ext[FILE_MAX]; \
440 BLI_strncpy(path, (input_path), FILE_MAX); \
441 BLI_path_frame_strip(path, ext, sizeof(ext)); \
442 EXPECT_STREQ(path, expect_path); \
443 EXPECT_STREQ(ext, expect_ext); \
448 TEST(path_util, PathFrameStrip)
453 PATH_FRAME_STRIP(
"/abspath/to/somefile.001.abc",
"/abspath/to/somefile.###",
".abc");
454 PATH_FRAME_STRIP(
"/ext/longer/somefile.001.alembic",
"/ext/longer/somefile.###",
".alembic");
455 PATH_FRAME_STRIP(
"/ext/shorter/somefile.123001.abc",
"/ext/shorter/somefile.######",
".abc");
457 #undef PATH_FRAME_STRIP
459 #define PATH_EXTENSION_CHECK(input_path, input_ext, expect_ext) \
461 const bool ret = BLI_path_extension_check(input_path, input_ext); \
462 if (strcmp(input_ext, expect_ext) == 0) { \
472 TEST(path_util, PathExtensionCheck)
480 ".veryveryverylonglonglongextension",
481 ".veryveryverylonglonglongextension");
495 #undef PATH_EXTENSION_CHECK
497 #define PATH_FRAME_CHECK_CHARS(input_path, expect_hasChars) \
499 const bool ret = BLI_path_frame_check_chars(input_path); \
500 if (expect_hasChars) { \
510 TEST(path_util, PathFrameCheckChars)
527 #undef PATH_FRAME_CHECK_CHARS
529 #define PATH_FRAME_RANGE(input_path, sta, end, digits, expect_outpath) \
531 char path[FILE_MAX]; \
533 BLI_strncpy(path, input_path, FILE_MAX); \
534 ret = BLI_path_frame_range(path, sta, end, digits); \
535 if (expect_outpath == NULL) { \
540 EXPECT_STREQ(path, expect_outpath); \
546 TEST(path_util, PathFrameRange)
557 PATH_FRAME_RANGE(
"", 1, 0, 20,
"00000000000000000001-00000000000000000000");
559 #undef PATH_FRAME_RANGE
561 #define PATH_FRAME_GET(input_path, expect_frame, expect_numdigits, expect_pathisvalid) \
563 char path[FILE_MAX]; \
564 int out_frame = -1, out_numdigits = -1; \
565 BLI_strncpy(path, input_path, FILE_MAX); \
566 const bool ret = BLI_path_frame_get(path, &out_frame, &out_numdigits); \
567 if (expect_pathisvalid) { \
573 EXPECT_EQ(out_frame, expect_frame); \
574 EXPECT_EQ(out_numdigits, expect_numdigits); \
583 PATH_FRAME_GET(
"path/to/frame_2810.dummy_quite_long_extension", 2810, 4,
true);
588 #undef PATH_FRAME_GET
607 # define PATH_REL(abs_path, ref_path, rel_path) \
609 char path[FILE_MAX]; \
610 BLI_strncpy(path, abs_path, sizeof(path)); \
611 BLI_path_rel(path, ref_path); \
612 EXPECT_STREQ(rel_path, path); \
618 PATH_REL(
"/foo/bar/blender.blend",
"/foo/bar/",
"//blender.blend");
619 PATH_REL(
"/foo/bar/blender.blend",
"/foo/bar",
"//bar/blender.blend");
624 abs_path_in[0] =
'/';
625 for (
int i = 1; i <
FILE_MAX - 1; i++) {
626 abs_path_in[i] =
'A';
630 abs_path_out[0] =
'/';
631 abs_path_out[1] =
'/';
632 for (
int i = 2; i <
FILE_MAX - 1; i++) {
633 abs_path_out[i] =
'A';
636 PATH_REL(abs_path_in,
"/", abs_path_out);
638 const char *ref_path_in =
"/foo/bar/";
639 const size_t ref_path_in_len = strlen(ref_path_in);
640 strcpy(abs_path_in, ref_path_in);
641 for (
int i = ref_path_in_len; i <
FILE_MAX - 1; i++) {
642 abs_path_in[i] =
'A';
645 abs_path_out[0] =
'/';
646 abs_path_out[1] =
'/';
647 for (
int i = 2; i <
FILE_MAX - ((int)ref_path_in_len - 1); i++) {
648 abs_path_out[i] =
'A';
650 abs_path_out[
FILE_MAX - (ref_path_in_len - 1)] =
'\0';
651 PATH_REL(abs_path_in, ref_path_in, abs_path_out);
662 EXPECT_TRUE(
BLI_path_contains(
"/some/path",
"/some/path")) <<
"A path contains itself";
664 <<
"A path contains its subdirectory";
666 <<
"Paths should be normalized";
668 <<
"Windows paths should be supported as well";
671 <<
"Windows paths should be supported as well";
673 <<
"Root directory not be contained in a subdirectory";
675 <<
"Paths should be normalized";
677 <<
"Just sharing a suffix is not enough, path semantics should be followed";
679 <<
"Relative paths are not supported";
683 TEST(path_util, PathContains_Windows_case_insensitive)
686 <<
"On Windows path comparison should ignore case";
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
File and directory operations.
bool BLI_path_frame(char *path, int frame, int digits) ATTR_NONNULL()
const char * BLI_path_extension(const char *filepath) ATTR_NONNULL()
void BLI_split_dirfile(const char *string, char *dir, char *file, size_t dirlen, size_t filelen)
void BLI_path_normalize(const char *relabase, char *path) ATTR_NONNULL(2)
bool BLI_path_contains(const char *container_path, const char *containee_path) ATTR_WARN_UNUSED_RESULT
#define PATH_FRAME_RANGE(input_path, sta, end, digits, expect_outpath)
#define PATH_EXTENSION_CHECK(input_path, input_ext, expect_ext)
#define PATH_FRAME_STRIP(input_path, expect_path, expect_ext)
#define JOIN(str_expect, out_size,...)
#define AT_INDEX(str_input, index_input, str_expect)
#define PATH_FRAME_GET(input_path, expect_frame, expect_numdigits, expect_pathisvalid)
#define PATH_FRAME_CHECK_CHARS(input_path, expect_hasChars)
#define PATH_REL(abs_path, ref_path, rel_path)