1 // path_test program -----------------------------------------------------------------//
2
3 // Copyright Beman Dawes 2002, 2008
4 // Copyright Vladimir Prus 2002
5
6 // Use, modification, and distribution is subject to the Boost Software
7 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9
10 // See library home page at http://www.boost.org/libs/filesystem
11
12 // basic_path's stem(), extension(), and replace_extension() tests are based
13 // on basename(), extension(), and change_extension() tests from the original
14 // convenience_test.cpp by Vladimir Prus.
15
16 //--------------------------------------------------------------------------------------//
17 // //
18 // Caution //
19 // //
20 // The class path relational operators (==, !=, <, etc.) on Windows treat slash and //
21 // backslash as equal. Thus any tests on Windows where the difference between slash //
22 // and backslash is significant should compare strings rather than paths. //
23 // //
24 // BOOST_TEST(path == path) // '\\' and '/' are equal //
25 // BOOST_TEST(path == convertable to string) // '\\' and '/' are equal //
26 // PATH_TEST_EQ(path, path) // '\\' and '/' are equal //
27 // //
28 // BOOST_TEST(path.string() == path.string()) // '\\' and '/' are not equal //
29 // BOOST_TEST(path.string() == //
30 // convertable to string) // '\\' and '/' are not equal //
31 // PATH_TEST_EQ(path.string(), //
32 // convertable to string) // '\\' and '/' are not equal //
33 // //
34 // The last of these is often what is needed, so the PATH_TEST_EQ macro is provided. //
35 // It converts its first argument to a path, and then performs a .string() on it, //
36 // eliminating much boilerplate .string() or even path(...).string() code. //
37 // //
38 // PATH_TEST_EQ(path, convertable to string) // '\\' and '/' are not equal //
39 // //
40 //--------------------------------------------------------------------------------------//
41
42 #include <boost/config/warning_disable.hpp>
43
44 // See deprecated_test for tests of deprecated features
45 #ifndef BOOST_FILESYSTEM_NO_DEPRECATED
46 # define BOOST_FILESYSTEM_NO_DEPRECATED
47 #endif
48 #ifndef BOOST_SYSTEM_NO_DEPRECATED
49 # define BOOST_SYSTEM_NO_DEPRECATED
50 #endif
51
52 #include <boost/filesystem/operations.hpp>
53
54 #include <boost/config.hpp>
55 # if defined( BOOST_NO_STD_WSTRING )
56 # error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support
57 # endif
58
59 #include <boost/utility.hpp>
60 #include <iostream>
61 #include <sstream>
62 #include <string>
63 #include <vector>
64 #include <cstring>
65 #include <cassert>
66 #include <boost/detail/lightweight_test.hpp>
67 #include <boost/detail/lightweight_main.hpp>
68
69 namespace fs = boost::filesystem;
70 using boost::filesystem::path;
71 using boost::next;
72 using boost::prior;
73
74 #ifdef BOOST_WINDOWS_API
75 # define BOOST_DIR_SEP "\\"
76 #else
77 # define BOOST_DIR_SEP "/"
78 #endif
79
80 #define PATH_TEST_EQ(a, b) check(a, b, __FILE__, __LINE__)
81
82 namespace
83 {
84 std::string platform(BOOST_PLATFORM);
85
check(const fs::path & source,const std::string & expected,const char * file,int line)86 void check(const fs::path & source,
87 const std::string & expected, const char* file, int line)
88 {
89 if (source.string() == expected)
90 return;
91
92 std::cout << file
93 << '(' << line << "): source: \"" << source.string()
94 << "\" != expected: \"" << expected
95 << "\"" << std::endl;
96
97 ++::boost::detail::test_errors();
98 }
99
100 path p1("fe/fi/fo/fum");
101 path p2(p1);
102 path p3;
103 path p4("foobar");
104 path p5;
105
106 // exception_tests -----------------------------------------------------------------//
107
exception_tests()108 void exception_tests()
109 {
110 std::cout << "exception_tests..." << std::endl;
111 const std::string str_1("string-1");
112 boost::system::error_code ec(12345, boost::system::system_category());
113 try { throw fs::filesystem_error(str_1, ec); }
114 catch (const fs::filesystem_error & ex)
115 {
116 //std::cout << ex.what() << "*" << std::endl;
117 //BOOST_TEST(std::strcmp(ex.what(),
118 // "string-1: Unknown error") == 0);
119 BOOST_TEST(ex.code() == ec);
120 }
121
122 try { throw fs::filesystem_error(str_1, "p1", "p2", ec); }
123 catch (const fs::filesystem_error & ex)
124 {
125 //std::cout << ex.what() << "*" << std::endl;
126 //BOOST_TEST(std::strcmp(ex.what(),
127 // "string-1: Unknown error: \"p1\", \"p2\"") == 0);
128 BOOST_TEST(ex.code() == ec);
129 BOOST_TEST(ex.path1() == "p1");
130 BOOST_TEST(ex.path2() == "p2");
131 }
132 }
133
134 // overload_tests ------------------------------------------------------------------//
135
136 // These verify various overloads don't cause compiler errors
137 // They pre-date operations_unit_test.cpp
138
overload_tests()139 void overload_tests()
140 {
141 std::cout << "overload_tests..." << std::endl;
142
143 fs::exists(p1);
144 fs::exists("foo");
145 fs::exists(std::string("foo"));
146
147 fs::exists(p1 / path("foo"));
148 fs::exists(p1 / "foo");
149 fs::exists(p1 / std::string("foo"));
150
151 fs::exists("foo" / p1);
152 fs::exists(std::string("foo") / p1);
153
154 p4 /= path("foo");
155 p4 /= "foo";
156 p4 /= std::string("foo");
157 }
158
159 // iterator_tests ------------------------------------------------------------------//
160
iterator_tests()161 void iterator_tests()
162 {
163 std::cout << "iterator_tests..." << std::endl;
164
165 path itr_ck = "";
166 path::const_iterator itr = itr_ck.begin();
167 BOOST_TEST(itr == itr_ck.end());
168
169 itr_ck = "/";
170 itr = itr_ck.begin();
171 BOOST_TEST(itr->string() == "/");
172 BOOST_TEST(++itr == itr_ck.end());
173 BOOST_TEST((--itr)->string() == "/");
174
175 itr_ck = "foo";
176 BOOST_TEST(*itr_ck.begin() == std::string("foo"));
177 BOOST_TEST(boost::next(itr_ck.begin()) == itr_ck.end());
178 BOOST_TEST(*boost::prior(itr_ck.end()) == std::string("foo"));
179 BOOST_TEST(boost::prior(itr_ck.end()) == itr_ck.begin());
180
181 itr_ck = path("/foo");
182 BOOST_TEST((itr_ck.begin())->string() == "/");
183 BOOST_TEST(*boost::next(itr_ck.begin()) == std::string("foo"));
184 BOOST_TEST(boost::next(boost::next(itr_ck.begin())) == itr_ck.end());
185 BOOST_TEST(boost::next(itr_ck.begin()) == boost::prior(itr_ck.end()));
186 BOOST_TEST(*boost::prior(itr_ck.end()) == std::string("foo"));
187 BOOST_TEST(*boost::prior(boost::prior(itr_ck.end())) == std::string("/"));
188 BOOST_TEST(boost::prior(boost::prior(itr_ck.end())) == itr_ck.begin());
189
190 itr_ck = "/foo/bar";
191 itr = itr_ck.begin();
192 BOOST_TEST(itr->string() == "/");
193 BOOST_TEST(*++itr == std::string("foo"));
194 BOOST_TEST(*++itr == std::string("bar"));
195 BOOST_TEST(++itr == itr_ck.end());
196 PATH_TEST_EQ(*--itr, "bar");
197 PATH_TEST_EQ(*--itr, "foo");
198 PATH_TEST_EQ(*--itr, "/");
199
200 itr_ck = "../f"; // previously failed due to short name bug
201 itr = itr_ck.begin();
202 PATH_TEST_EQ(itr->string(), "..");
203 PATH_TEST_EQ(*++itr, "f");
204 BOOST_TEST(++itr == itr_ck.end());
205 PATH_TEST_EQ(*--itr, "f");
206 PATH_TEST_EQ(*--itr, "..");
207
208 // POSIX says treat "/foo/bar/" as "/foo/bar/."
209 itr_ck = "/foo/bar/";
210 itr = itr_ck.begin();
211 PATH_TEST_EQ(itr->string(), "/");
212 PATH_TEST_EQ(*++itr, "foo");
213 BOOST_TEST(itr != itr_ck.end());
214 PATH_TEST_EQ(*++itr, "bar");
215 BOOST_TEST(itr != itr_ck.end());
216 PATH_TEST_EQ(*++itr, ".");
217 BOOST_TEST(itr != itr_ck.end()); // verify the . isn't also seen as end()
218 BOOST_TEST(++itr == itr_ck.end());
219 PATH_TEST_EQ(*--itr, ".");
220 PATH_TEST_EQ(*--itr, "bar");
221 PATH_TEST_EQ(*--itr, "foo");
222 PATH_TEST_EQ(*--itr, "/");
223
224 // POSIX says treat "/f/b/" as "/f/b/."
225 itr_ck = "/f/b/";
226 itr = itr_ck.begin();
227 PATH_TEST_EQ(itr->string(), "/");
228 PATH_TEST_EQ(*++itr, "f");
229 PATH_TEST_EQ(*++itr, "b");
230 PATH_TEST_EQ(*++itr, ".");
231 BOOST_TEST(itr != itr_ck.end()); // verify the . isn't also seen as end()
232 BOOST_TEST(++itr == itr_ck.end());
233 PATH_TEST_EQ(*--itr, ".");
234 PATH_TEST_EQ(*--itr, "b");
235 PATH_TEST_EQ(*--itr, "f");
236 PATH_TEST_EQ(*--itr, "/");
237
238 // POSIX says treat "a/b/" as "a/b/."
239 // Although similar to the prior test case, this failed the ". isn't end" test due to
240 // a bug while the prior case did not fail.
241 itr_ck = "a/b/";
242 itr = itr_ck.begin();
243 PATH_TEST_EQ(*itr, "a");
244 PATH_TEST_EQ(*++itr, "b");
245 PATH_TEST_EQ(*++itr, ".");
246 BOOST_TEST(itr != itr_ck.end()); // verify the . isn't also seen as end()
247 BOOST_TEST(++itr == itr_ck.end());
248 PATH_TEST_EQ(*--itr, ".");
249 PATH_TEST_EQ(*--itr, "b");
250 PATH_TEST_EQ(*--itr, "a");
251
252 itr_ck = "//net";
253 itr = itr_ck.begin();
254 // two leading slashes are permitted by POSIX (as implementation defined),
255 // while for Windows it is always well defined (as a network name)
256 PATH_TEST_EQ(itr->string(), "//net");
257 BOOST_TEST(++itr == itr_ck.end());
258 PATH_TEST_EQ(*--itr, "//net");
259
260 itr_ck = "//net/";
261 itr = itr_ck.begin();
262 PATH_TEST_EQ(itr->string(), "//net");
263 PATH_TEST_EQ(*++itr, "/");
264 BOOST_TEST(++itr == itr_ck.end());
265 PATH_TEST_EQ(*--itr, "/");
266 PATH_TEST_EQ(*--itr, "//net");
267
268 itr_ck = "//foo///bar///";
269 itr = itr_ck.begin();
270 PATH_TEST_EQ(itr->string(), "//foo");
271 PATH_TEST_EQ(*++itr, "/");
272 PATH_TEST_EQ(*++itr, "bar");
273 PATH_TEST_EQ(*++itr, ".");
274 BOOST_TEST(++itr == itr_ck.end());
275 PATH_TEST_EQ(*--itr, ".");
276 PATH_TEST_EQ(*--itr, "bar");
277 PATH_TEST_EQ(*--itr, "/");
278 PATH_TEST_EQ(*--itr, "//foo");
279
280 itr_ck = "///foo///bar///";
281 itr = itr_ck.begin();
282 // three or more leading slashes are to be treated as a single slash
283 PATH_TEST_EQ(itr->string(), "/");
284 PATH_TEST_EQ(*++itr, "foo");
285 PATH_TEST_EQ(*++itr, "bar");
286 PATH_TEST_EQ(*++itr, ".");
287 BOOST_TEST(++itr == itr_ck.end());
288 PATH_TEST_EQ(*--itr, ".");
289 PATH_TEST_EQ(*--itr, "bar");
290 PATH_TEST_EQ(*--itr, "foo");
291 PATH_TEST_EQ(*--itr, "/");
292
293 if (platform == "Windows")
294 {
295 itr_ck = "c:/";
296 itr = itr_ck.begin();
297 PATH_TEST_EQ(itr->string(), "c:");
298 PATH_TEST_EQ(*++itr, std::string("/"));
299 BOOST_TEST(++itr == itr_ck.end());
300 PATH_TEST_EQ(*--itr, "/");
301 PATH_TEST_EQ(*--itr, "c:");
302
303 itr_ck = "c:\\";
304 itr = itr_ck.begin();
305 PATH_TEST_EQ(itr->string(), "c:");
306 PATH_TEST_EQ(*++itr, "/"); // test that iteration returns generic format
307 BOOST_TEST(++itr == itr_ck.end());
308 PATH_TEST_EQ(*--itr, "/"); // test that iteration returns generic format
309 PATH_TEST_EQ(*--itr, "c:");
310
311 itr_ck = "c:/foo";
312 itr = itr_ck.begin();
313 BOOST_TEST(*itr == std::string("c:"));
314 BOOST_TEST(*++itr == std::string("/"));
315 BOOST_TEST(*++itr == std::string("foo"));
316 BOOST_TEST(++itr == itr_ck.end());
317 BOOST_TEST(*--itr == std::string("foo"));
318 BOOST_TEST((--itr)->string() == "/");
319 BOOST_TEST(*--itr == std::string("c:"));
320
321 itr_ck = "c:\\foo";
322 itr = itr_ck.begin();
323 BOOST_TEST(*itr == std::string("c:"));
324 BOOST_TEST(*++itr == std::string("\\"));
325 BOOST_TEST(*++itr == std::string("foo"));
326 BOOST_TEST(++itr == itr_ck.end());
327 BOOST_TEST(*--itr == std::string("foo"));
328 BOOST_TEST(*--itr == std::string("\\"));
329 BOOST_TEST(*--itr == std::string("c:"));
330
331 itr_ck = "\\\\\\foo\\\\\\bar\\\\\\";
332 itr = itr_ck.begin();
333 // three or more leading slashes are to be treated as a single slash
334 PATH_TEST_EQ(itr->string(), "/");
335 PATH_TEST_EQ(*++itr, "foo");
336 PATH_TEST_EQ(*++itr, "bar");
337 PATH_TEST_EQ(*++itr, ".");
338 BOOST_TEST(++itr == itr_ck.end());
339 PATH_TEST_EQ(*--itr, ".");
340 PATH_TEST_EQ(*--itr, "bar");
341 PATH_TEST_EQ(*--itr, "foo");
342 PATH_TEST_EQ(*--itr, "/");
343
344 itr_ck = "c:foo";
345 itr = itr_ck.begin();
346 BOOST_TEST(*itr == std::string("c:"));
347 BOOST_TEST(*++itr == std::string("foo"));
348 BOOST_TEST(++itr == itr_ck.end());
349 BOOST_TEST(*--itr == std::string("foo"));
350 BOOST_TEST(*--itr == std::string("c:"));
351
352 itr_ck = "c:foo/";
353 itr = itr_ck.begin();
354 BOOST_TEST(*itr == std::string("c:"));
355 BOOST_TEST(*++itr == std::string("foo"));
356 BOOST_TEST(*++itr == std::string("."));
357 BOOST_TEST(++itr == itr_ck.end());
358 BOOST_TEST(*--itr == std::string("."));
359 BOOST_TEST(*--itr == std::string("foo"));
360 BOOST_TEST(*--itr == std::string("c:"));
361
362 itr_ck = path("c:");
363 BOOST_TEST(*itr_ck.begin() == std::string("c:"));
364 BOOST_TEST(next(itr_ck.begin()) == itr_ck.end());
365 BOOST_TEST(prior(itr_ck.end()) == itr_ck.begin());
366 BOOST_TEST(*prior(itr_ck.end()) == std::string("c:"));
367
368 itr_ck = path("c:/");
369 BOOST_TEST(*itr_ck.begin() == std::string("c:"));
370 BOOST_TEST(*next(itr_ck.begin()) == std::string("/"));
371 BOOST_TEST(next(next(itr_ck.begin())) == itr_ck.end());
372 BOOST_TEST(prior(prior(itr_ck.end())) == itr_ck.begin());
373 BOOST_TEST(*prior(itr_ck.end()) == std::string("/"));
374 BOOST_TEST(*prior(prior(itr_ck.end())) == std::string("c:"));
375
376 itr_ck = path("c:foo");
377 BOOST_TEST(*itr_ck.begin() == std::string("c:"));
378 BOOST_TEST(*next(itr_ck.begin()) == std::string("foo"));
379 BOOST_TEST(next(next(itr_ck.begin())) == itr_ck.end());
380 BOOST_TEST(prior(prior(itr_ck.end())) == itr_ck.begin());
381 BOOST_TEST(*prior(itr_ck.end()) == std::string("foo"));
382 BOOST_TEST(*prior(prior(itr_ck.end())) == std::string("c:"));
383
384 itr_ck = path("c:/foo");
385 BOOST_TEST(*itr_ck.begin() == std::string("c:"));
386 BOOST_TEST(*next(itr_ck.begin()) == std::string("/"));
387 BOOST_TEST(*next(next(itr_ck.begin())) == std::string("foo"));
388 BOOST_TEST(next(next(next(itr_ck.begin()))) == itr_ck.end());
389 BOOST_TEST(prior(prior(prior(itr_ck.end()))) == itr_ck.begin());
390 BOOST_TEST(*prior(itr_ck.end()) == std::string("foo"));
391 BOOST_TEST(*prior(prior(itr_ck.end())) == std::string("/"));
392 BOOST_TEST(*prior(prior(prior(itr_ck.end()))) == std::string("c:"));
393
394 itr_ck = path("//net");
395 BOOST_TEST(*itr_ck.begin() == std::string("//net"));
396 BOOST_TEST(next(itr_ck.begin()) == itr_ck.end());
397 BOOST_TEST(prior(itr_ck.end()) == itr_ck.begin());
398 BOOST_TEST(*prior(itr_ck.end()) == std::string("//net"));
399
400 itr_ck = path("//net/");
401 PATH_TEST_EQ(itr_ck.begin()->string(), "//net");
402 PATH_TEST_EQ(next(itr_ck.begin())->string(), "/");
403 BOOST_TEST(next(next(itr_ck.begin())) == itr_ck.end());
404 BOOST_TEST(prior(prior(itr_ck.end())) == itr_ck.begin());
405 PATH_TEST_EQ(prior(itr_ck.end())->string(), "/");
406 PATH_TEST_EQ(prior(prior(itr_ck.end()))->string(), "//net");
407
408 itr_ck = path("//net/foo");
409 BOOST_TEST(*itr_ck.begin() == std::string("//net"));
410 BOOST_TEST(*next(itr_ck.begin()) == std::string("/"));
411 BOOST_TEST(*next(next(itr_ck.begin())) == std::string("foo"));
412 BOOST_TEST(next(next(next(itr_ck.begin()))) == itr_ck.end());
413 BOOST_TEST(prior(prior(prior(itr_ck.end()))) == itr_ck.begin());
414 BOOST_TEST(*prior(itr_ck.end()) == std::string("foo"));
415 BOOST_TEST(*prior(prior(itr_ck.end())) == std::string("/"));
416 BOOST_TEST(*prior(prior(prior(itr_ck.end()))) == std::string("//net"));
417
418 itr_ck = path("prn:");
419 BOOST_TEST(*itr_ck.begin() == std::string("prn:"));
420 BOOST_TEST(next(itr_ck.begin()) == itr_ck.end());
421 BOOST_TEST(prior(itr_ck.end()) == itr_ck.begin());
422 BOOST_TEST(*prior(itr_ck.end()) == std::string("prn:"));
423 }
424 else
425 {
426 itr_ck = "///";
427 itr = itr_ck.begin();
428 PATH_TEST_EQ(itr->string(), "/");
429 BOOST_TEST(++itr == itr_ck.end());
430 }
431 }
432
433 // non_member_tests ----------------------------------------------------------------//
434
non_member_tests()435 void non_member_tests()
436 {
437 std::cout << "non_member_tests..." << std::endl;
438
439 // test non-member functions, particularly operator overloads
440
441 path e, e2;
442 std::string es, es2;
443 char ecs[] = "";
444 char ecs2[] = "";
445
446 char acs[] = "a";
447 std::string as(acs);
448 path a(as);
449
450 char acs2[] = "a";
451 std::string as2(acs2);
452 path a2(as2);
453
454 char bcs[] = "b";
455 std::string bs(bcs);
456 path b(bs);
457
458 // swap
459 a.swap(b);
460 BOOST_TEST(a.string() == "b");
461 BOOST_TEST(b.string() == "a");
462 fs::swap(a, b);
463 BOOST_TEST(a.string() == "a");
464 BOOST_TEST(b.string() == "b");
465
466 // probe operator /
467 PATH_TEST_EQ(path("") / ".", ".");
468 PATH_TEST_EQ(path("") / "..", "..");
469 if (platform == "Windows")
470 {
471 BOOST_TEST(path("foo\\bar") == "foo/bar");
472 BOOST_TEST((b / a).native() == path("b\\a").native());
473 BOOST_TEST((bs / a).native() == path("b\\a").native());
474 BOOST_TEST((bcs / a).native() == path("b\\a").native());
475 BOOST_TEST((b / as).native() == path("b\\a").native());
476 BOOST_TEST((b / acs).native() == path("b\\a").native());
477 PATH_TEST_EQ(path("a") / "b", "a\\b");
478 PATH_TEST_EQ(path("..") / "", "..");
479 PATH_TEST_EQ(path("foo") / path("bar"), "foo\\bar"); // path arg
480 PATH_TEST_EQ(path("foo") / "bar", "foo\\bar"); // const char* arg
481 PATH_TEST_EQ(path("foo") / path("woo/bar").filename(), "foo\\bar"); // const std::string & arg
482 PATH_TEST_EQ("foo" / path("bar"), "foo\\bar");
483 PATH_TEST_EQ(path("..") / ".." , "..\\..");
484 PATH_TEST_EQ(path("/") / ".." , "/..");
485 PATH_TEST_EQ(path("/..") / ".." , "/..\\..");
486 PATH_TEST_EQ(path("..") / "foo" , "..\\foo");
487 PATH_TEST_EQ(path("foo") / ".." , "foo\\..");
488 PATH_TEST_EQ(path("..") / "f" , "..\\f");
489 PATH_TEST_EQ(path("/..") / "f" , "/..\\f");
490 PATH_TEST_EQ(path("f") / ".." , "f\\..");
491 PATH_TEST_EQ(path("foo") / ".." / ".." , "foo\\..\\..");
492 PATH_TEST_EQ(path("foo") / ".." / ".." / ".." , "foo\\..\\..\\..");
493 PATH_TEST_EQ(path("f") / ".." / "b" , "f\\..\\b");
494 PATH_TEST_EQ(path("foo") / ".." / "bar" , "foo\\..\\bar");
495 PATH_TEST_EQ(path("foo") / "bar" / ".." , "foo\\bar\\..");
496 PATH_TEST_EQ(path("foo") / "bar" / ".." / "..", "foo\\bar\\..\\..");
497 PATH_TEST_EQ(path("foo") / "bar" / ".." / "blah", "foo\\bar\\..\\blah");
498 PATH_TEST_EQ(path("f") / "b" / ".." , "f\\b\\..");
499 PATH_TEST_EQ(path("f") / "b" / ".." / "a", "f\\b\\..\\a");
500 PATH_TEST_EQ(path("foo") / "bar" / "blah" / ".." / "..", "foo\\bar\\blah\\..\\..");
501 PATH_TEST_EQ(path("foo") / "bar" / "blah" / ".." / ".." / "bletch", "foo\\bar\\blah\\..\\..\\bletch");
502
503 PATH_TEST_EQ(path(".") / "foo", ".\\foo");
504 PATH_TEST_EQ(path(".") / "..", ".\\..");
505 PATH_TEST_EQ(path("foo") / ".", "foo\\.");
506 PATH_TEST_EQ(path("..") / ".", "..\\.");
507 PATH_TEST_EQ(path(".") / ".", ".\\.");
508 PATH_TEST_EQ(path(".") / "." / ".", ".\\.\\.");
509 PATH_TEST_EQ(path(".") / "foo" / ".", ".\\foo\\.");
510 PATH_TEST_EQ(path("foo") / "." / "bar", "foo\\.\\bar");
511 PATH_TEST_EQ(path("foo") / "." / ".", "foo\\.\\.");
512 PATH_TEST_EQ(path("foo") / "." / "..", "foo\\.\\..");
513 PATH_TEST_EQ(path(".") / "." / "..", ".\\.\\..");
514 PATH_TEST_EQ(path(".") / ".." / ".", ".\\..\\.");
515 PATH_TEST_EQ(path("..") / "." / ".", "..\\.\\.");
516 }
517 else // POSIX
518 {
519 PATH_TEST_EQ(b / a, "b/a");
520 PATH_TEST_EQ(bs / a, "b/a");
521 PATH_TEST_EQ(bcs / a, "b/a");
522 PATH_TEST_EQ(b / as, "b/a");
523 PATH_TEST_EQ(b / acs, "b/a");
524 PATH_TEST_EQ(path("a") / "b", "a/b");
525 PATH_TEST_EQ(path("..") / "", "..");
526 PATH_TEST_EQ(path("") / "..", "..");
527 PATH_TEST_EQ(path("foo") / path("bar"), "foo/bar"); // path arg
528 PATH_TEST_EQ(path("foo") / "bar", "foo/bar"); // const char* arg
529 PATH_TEST_EQ(path("foo") / path("woo/bar").filename(), "foo/bar"); // const std::string & arg
530 PATH_TEST_EQ("foo" / path("bar"), "foo/bar");
531 PATH_TEST_EQ(path("..") / ".." , "../..");
532 PATH_TEST_EQ(path("/") / ".." , "/..");
533 PATH_TEST_EQ(path("/..") / ".." , "/../..");
534 PATH_TEST_EQ(path("..") / "foo" , "../foo");
535 PATH_TEST_EQ(path("foo") / ".." , "foo/..");
536 PATH_TEST_EQ(path("..") / "f" , "../f");
537 PATH_TEST_EQ(path("/..") / "f" , "/../f");
538 PATH_TEST_EQ(path("f") / ".." , "f/..");
539 PATH_TEST_EQ(path("foo") / ".." / ".." , "foo/../..");
540 PATH_TEST_EQ(path("foo") / ".." / ".." / ".." , "foo/../../..");
541 PATH_TEST_EQ(path("f") / ".." / "b" , "f/../b");
542 PATH_TEST_EQ(path("foo") / ".." / "bar" , "foo/../bar");
543 PATH_TEST_EQ(path("foo") / "bar" / ".." , "foo/bar/..");
544 PATH_TEST_EQ(path("foo") / "bar" / ".." / "..", "foo/bar/../..");
545 PATH_TEST_EQ(path("foo") / "bar" / ".." / "blah", "foo/bar/../blah");
546 PATH_TEST_EQ(path("f") / "b" / ".." , "f/b/..");
547 PATH_TEST_EQ(path("f") / "b" / ".." / "a", "f/b/../a");
548 PATH_TEST_EQ(path("foo") / "bar" / "blah" / ".." / "..", "foo/bar/blah/../..");
549 PATH_TEST_EQ(path("foo") / "bar" / "blah" / ".." / ".." / "bletch", "foo/bar/blah/../../bletch");
550
551 PATH_TEST_EQ(path(".") / "foo", "./foo");
552 PATH_TEST_EQ(path(".") / "..", "./..");
553 PATH_TEST_EQ(path("foo") / ".", "foo/.");
554 PATH_TEST_EQ(path("..") / ".", "../.");
555 PATH_TEST_EQ(path(".") / ".", "./.");
556 PATH_TEST_EQ(path(".") / "." / ".", "././.");
557 PATH_TEST_EQ(path(".") / "foo" / ".", "./foo/.");
558 PATH_TEST_EQ(path("foo") / "." / "bar", "foo/./bar");
559 PATH_TEST_EQ(path("foo") / "." / ".", "foo/./.");
560 PATH_TEST_EQ(path("foo") / "." / "..", "foo/./..");
561 PATH_TEST_EQ(path(".") / "." / "..", "././..");
562 PATH_TEST_EQ(path(".") / ".." / ".", "./../.");
563 PATH_TEST_EQ(path("..") / "." / ".", ".././.");
564 }
565
566 // probe operator <
567 BOOST_TEST(!(e < e2));
568 BOOST_TEST(!(es < e2));
569 BOOST_TEST(!(ecs < e2));
570 BOOST_TEST(!(e < es2));
571 BOOST_TEST(!(e < ecs2));
572
573 BOOST_TEST(e < a);
574 BOOST_TEST(es < a);
575 BOOST_TEST(ecs < a);
576 BOOST_TEST(e < as);
577 BOOST_TEST(e < acs);
578
579 BOOST_TEST(a < b);
580 BOOST_TEST(as < b);
581 BOOST_TEST(acs < b);
582 BOOST_TEST(a < bs);
583 BOOST_TEST(a < bcs);
584
585 BOOST_TEST(!(a < a2));
586 BOOST_TEST(!(as < a2));
587 BOOST_TEST(!(acs < a2));
588 BOOST_TEST(!(a < as2));
589 BOOST_TEST(!(a < acs2));
590
591 // make sure basic_path overloads don't conflict with std::string overloads
592
593 BOOST_TEST(!(as < as));
594 BOOST_TEST(!(as < acs));
595 BOOST_TEST(!(acs < as));
596
597 // character set reality check before lexicographical tests
598 BOOST_TEST(std::string("a.b") < std::string("a/b"));
599 // verify compare is actually lexicographical
600 BOOST_TEST(path("a/b") < path("a.b"));
601 BOOST_TEST(path("a/b") == path("a///b"));
602 BOOST_TEST(path("a/b/") == path("a/b/."));
603 BOOST_TEST(path("a/b") != path("a/b/"));
604
605 // make sure the derivative operators also work
606
607 BOOST_TEST(b > a);
608 BOOST_TEST(b > as);
609 BOOST_TEST(b > acs);
610 BOOST_TEST(bs > a);
611 BOOST_TEST(bcs > a);
612
613 BOOST_TEST(!(a2 > a));
614 BOOST_TEST(!(a2 > as));
615 BOOST_TEST(!(a2 > acs));
616 BOOST_TEST(!(as2 > a));
617 BOOST_TEST(!(acs2 > a));
618
619 BOOST_TEST(a <= b);
620 BOOST_TEST(as <= b);
621 BOOST_TEST(acs <= b);
622 BOOST_TEST(a <= bs);
623 BOOST_TEST(a <= bcs);
624
625 BOOST_TEST(a <= a2);
626 BOOST_TEST(as <= a2);
627 BOOST_TEST(acs <= a2);
628 BOOST_TEST(a <= as2);
629 BOOST_TEST(a <= acs2);
630
631 BOOST_TEST(b >= a);
632 BOOST_TEST(bs >= a);
633 BOOST_TEST(bcs >= a);
634 BOOST_TEST(b >= as);
635 BOOST_TEST(b >= acs);
636
637 BOOST_TEST(a2 >= a);
638 BOOST_TEST(as2 >= a);
639 BOOST_TEST(acs2 >= a);
640 BOOST_TEST(a2 >= as);
641 BOOST_TEST(a2 >= acs);
642
643 // operator == and != are implemented separately, so test separately
644
645 path p101("fe/fi/fo/fum");
646 path p102(p101);
647 path p103("fe/fi/fo/fumm");
648 BOOST_TEST(p101.string() != p103.string());
649
650 // check each overload
651 BOOST_TEST(p101 != p103);
652 BOOST_TEST(p101 != p103.string());
653 BOOST_TEST(p101 != p103.string().c_str());
654 BOOST_TEST(p101.string() != p103);
655 BOOST_TEST(p101.string().c_str() != p103);
656
657 p103 = p102;
658 BOOST_TEST(p101.string() == p103.string());
659
660 // check each overload
661 BOOST_TEST(p101 == p103);
662 BOOST_TEST(p101 == p103.string());
663 BOOST_TEST(p101 == p103.string().c_str());
664 BOOST_TEST(p101.string() == p103);
665 BOOST_TEST(p101.string().c_str() == p103);
666
667 if (platform == "Windows")
668 {
669 std::cout << "Windows relational tests..." << std::endl;
670 path p10 ("c:\\file");
671 path p11 ("c:/file");
672 // check each overload
673 BOOST_TEST(p10.generic_string() == p11.generic_string());
674 BOOST_TEST(p10 == p11);
675 BOOST_TEST(p10 == p11.string());
676 BOOST_TEST(p10 == p11.string().c_str());
677 BOOST_TEST(p10.string() == p11);
678 BOOST_TEST(p10.string().c_str() == p11);
679 BOOST_TEST(p10 == L"c:\\file");
680 BOOST_TEST(p10 == L"c:/file");
681 BOOST_TEST(p11 == L"c:\\file");
682 BOOST_TEST(p11 == L"c:/file");
683 BOOST_TEST(L"c:\\file" == p10);
684 BOOST_TEST(L"c:/file" == p10);
685 BOOST_TEST(L"c:\\file" == p11);
686 BOOST_TEST(L"c:/file" == p11);
687
688 BOOST_TEST(!(p10.generic_string() != p11.generic_string()));
689 BOOST_TEST(!(p10 != p11));
690 BOOST_TEST(!(p10 != p11.string()));
691 BOOST_TEST(!(p10 != p11.string().c_str()));
692 BOOST_TEST(!(p10.string() != p11));
693 BOOST_TEST(!(p10.string().c_str() != p11));
694 BOOST_TEST(!(p10 != L"c:\\file"));
695 BOOST_TEST(!(p10 != L"c:/file"));
696 BOOST_TEST(!(p11 != L"c:\\file"));
697 BOOST_TEST(!(p11 != L"c:/file"));
698 BOOST_TEST(!(L"c:\\file" != p10));
699 BOOST_TEST(!(L"c:/file" != p10));
700 BOOST_TEST(!(L"c:\\file" != p11));
701 BOOST_TEST(!(L"c:/file" != p11));
702
703 BOOST_TEST(!(p10.string() < p11.string()));
704 BOOST_TEST(!(p10 < p11));
705 BOOST_TEST(!(p10 < p11.string()));
706 BOOST_TEST(!(p10 < p11.string().c_str()));
707 BOOST_TEST(!(p10.string() < p11));
708 BOOST_TEST(!(p10.string().c_str() < p11));
709 BOOST_TEST(!(p10 < L"c:\\file"));
710 BOOST_TEST(!(p10 < L"c:/file"));
711 BOOST_TEST(!(p11 < L"c:\\file"));
712 BOOST_TEST(!(p11 < L"c:/file"));
713 BOOST_TEST(!(L"c:\\file" < p10));
714 BOOST_TEST(!(L"c:/file" < p10));
715 BOOST_TEST(!(L"c:\\file" < p11));
716 BOOST_TEST(!(L"c:/file" < p11));
717
718 BOOST_TEST(!(p10.generic_string() > p11.generic_string()));
719 BOOST_TEST(!(p10 > p11));
720 BOOST_TEST(!(p10 > p11.string()));
721 BOOST_TEST(!(p10 > p11.string().c_str()));
722 BOOST_TEST(!(p10.string() > p11));
723 BOOST_TEST(!(p10.string().c_str() > p11));
724 BOOST_TEST(!(p10 > L"c:\\file"));
725 BOOST_TEST(!(p10 > L"c:/file"));
726 BOOST_TEST(!(p11 > L"c:\\file"));
727 BOOST_TEST(!(p11 > L"c:/file"));
728 BOOST_TEST(!(L"c:\\file" > p10));
729 BOOST_TEST(!(L"c:/file" > p10));
730 BOOST_TEST(!(L"c:\\file" > p11));
731 BOOST_TEST(!(L"c:/file" > p11));
732 }
733 }
734
735 // query_and_decomposition_tests ---------------------------------------------------//
736 //
737 // remove_filename() is also tested here, because its specification depends on
738 // a decomposition function.
739
query_and_decomposition_tests()740 void query_and_decomposition_tests()
741 {
742 std::cout << "query_and_decomposition_tests..." << std::endl;
743
744 // stem() tests not otherwise covered
745 BOOST_TEST(path("b").stem() == "b");
746 BOOST_TEST(path("a/b.txt").stem() == "b");
747 BOOST_TEST(path("a/b.").stem() == "b");
748 BOOST_TEST(path("a.b.c").stem() == "a.b");
749 BOOST_TEST(path("a.b.c.").stem() == "a.b.c");
750
751 // extension() tests not otherwise covered
752 BOOST_TEST(path("a/b").extension() == "");
753 BOOST_TEST(path("a.b/c").extension() == "");
754 BOOST_TEST(path("a/b.txt").extension() == ".txt");
755 BOOST_TEST(path("a/b.").extension() == ".");
756 BOOST_TEST(path("a.b.c").extension() == ".c");
757 BOOST_TEST(path("a.b.c.").extension() == ".");
758 BOOST_TEST(path("a/").extension() == "");
759
760 // main q & d test sequence
761 path p;
762 path q;
763
764 p = q = "";
765 BOOST_TEST(p.relative_path().string() == "");
766 BOOST_TEST(p.parent_path().string() == "");
767 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
768 BOOST_TEST(p.filename() == "");
769 BOOST_TEST(p.stem() == "");
770 BOOST_TEST(p.extension() == "");
771 BOOST_TEST(p.root_name() == "");
772 BOOST_TEST(p.root_directory() == "");
773 BOOST_TEST(p.root_path().string() == "");
774 BOOST_TEST(!p.has_root_path());
775 BOOST_TEST(!p.has_root_name());
776 BOOST_TEST(!p.has_root_directory());
777 BOOST_TEST(!p.has_relative_path());
778 BOOST_TEST(!p.has_filename());
779 BOOST_TEST(!p.has_stem());
780 BOOST_TEST(!p.has_extension());
781 BOOST_TEST(!p.has_parent_path());
782 BOOST_TEST(!p.is_absolute());
783
784 p = q = "/";
785 BOOST_TEST(p.relative_path().string() == "");
786 BOOST_TEST(p.parent_path().string() == "");
787 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
788 BOOST_TEST(p.filename() == "/");
789 BOOST_TEST(p.stem() == "/");
790 BOOST_TEST(p.extension() == "");
791 BOOST_TEST(p.root_name() == "");
792 BOOST_TEST(p.root_directory() == "/");
793 BOOST_TEST(p.root_path().string() == "/");
794 BOOST_TEST(p.has_root_path());
795 BOOST_TEST(!p.has_root_name());
796 BOOST_TEST(p.has_root_directory());
797 BOOST_TEST(!p.has_relative_path());
798 BOOST_TEST(p.has_filename());
799 BOOST_TEST(p.has_stem());
800 BOOST_TEST(!p.has_extension());
801 BOOST_TEST(!p.has_parent_path());
802 if (platform == "POSIX")
803 BOOST_TEST(p.is_absolute());
804 else
805 BOOST_TEST(!p.is_absolute());
806
807 p = q = "//";
808 PATH_TEST_EQ(p.relative_path().string(), "");
809 PATH_TEST_EQ(p.parent_path().string(), "");
810 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
811 PATH_TEST_EQ(p.filename(), "//");
812 PATH_TEST_EQ(p.stem(), "//");
813 PATH_TEST_EQ(p.extension(), "");
814 PATH_TEST_EQ(p.root_name(), "//");
815 PATH_TEST_EQ(p.root_directory(), "");
816 PATH_TEST_EQ(p.root_path().string(), "//");
817 BOOST_TEST(p.has_root_path());
818 BOOST_TEST(p.has_root_name());
819 BOOST_TEST(!p.has_root_directory());
820 BOOST_TEST(!p.has_relative_path());
821 BOOST_TEST(p.has_filename());
822 BOOST_TEST(p.has_stem());
823 BOOST_TEST(!p.has_extension());
824 BOOST_TEST(!p.has_parent_path());
825 BOOST_TEST(!p.is_absolute());
826
827 p = q = "///";
828 PATH_TEST_EQ(p.relative_path().string(), "");
829 PATH_TEST_EQ(p.parent_path().string(), "");
830 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
831 PATH_TEST_EQ(p.filename(), "/");
832 PATH_TEST_EQ(p.stem(), "/");
833 PATH_TEST_EQ(p.extension(), "");
834 PATH_TEST_EQ(p.root_name(), "");
835 PATH_TEST_EQ(p.root_directory(), "/");
836 PATH_TEST_EQ(p.root_path().string(), "/");
837 BOOST_TEST(p.has_root_path());
838 BOOST_TEST(!p.has_root_name());
839 BOOST_TEST(p.has_root_directory());
840 BOOST_TEST(!p.has_relative_path());
841 BOOST_TEST(p.has_filename());
842 BOOST_TEST(p.has_stem());
843 BOOST_TEST(!p.has_extension());
844 BOOST_TEST(!p.has_parent_path());
845 if (platform == "POSIX")
846 BOOST_TEST(p.is_absolute());
847 else
848 BOOST_TEST(!p.is_absolute());
849
850 p = q = ".";
851 BOOST_TEST(p.relative_path().string() == ".");
852 BOOST_TEST(p.parent_path().string() == "");
853 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
854 BOOST_TEST(p.filename() == ".");
855 BOOST_TEST(p.stem() == ".");
856 BOOST_TEST(p.extension() == "");
857 BOOST_TEST(p.root_name() == "");
858 BOOST_TEST(p.root_directory() == "");
859 BOOST_TEST(p.root_path().string() == "");
860 BOOST_TEST(!p.has_root_path());
861 BOOST_TEST(!p.has_root_name());
862 BOOST_TEST(!p.has_root_directory());
863 BOOST_TEST(p.has_relative_path());
864 BOOST_TEST(p.has_filename());
865 BOOST_TEST(p.has_stem());
866 BOOST_TEST(!p.has_extension());
867 BOOST_TEST(!p.has_parent_path());
868 BOOST_TEST(!p.is_absolute());
869
870 p = q = "..";
871 BOOST_TEST(p.relative_path().string() == "..");
872 BOOST_TEST(p.parent_path().string() == "");
873 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
874 BOOST_TEST(p.filename() == "..");
875 BOOST_TEST(p.stem() == "..");
876 BOOST_TEST(p.extension() == "");
877 BOOST_TEST(p.root_name() == "");
878 BOOST_TEST(p.root_directory() == "");
879 BOOST_TEST(p.root_path().string() == "");
880 BOOST_TEST(!p.has_root_path());
881 BOOST_TEST(!p.has_root_name());
882 BOOST_TEST(!p.has_root_directory());
883 BOOST_TEST(p.has_relative_path());
884 BOOST_TEST(p.has_filename());
885 BOOST_TEST(p.has_stem());
886 BOOST_TEST(!p.has_extension());
887 BOOST_TEST(!p.has_parent_path());
888 BOOST_TEST(!p.is_absolute());
889
890 p = q = "foo";
891 BOOST_TEST(p.relative_path().string() == "foo");
892 BOOST_TEST(p.parent_path().string() == "");
893 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
894 BOOST_TEST(p.filename() == "foo");
895 BOOST_TEST(p.stem() == "foo");
896 BOOST_TEST(p.extension() == "");
897 BOOST_TEST(p.root_name() == "");
898 BOOST_TEST(p.root_directory() == "");
899 BOOST_TEST(p.root_path().string() == "");
900 BOOST_TEST(!p.has_root_path());
901 BOOST_TEST(!p.has_root_name());
902 BOOST_TEST(!p.has_root_directory());
903 BOOST_TEST(p.has_relative_path());
904 BOOST_TEST(p.has_filename());
905 BOOST_TEST(p.has_stem());
906 BOOST_TEST(!p.has_extension());
907 BOOST_TEST(!p.has_parent_path());
908 BOOST_TEST(!p.is_absolute());
909
910 p = q = "/foo";
911 PATH_TEST_EQ(p.relative_path().string(), "foo");
912 PATH_TEST_EQ(p.parent_path().string(), "/");
913 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
914 PATH_TEST_EQ(p.filename(), "foo");
915 PATH_TEST_EQ(p.stem(), "foo");
916 PATH_TEST_EQ(p.extension(), "");
917 PATH_TEST_EQ(p.root_name(), "");
918 PATH_TEST_EQ(p.root_directory(), "/");
919 PATH_TEST_EQ(p.root_path().string(), "/");
920 BOOST_TEST(p.has_root_path());
921 BOOST_TEST(!p.has_root_name());
922 BOOST_TEST(p.has_root_directory());
923 BOOST_TEST(p.has_relative_path());
924 BOOST_TEST(p.has_filename());
925 BOOST_TEST(p.has_stem());
926 BOOST_TEST(!p.has_extension());
927 BOOST_TEST(p.has_parent_path());
928 if (platform == "POSIX")
929 BOOST_TEST(p.is_absolute());
930 else
931 BOOST_TEST(!p.is_absolute());
932
933 p = q = "/foo/";
934 PATH_TEST_EQ(p.relative_path().string(), "foo/");
935 PATH_TEST_EQ(p.parent_path().string(), "/foo");
936 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
937 PATH_TEST_EQ(p.filename(), ".");
938 PATH_TEST_EQ(p.stem(), ".");
939 PATH_TEST_EQ(p.extension(), "");
940 PATH_TEST_EQ(p.root_name(), "");
941 PATH_TEST_EQ(p.root_directory(), "/");
942 PATH_TEST_EQ(p.root_path().string(), "/");
943 BOOST_TEST(p.has_root_path());
944 BOOST_TEST(!p.has_root_name());
945 BOOST_TEST(p.has_root_directory());
946 BOOST_TEST(p.has_relative_path());
947 BOOST_TEST(p.has_filename());
948 BOOST_TEST(p.has_stem());
949 BOOST_TEST(!p.has_extension());
950 BOOST_TEST(p.has_parent_path());
951 if (platform == "POSIX")
952 BOOST_TEST(p.is_absolute());
953 else
954 BOOST_TEST(!p.is_absolute());
955
956 p = q = "///foo";
957 PATH_TEST_EQ(p.relative_path().string(), "foo");
958 PATH_TEST_EQ(p.parent_path().string(), "/");
959 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
960 PATH_TEST_EQ(p.filename(), "foo");
961 PATH_TEST_EQ(p.root_name(), "");
962 PATH_TEST_EQ(p.root_directory(), "/");
963 PATH_TEST_EQ(p.root_path().string(), "/");
964 BOOST_TEST(p.has_root_path());
965 BOOST_TEST(!p.has_root_name());
966 BOOST_TEST(p.has_root_directory());
967 BOOST_TEST(p.has_relative_path());
968 BOOST_TEST(p.has_filename());
969 BOOST_TEST(p.has_parent_path());
970 if (platform == "POSIX")
971 BOOST_TEST(p.is_absolute());
972 else
973 BOOST_TEST(!p.is_absolute());
974
975 p = q = "foo/bar";
976 BOOST_TEST(p.relative_path().string() == "foo/bar");
977 BOOST_TEST(p.parent_path().string() == "foo");
978 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
979 BOOST_TEST(p.filename() == "bar");
980 BOOST_TEST(p.stem() == "bar");
981 BOOST_TEST(p.extension() == "");
982 BOOST_TEST(p.root_name() == "");
983 BOOST_TEST(p.root_directory() == "");
984 BOOST_TEST(p.root_path().string() == "");
985 BOOST_TEST(!p.has_root_path());
986 BOOST_TEST(!p.has_root_name());
987 BOOST_TEST(!p.has_root_directory());
988 BOOST_TEST(p.has_relative_path());
989 BOOST_TEST(p.has_filename());
990 BOOST_TEST(p.has_stem());
991 BOOST_TEST(!p.has_extension());
992 BOOST_TEST(p.has_parent_path());
993 BOOST_TEST(!p.is_absolute());
994
995 p = q = "../foo";
996 BOOST_TEST(p.relative_path().string() == "../foo");
997 BOOST_TEST(p.parent_path().string() == "..");
998 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
999 BOOST_TEST(p.filename() == "foo");
1000 BOOST_TEST(p.root_name() == "");
1001 BOOST_TEST(p.root_directory() == "");
1002 BOOST_TEST(p.root_path().string() == "");
1003 BOOST_TEST(!p.has_root_path());
1004 BOOST_TEST(!p.has_root_name());
1005 BOOST_TEST(!p.has_root_directory());
1006 BOOST_TEST(p.has_relative_path());
1007 BOOST_TEST(p.has_filename());
1008 BOOST_TEST(p.has_parent_path());
1009 BOOST_TEST(!p.is_absolute());
1010
1011 p = q = "..///foo";
1012 PATH_TEST_EQ(p.relative_path().string(), "..///foo");
1013 PATH_TEST_EQ(p.parent_path().string(), "..");
1014 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1015 PATH_TEST_EQ(p.filename(), "foo");
1016 PATH_TEST_EQ(p.root_name(), "");
1017 PATH_TEST_EQ(p.root_directory(), "");
1018 PATH_TEST_EQ(p.root_path().string(), "");
1019 BOOST_TEST(!p.has_root_path());
1020 BOOST_TEST(!p.has_root_name());
1021 BOOST_TEST(!p.has_root_directory());
1022 BOOST_TEST(p.has_relative_path());
1023 BOOST_TEST(p.has_filename());
1024 BOOST_TEST(p.has_parent_path());
1025 BOOST_TEST(!p.is_absolute());
1026
1027 p = q = "/foo/bar";
1028 BOOST_TEST(p.relative_path().string() == "foo/bar");
1029 BOOST_TEST(p.parent_path().string() == "/foo");
1030 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1031 BOOST_TEST(p.filename() == "bar");
1032 BOOST_TEST(p.root_name() == "");
1033 BOOST_TEST(p.root_directory() == "/");
1034 BOOST_TEST(p.root_path().string() == "/");
1035 BOOST_TEST(p.has_root_path());
1036 BOOST_TEST(!p.has_root_name());
1037 BOOST_TEST(p.has_root_directory());
1038 BOOST_TEST(p.has_relative_path());
1039 BOOST_TEST(p.has_filename());
1040 BOOST_TEST(p.has_parent_path());
1041 if (platform == "POSIX")
1042 BOOST_TEST(p.is_absolute());
1043 else
1044 BOOST_TEST(!p.is_absolute());
1045
1046 // Both POSIX and Windows allow two leading slashs
1047 // (POSIX meaning is implementation defined)
1048 PATH_TEST_EQ(path("//resource"), "//resource");
1049 PATH_TEST_EQ(path("//resource/"), "//resource/");
1050 PATH_TEST_EQ(path("//resource/foo"), "//resource/foo");
1051
1052 p = q = path("//net");
1053 PATH_TEST_EQ(p.string(), "//net");
1054 PATH_TEST_EQ(p.relative_path().string(), "");
1055 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1056 PATH_TEST_EQ(p.parent_path().string(), "");
1057 PATH_TEST_EQ(p.filename(), "//net");
1058 PATH_TEST_EQ(p.root_name(), "//net");
1059 PATH_TEST_EQ(p.root_directory(), "");
1060 PATH_TEST_EQ(p.root_path().string(), "//net");
1061 BOOST_TEST(p.has_root_path());
1062 BOOST_TEST(p.has_root_name());
1063 BOOST_TEST(!p.has_root_directory());
1064 BOOST_TEST(!p.has_relative_path());
1065 BOOST_TEST(p.has_filename());
1066 BOOST_TEST(!p.has_parent_path());
1067 BOOST_TEST(!p.is_absolute());
1068
1069 p = q = path("//net/");
1070 BOOST_TEST(p.relative_path().string() == "");
1071 BOOST_TEST(p.parent_path().string() == "//net");
1072 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1073 BOOST_TEST(p.filename() == "/");
1074 BOOST_TEST(p.root_name() == "//net");
1075 BOOST_TEST(p.root_directory() == "/");
1076 BOOST_TEST(p.root_path().string() == "//net/");
1077 BOOST_TEST(p.has_root_path());
1078 BOOST_TEST(p.has_root_name());
1079 BOOST_TEST(p.has_root_directory());
1080 BOOST_TEST(!p.has_relative_path());
1081 BOOST_TEST(p.has_filename());
1082 BOOST_TEST(p.has_parent_path());
1083 BOOST_TEST(p.is_absolute());
1084
1085 p = q = path("//net/foo");
1086 BOOST_TEST(p.relative_path().string() == "foo");
1087 BOOST_TEST(p.parent_path().string() == "//net/");
1088 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1089 BOOST_TEST(p.filename() == "foo");
1090 BOOST_TEST(p.root_name() == "//net");
1091 BOOST_TEST(p.root_directory() == "/");
1092 BOOST_TEST(p.root_path().string() == "//net/");
1093 BOOST_TEST(p.has_root_path());
1094 BOOST_TEST(p.has_root_name());
1095 BOOST_TEST(p.has_root_directory());
1096 BOOST_TEST(p.has_relative_path());
1097 BOOST_TEST(p.has_filename());
1098 BOOST_TEST(p.has_parent_path());
1099 BOOST_TEST(p.is_absolute());
1100
1101 p = q = path("//net///foo");
1102 PATH_TEST_EQ(p.relative_path().string(), "foo");
1103 PATH_TEST_EQ(p.parent_path().string(), "//net/");
1104 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1105 PATH_TEST_EQ(p.filename(), "foo");
1106 PATH_TEST_EQ(p.root_name(), "//net");
1107 PATH_TEST_EQ(p.root_directory(), "/");
1108 PATH_TEST_EQ(p.root_path().string(), "//net/");
1109 BOOST_TEST(p.has_root_path());
1110 BOOST_TEST(p.has_root_name());
1111 BOOST_TEST(p.has_root_directory());
1112 BOOST_TEST(p.has_relative_path());
1113 BOOST_TEST(p.has_filename());
1114 BOOST_TEST(p.has_parent_path());
1115 BOOST_TEST(p.is_absolute());
1116
1117 // ticket 2739, infinite recursion leading to stack overflow, was caused
1118 // by failure to handle this case correctly on Windows.
1119 p = path(":");
1120 PATH_TEST_EQ(p.parent_path().string(), "");
1121 PATH_TEST_EQ(p.filename(), ":");
1122 BOOST_TEST(!p.has_parent_path());
1123 BOOST_TEST(p.has_filename());
1124
1125 // test some similar cases that both POSIX and Windows should handle identically
1126 p = path("c:");
1127 PATH_TEST_EQ(p.parent_path().string(), "");
1128 PATH_TEST_EQ(p.filename(), "c:");
1129 BOOST_TEST(!p.has_parent_path());
1130 BOOST_TEST(p.has_filename());
1131 p = path("cc:");
1132 PATH_TEST_EQ(p.parent_path().string(), "");
1133 PATH_TEST_EQ(p.filename(), "cc:");
1134 BOOST_TEST(!p.has_parent_path());
1135 BOOST_TEST(p.has_filename());
1136
1137 // Windows specific tests
1138 if (platform == "Windows")
1139 {
1140
1141 //p = q = L"\\\\?\\";
1142 //BOOST_TEST(p.relative_path().string() == "");
1143 //BOOST_TEST(p.parent_path().string() == "");
1144 //PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1145 //BOOST_TEST(p.filename() == "");
1146 //BOOST_TEST(p.stem() == "");
1147 //BOOST_TEST(p.extension() == "");
1148 //BOOST_TEST(p.root_name() == "");
1149 //BOOST_TEST(p.root_directory() == "");
1150 //BOOST_TEST(p.root_path().string() == "");
1151 //BOOST_TEST(!p.has_root_path());
1152 //BOOST_TEST(!p.has_root_name());
1153 //BOOST_TEST(!p.has_root_directory());
1154 //BOOST_TEST(!p.has_relative_path());
1155 //BOOST_TEST(!p.has_filename());
1156 //BOOST_TEST(!p.has_stem());
1157 //BOOST_TEST(!p.has_extension());
1158 //BOOST_TEST(!p.has_parent_path());
1159 //BOOST_TEST(!p.is_absolute());
1160
1161 p = q = path("c:");
1162 BOOST_TEST(p.relative_path().string() == "");
1163 BOOST_TEST(p.parent_path().string() == "");
1164 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1165 BOOST_TEST(p.filename() == "c:");
1166 BOOST_TEST(p.root_name() == "c:");
1167 BOOST_TEST(p.root_directory() == "");
1168 BOOST_TEST(p.root_path().string() == "c:");
1169 BOOST_TEST(p.has_root_path());
1170 BOOST_TEST(p.has_root_name());
1171 BOOST_TEST(!p.has_root_directory());
1172 BOOST_TEST(!p.has_relative_path());
1173 BOOST_TEST(p.has_filename());
1174 BOOST_TEST(!p.has_parent_path());
1175 BOOST_TEST(!p.is_absolute());
1176
1177 //p = q = path(L"\\\\?\\c:");
1178 //BOOST_TEST(p.relative_path().string() == "");
1179 //BOOST_TEST(p.parent_path().string() == "");
1180 //PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1181 //BOOST_TEST(p.filename() == "c:");
1182 //BOOST_TEST(p.root_name() == "c:");
1183 //BOOST_TEST(p.root_directory() == "");
1184 //BOOST_TEST(p.root_path().string() == "c:");
1185 //BOOST_TEST(p.has_root_path());
1186 //BOOST_TEST(p.has_root_name());
1187 //BOOST_TEST(!p.has_root_directory());
1188 //BOOST_TEST(!p.has_relative_path());
1189 //BOOST_TEST(p.has_filename());
1190 //BOOST_TEST(!p.has_parent_path());
1191 //BOOST_TEST(!p.is_absolute());
1192
1193 p = q = path("c:foo");
1194 BOOST_TEST(p.relative_path().string() == "foo");
1195 BOOST_TEST(p.parent_path().string() == "c:");
1196 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1197 BOOST_TEST(p.filename() == "foo");
1198 BOOST_TEST(p.root_name() == "c:");
1199 BOOST_TEST(p.root_directory() == "");
1200 BOOST_TEST(p.root_path().string() == "c:");
1201 BOOST_TEST(p.has_root_path());
1202 BOOST_TEST(p.has_root_name());
1203 BOOST_TEST(!p.has_root_directory());
1204 BOOST_TEST(p.has_relative_path());
1205 BOOST_TEST(p.has_filename());
1206 BOOST_TEST(p.has_parent_path());
1207 BOOST_TEST(!p.is_absolute());
1208
1209 //p = q = path(L"\\\\?\\c:foo");
1210 //BOOST_TEST(p.relative_path().string() == "foo");
1211 //BOOST_TEST(p.parent_path().string() == "c:");
1212 //PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1213 //BOOST_TEST(p.filename() == "foo");
1214 //BOOST_TEST(p.root_name() == "c:");
1215 //BOOST_TEST(p.root_directory() == "");
1216 //BOOST_TEST(p.root_path().string() == "c:");
1217 //BOOST_TEST(p.has_root_path());
1218 //BOOST_TEST(p.has_root_name());
1219 //BOOST_TEST(!p.has_root_directory());
1220 //BOOST_TEST(p.has_relative_path());
1221 //BOOST_TEST(p.has_filename());
1222 //BOOST_TEST(p.has_parent_path());
1223 //BOOST_TEST(!p.is_absolute());
1224
1225 p = q = path("c:/");
1226 BOOST_TEST(p.relative_path().string() == "");
1227 BOOST_TEST(p.parent_path().string() == "c:");
1228 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1229 BOOST_TEST(p.filename() == "/");
1230 BOOST_TEST(p.root_name() == "c:");
1231 BOOST_TEST(p.root_directory() == "/");
1232 BOOST_TEST(p.root_path().string() == "c:/");
1233 BOOST_TEST(p.has_root_path());
1234 BOOST_TEST(p.has_root_name());
1235 BOOST_TEST(p.has_root_directory());
1236 BOOST_TEST(!p.has_relative_path());
1237 BOOST_TEST(p.has_filename());
1238 BOOST_TEST(p.has_parent_path());
1239 BOOST_TEST(p.is_absolute());
1240
1241 p = q = path("c:..");
1242 BOOST_TEST(p.relative_path().string() == "..");
1243 BOOST_TEST(p.parent_path().string() == "c:");
1244 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1245 BOOST_TEST(p.filename() == "..");
1246 BOOST_TEST(p.root_name() == "c:");
1247 BOOST_TEST(p.root_directory() == "");
1248 BOOST_TEST(p.root_path().string() == "c:");
1249 BOOST_TEST(p.has_root_path());
1250 BOOST_TEST(p.has_root_name());
1251 BOOST_TEST(!p.has_root_directory());
1252 BOOST_TEST(p.has_relative_path());
1253 BOOST_TEST(p.has_filename());
1254 BOOST_TEST(p.has_parent_path());
1255 BOOST_TEST(!p.is_absolute());
1256
1257 p = q = path("c:/foo");
1258 PATH_TEST_EQ(p.relative_path().string(), "foo");
1259 PATH_TEST_EQ(p.parent_path().string(), "c:/");
1260 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1261 PATH_TEST_EQ(p.filename(), "foo");
1262 PATH_TEST_EQ(p.root_name(), "c:");
1263 PATH_TEST_EQ(p.root_directory(), "/");
1264 PATH_TEST_EQ(p.root_path().string(), "c:/");
1265 BOOST_TEST(p.has_root_path());
1266 BOOST_TEST(p.has_root_name());
1267 BOOST_TEST(p.has_root_directory());
1268 BOOST_TEST(p.has_relative_path());
1269 BOOST_TEST(p.has_filename());
1270 BOOST_TEST(p.has_parent_path());
1271 BOOST_TEST(p.is_absolute());
1272
1273 p = q = path("c://foo");
1274 PATH_TEST_EQ(p.relative_path().string(), "foo");
1275 PATH_TEST_EQ(p.parent_path().string(), "c:/");
1276 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1277 PATH_TEST_EQ(p.filename(), "foo");
1278 PATH_TEST_EQ(p.root_name(), "c:");
1279 PATH_TEST_EQ(p.root_directory(), "/");
1280 PATH_TEST_EQ(p.root_path().string(), "c:/");
1281 BOOST_TEST(p.has_root_path());
1282 BOOST_TEST(p.has_root_name());
1283 BOOST_TEST(p.has_root_directory());
1284 BOOST_TEST(p.has_relative_path());
1285 BOOST_TEST(p.has_filename());
1286 BOOST_TEST(p.has_parent_path());
1287 BOOST_TEST(p.is_absolute());
1288
1289 p = q = path("c:\\foo\\bar");
1290 PATH_TEST_EQ(p.relative_path().string(), "foo\\bar");
1291 PATH_TEST_EQ(p.parent_path().string(), "c:\\foo");
1292 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1293 PATH_TEST_EQ(p.filename(), "bar");
1294 PATH_TEST_EQ(p.root_name(), "c:");
1295 PATH_TEST_EQ(p.root_directory(), "\\");
1296 PATH_TEST_EQ(p.root_path().string(), "c:\\");
1297 BOOST_TEST(p.has_root_path());
1298 BOOST_TEST(p.has_root_name());
1299 BOOST_TEST(p.has_root_directory());
1300 BOOST_TEST(p.has_relative_path());
1301 BOOST_TEST(p.has_filename());
1302 BOOST_TEST(p.has_parent_path());
1303 BOOST_TEST(p.is_absolute());
1304
1305 p = q = path("prn:");
1306 BOOST_TEST(p.relative_path().string() == "");
1307 BOOST_TEST(p.parent_path().string() == "");
1308 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1309 BOOST_TEST(p.filename() == "prn:");
1310 BOOST_TEST(p.root_name() == "prn:");
1311 BOOST_TEST(p.root_directory() == "");
1312 BOOST_TEST(p.root_path().string() == "prn:");
1313 BOOST_TEST(p.has_root_path());
1314 BOOST_TEST(p.has_root_name());
1315 BOOST_TEST(!p.has_root_directory());
1316 BOOST_TEST(!p.has_relative_path());
1317 BOOST_TEST(p.has_filename());
1318 BOOST_TEST(!p.has_parent_path());
1319 BOOST_TEST(!p.is_absolute());
1320
1321 p = q = path("\\\\net\\\\\\foo");
1322 PATH_TEST_EQ(p.relative_path().string(), "foo");
1323 PATH_TEST_EQ(p.parent_path().string(), "\\\\net\\");
1324 PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1325 PATH_TEST_EQ(p.filename(), "foo");
1326 PATH_TEST_EQ(p.root_name(), "\\\\net");
1327 PATH_TEST_EQ(p.root_directory(), "\\");
1328 PATH_TEST_EQ(p.root_path().string(), "\\\\net\\");
1329 BOOST_TEST(p.has_root_path());
1330 BOOST_TEST(p.has_root_name());
1331 BOOST_TEST(p.has_root_directory());
1332 BOOST_TEST(p.has_relative_path());
1333 BOOST_TEST(p.has_filename());
1334 BOOST_TEST(p.has_parent_path());
1335 BOOST_TEST(p.is_absolute());
1336 } // Windows
1337
1338 else
1339 { // POSIX
1340 PATH_TEST_EQ(path("/foo/bar/"), "/foo/bar/");
1341 PATH_TEST_EQ(path("//foo//bar//"), "//foo//bar//");
1342 PATH_TEST_EQ(path("///foo///bar///"), "///foo///bar///");
1343
1344 p = path("/usr/local/bin:/usr/bin:/bin");
1345 BOOST_TEST(p.string() == "/usr/local/bin:/usr/bin:/bin");
1346 } // POSIX
1347 }
1348
1349 // composition_tests ----------------------------------------------------------------//
1350
composition_tests()1351 void composition_tests()
1352 {
1353 std::cout << "composition_tests..." << std::endl;
1354
1355 }
1356
1357 // construction_tests ---------------------------------------------------------------//
1358
construction_tests()1359 void construction_tests()
1360 {
1361 std::cout << "construction_tests..." << std::endl;
1362
1363 PATH_TEST_EQ("", "");
1364
1365 PATH_TEST_EQ("foo", "foo");
1366 PATH_TEST_EQ("f", "f");
1367
1368 PATH_TEST_EQ("foo/", "foo/");
1369 PATH_TEST_EQ("f/", "f/");
1370 PATH_TEST_EQ("foo/..", "foo/..");
1371 PATH_TEST_EQ("foo/../", "foo/../");
1372 PATH_TEST_EQ("foo/bar/../..", "foo/bar/../..");
1373 PATH_TEST_EQ("foo/bar/../../", "foo/bar/../../");
1374 PATH_TEST_EQ("/", "/");
1375 PATH_TEST_EQ("/f", "/f");
1376
1377 PATH_TEST_EQ("/foo", "/foo");
1378 PATH_TEST_EQ("/foo/bar/", "/foo/bar/");
1379 PATH_TEST_EQ("//foo//bar//", "//foo//bar//");
1380 PATH_TEST_EQ("///foo///bar///", "///foo///bar///");
1381 PATH_TEST_EQ("\\/foo\\/bar\\/", "\\/foo\\/bar\\/");
1382 PATH_TEST_EQ("\\//foo\\//bar\\//", "\\//foo\\//bar\\//");
1383
1384 if (platform == "Windows")
1385 {
1386 PATH_TEST_EQ(path("c:") / "foo", "c:foo");
1387 PATH_TEST_EQ(path("c:") / "/foo", "c:/foo");
1388
1389 PATH_TEST_EQ("\\foo\\bar\\", "\\foo\\bar\\");
1390 PATH_TEST_EQ("\\\\foo\\\\bar\\\\", "\\\\foo\\\\bar\\\\");
1391 PATH_TEST_EQ("\\\\\\foo\\\\\\bar\\\\\\", "\\\\\\foo\\\\\\bar\\\\\\");
1392
1393 PATH_TEST_EQ("\\", "\\");
1394 PATH_TEST_EQ("\\f", "\\f");
1395 PATH_TEST_EQ("\\foo", "\\foo");
1396 PATH_TEST_EQ("foo\\bar", "foo\\bar");
1397 PATH_TEST_EQ("foo bar", "foo bar");
1398 PATH_TEST_EQ("c:", "c:");
1399 PATH_TEST_EQ("c:/", "c:/");
1400 PATH_TEST_EQ("c:.", "c:.");
1401 PATH_TEST_EQ("c:./foo", "c:./foo");
1402 PATH_TEST_EQ("c:.\\foo", "c:.\\foo");
1403 PATH_TEST_EQ("c:..", "c:..");
1404 PATH_TEST_EQ("c:/.", "c:/.");
1405 PATH_TEST_EQ("c:/..", "c:/..");
1406 PATH_TEST_EQ("c:/../", "c:/../");
1407 PATH_TEST_EQ("c:\\..\\", "c:\\..\\");
1408 PATH_TEST_EQ("c:/../..", "c:/../..");
1409 PATH_TEST_EQ("c:/../foo", "c:/../foo");
1410 PATH_TEST_EQ("c:\\..\\foo", "c:\\..\\foo");
1411 PATH_TEST_EQ("c:../foo", "c:../foo");
1412 PATH_TEST_EQ("c:..\\foo", "c:..\\foo");
1413 PATH_TEST_EQ("c:/../../foo", "c:/../../foo");
1414 PATH_TEST_EQ("c:\\..\\..\\foo", "c:\\..\\..\\foo");
1415 PATH_TEST_EQ("c:foo/..", "c:foo/..");
1416 PATH_TEST_EQ("c:/foo/..", "c:/foo/..");
1417 PATH_TEST_EQ("c:/..foo", "c:/..foo");
1418 PATH_TEST_EQ("c:foo", "c:foo");
1419 PATH_TEST_EQ("c:/foo", "c:/foo");
1420 PATH_TEST_EQ("\\\\netname", "\\\\netname");
1421 PATH_TEST_EQ("\\\\netname\\", "\\\\netname\\");
1422 PATH_TEST_EQ("\\\\netname\\foo", "\\\\netname\\foo");
1423 PATH_TEST_EQ("c:/foo", "c:/foo");
1424 PATH_TEST_EQ("prn:", "prn:");
1425 }
1426 else
1427 {
1428 }
1429
1430 PATH_TEST_EQ("foo/bar", "foo/bar");
1431 PATH_TEST_EQ("a/b", "a/b"); // probe for length effects
1432 PATH_TEST_EQ("..", "..");
1433 PATH_TEST_EQ("../..", "../..");
1434 PATH_TEST_EQ("/..", "/..");
1435 PATH_TEST_EQ("/../..", "/../..");
1436 PATH_TEST_EQ("../foo", "../foo");
1437 PATH_TEST_EQ("foo/..", "foo/..");
1438 PATH_TEST_EQ("foo/..bar", "foo/..bar");
1439 PATH_TEST_EQ("../f", "../f");
1440 PATH_TEST_EQ("/../f", "/../f");
1441 PATH_TEST_EQ("f/..", "f/..");
1442 PATH_TEST_EQ("foo/../..", "foo/../..");
1443 PATH_TEST_EQ("foo/../../..", "foo/../../..");
1444 PATH_TEST_EQ("foo/../bar", "foo/../bar");
1445 PATH_TEST_EQ("foo/bar/..", "foo/bar/..");
1446 PATH_TEST_EQ("foo/bar/../..", "foo/bar/../..");
1447 PATH_TEST_EQ("foo/bar/../blah", "foo/bar/../blah");
1448 PATH_TEST_EQ("f/../b", "f/../b");
1449 PATH_TEST_EQ("f/b/..", "f/b/..");
1450 PATH_TEST_EQ("f/b/../a", "f/b/../a");
1451 PATH_TEST_EQ("foo/bar/blah/../..", "foo/bar/blah/../..");
1452 PATH_TEST_EQ("foo/bar/blah/../../bletch", "foo/bar/blah/../../bletch");
1453 PATH_TEST_EQ("...", "...");
1454 PATH_TEST_EQ("....", "....");
1455 PATH_TEST_EQ("foo/...", "foo/...");
1456 PATH_TEST_EQ("abc.", "abc.");
1457 PATH_TEST_EQ("abc..", "abc..");
1458 PATH_TEST_EQ("foo/abc.", "foo/abc.");
1459 PATH_TEST_EQ("foo/abc..", "foo/abc..");
1460
1461 PATH_TEST_EQ(".abc", ".abc");
1462 PATH_TEST_EQ("a.c", "a.c");
1463 PATH_TEST_EQ("..abc", "..abc");
1464 PATH_TEST_EQ("a..c", "a..c");
1465 PATH_TEST_EQ("foo/.abc", "foo/.abc");
1466 PATH_TEST_EQ("foo/a.c", "foo/a.c");
1467 PATH_TEST_EQ("foo/..abc", "foo/..abc");
1468 PATH_TEST_EQ("foo/a..c", "foo/a..c");
1469
1470 PATH_TEST_EQ(".", ".");
1471 PATH_TEST_EQ("./foo", "./foo");
1472 PATH_TEST_EQ("./..", "./..");
1473 PATH_TEST_EQ("./../foo", "./../foo");
1474 PATH_TEST_EQ("foo/.", "foo/.");
1475 PATH_TEST_EQ("../.", "../.");
1476 PATH_TEST_EQ("./.", "./.");
1477 PATH_TEST_EQ("././.", "././.");
1478 PATH_TEST_EQ("./foo/.", "./foo/.");
1479 PATH_TEST_EQ("foo/./bar", "foo/./bar");
1480 PATH_TEST_EQ("foo/./.", "foo/./.");
1481 PATH_TEST_EQ("foo/./..", "foo/./..");
1482 PATH_TEST_EQ("foo/./../bar", "foo/./../bar");
1483 PATH_TEST_EQ("foo/../.", "foo/../.");
1484 PATH_TEST_EQ("././..", "././..");
1485 PATH_TEST_EQ("./../.", "./../.");
1486 PATH_TEST_EQ(".././.", ".././.");
1487 }
1488
1489 // append_tests --------------------------------------------------------------------//
1490
append_test_aux(const path & p,const std::string & s,const std::string & expect)1491 void append_test_aux(const path & p, const std::string & s, const std::string & expect)
1492 {
1493 PATH_TEST_EQ((p / path(s)).string(), expect);
1494 PATH_TEST_EQ((p / s.c_str()).string(), expect);
1495 PATH_TEST_EQ((p / s).string(), expect);
1496 path x(p);
1497 x.append(s.begin(), s.end());
1498 PATH_TEST_EQ(x.string(), expect);
1499 }
1500
append_tests()1501 void append_tests()
1502 {
1503 std::cout << "append_tests..." << std::endl;
1504
1505 // There are many control paths to be exercised, since empty paths and arguments,
1506 // paths with trailing separators, arguments with leading separators, with or without
1507 // other characters being present, are all separate cases that need to be tested.
1508 // Furthermore, some of the code to be tested is specific to argument categories,
1509 // so that results in further permutations to be tested.
1510
1511 //// code to generate test cases
1512 ////
1513 //// expected results must be checked by hand
1514 //// "foo\bar" expected result must be edited by hand and moved for Windows/POSIX
1515 ////
1516 //const char* x[] = { "", "/", "foo", "foo/" };
1517 //const char* y[] = { "", "/", "bar", "/bar" };
1518
1519 //for (int i = 0; i < sizeof(x)/sizeof(char*); ++i)
1520 // for (int j = 0; j < sizeof(y)/sizeof(char*); ++j)
1521 // {
1522 // std::cout << "\n PATH_TEST_EQ(path(\"" << x[i] << "\") / \"" << y[j] << "\", \""
1523 // << path(x[i]) / y[j] << "\");\n";
1524 // std::cout << " append_test_aux(\"" << x[i] << "\", \"" << y[j] << "\", \""
1525 // << path(x[i]) / y[j] << "\");\n";
1526 // }
1527
1528 PATH_TEST_EQ(path("") / "", "");
1529 append_test_aux("", "", "");
1530
1531 PATH_TEST_EQ(path("") / "/", "/");
1532 append_test_aux("", "/", "/");
1533
1534 PATH_TEST_EQ(path("") / "bar", "bar");
1535 append_test_aux("", "bar", "bar");
1536
1537 PATH_TEST_EQ(path("") / "/bar", "/bar");
1538 append_test_aux("", "/bar", "/bar");
1539
1540 PATH_TEST_EQ(path("/") / "", "/");
1541 append_test_aux("/", "", "/");
1542
1543 PATH_TEST_EQ(path("/") / "/", "//");
1544 append_test_aux("/", "/", "//");
1545
1546 PATH_TEST_EQ(path("/") / "bar", "/bar");
1547 append_test_aux("/", "bar", "/bar");
1548
1549 PATH_TEST_EQ(path("/") / "/bar", "//bar");
1550 append_test_aux("/", "/bar", "//bar");
1551
1552 PATH_TEST_EQ(path("foo") / "", "foo");
1553 append_test_aux("foo", "", "foo");
1554
1555 PATH_TEST_EQ(path("foo") / "/", "foo/");
1556 append_test_aux("foo", "/", "foo/");
1557
1558 PATH_TEST_EQ(path("foo") / "/bar", "foo/bar");
1559 append_test_aux("foo", "/bar", "foo/bar");
1560
1561 PATH_TEST_EQ(path("foo/") / "", "foo/");
1562 append_test_aux("foo/", "", "foo/");
1563
1564 PATH_TEST_EQ(path("foo/") / "/", "foo//");
1565 append_test_aux("foo/", "/", "foo//");
1566
1567 PATH_TEST_EQ(path("foo/") / "bar", "foo/bar");
1568 append_test_aux("foo/", "bar", "foo/bar");
1569
1570
1571 if (platform == "Windows")
1572 {
1573 PATH_TEST_EQ(path("foo") / "bar", "foo\\bar");
1574 append_test_aux("foo", "bar", "foo\\bar");
1575
1576 PATH_TEST_EQ(path("foo\\") / "\\bar", "foo\\\\bar");
1577 append_test_aux("foo\\", "\\bar", "foo\\\\bar");
1578
1579 // hand created test case specific to Windows
1580 PATH_TEST_EQ(path("c:") / "bar", "c:bar");
1581 append_test_aux("c:", "bar", "c:bar");
1582 }
1583 else
1584 {
1585 PATH_TEST_EQ(path("foo") / "bar", "foo/bar");
1586 append_test_aux("foo", "bar", "foo/bar");
1587 }
1588
1589 // ticket #6819
1590 union
1591 {
1592 char a[1];
1593 char b[3];
1594 } u;
1595
1596 u.b[0] = 'a';
1597 u.b[1] = 'b';
1598 u.b[2] = '\0';
1599
1600 path p6819;
1601 p6819 /= u.a;
1602 BOOST_TEST_EQ(p6819, path("ab"));
1603 }
1604
1605 // self_assign_and_append_tests ------------------------------------------------------//
1606
self_assign_and_append_tests()1607 void self_assign_and_append_tests()
1608 {
1609 std::cout << "self_assign_and_append_tests..." << std::endl;
1610
1611 path p;
1612
1613 p = "snafubar";
1614 PATH_TEST_EQ(p = p, "snafubar");
1615
1616 p = "snafubar";
1617 p = p.c_str();
1618 PATH_TEST_EQ(p, "snafubar");
1619
1620 p = "snafubar";
1621 p.assign(p.c_str(), path::codecvt());
1622 PATH_TEST_EQ(p, "snafubar");
1623
1624 p = "snafubar";
1625 PATH_TEST_EQ(p = p.c_str()+5, "bar");
1626
1627 p = "snafubar";
1628 PATH_TEST_EQ(p.assign(p.c_str() + 5, p.c_str() + 7), "ba");
1629
1630 p = "snafubar";
1631 p /= p;
1632 PATH_TEST_EQ(p, "snafubar" BOOST_DIR_SEP "snafubar");
1633
1634 p = "snafubar";
1635 p /= p.c_str();
1636 PATH_TEST_EQ(p, "snafubar" BOOST_DIR_SEP "snafubar");
1637
1638 p = "snafubar";
1639 p.append(p.c_str(), path::codecvt());
1640 PATH_TEST_EQ(p, "snafubar" BOOST_DIR_SEP "snafubar");
1641
1642 p = "snafubar";
1643 PATH_TEST_EQ(p.append(p.c_str() + 5, p.c_str() + 7), "snafubar" BOOST_DIR_SEP "ba");
1644 }
1645
1646
1647 // name_function_tests -------------------------------------------------------------//
1648
name_function_tests()1649 void name_function_tests()
1650 {
1651 std::cout << "name_function_tests..." << std::endl;
1652
1653 BOOST_TEST(fs::portable_posix_name(std::string("x")));
1654 BOOST_TEST(fs::windows_name(std::string("x")));
1655 BOOST_TEST(fs::portable_name(std::string("x")));
1656 BOOST_TEST(fs::portable_directory_name(std::string("x")));
1657 BOOST_TEST(fs::portable_file_name(std::string("x")));
1658
1659 BOOST_TEST(fs::portable_posix_name(std::string(".")));
1660 BOOST_TEST(fs::windows_name(std::string(".")));
1661 BOOST_TEST(fs::portable_name(std::string(".")));
1662 BOOST_TEST(fs::portable_directory_name(std::string(".")));
1663 BOOST_TEST(!fs::portable_file_name(std::string(".")));
1664
1665 BOOST_TEST(fs::portable_posix_name(std::string("..")));
1666 BOOST_TEST(fs::windows_name(std::string("..")));
1667 BOOST_TEST(fs::portable_name(std::string("..")));
1668 BOOST_TEST(fs::portable_directory_name(std::string("..")));
1669 BOOST_TEST(!fs::portable_file_name(std::string("..")));
1670
1671 BOOST_TEST(!fs::native(std::string("")));
1672 BOOST_TEST(!fs::portable_posix_name(std::string("")));
1673 BOOST_TEST(!fs::windows_name(std::string("")));
1674 BOOST_TEST(!fs::portable_name(std::string("")));
1675 BOOST_TEST(!fs::portable_directory_name(std::string("")));
1676 BOOST_TEST(!fs::portable_file_name(std::string("")));
1677
1678 BOOST_TEST(!fs::native(std::string(" ")));
1679 BOOST_TEST(!fs::portable_posix_name(std::string(" ")));
1680 BOOST_TEST(!fs::windows_name(std::string(" ")));
1681 BOOST_TEST(!fs::portable_name(std::string(" ")));
1682 BOOST_TEST(!fs::portable_directory_name(std::string(" ")));
1683 BOOST_TEST(!fs::portable_file_name(std::string(" ")));
1684
1685 BOOST_TEST(!fs::portable_posix_name(std::string(":")));
1686 BOOST_TEST(!fs::windows_name(std::string(":")));
1687 BOOST_TEST(!fs::portable_name(std::string(":")));
1688 BOOST_TEST(!fs::portable_directory_name(std::string(":")));
1689 BOOST_TEST(!fs::portable_file_name(std::string(":")));
1690
1691 BOOST_TEST(fs::portable_posix_name(std::string("-")));
1692 BOOST_TEST(fs::windows_name(std::string("-")));
1693 BOOST_TEST(!fs::portable_name(std::string("-")));
1694 BOOST_TEST(!fs::portable_directory_name(std::string("-")));
1695 BOOST_TEST(!fs::portable_file_name(std::string("-")));
1696
1697 BOOST_TEST(!fs::portable_posix_name(std::string("foo bar")));
1698 BOOST_TEST(fs::windows_name(std::string("foo bar")));
1699 BOOST_TEST(!fs::windows_name(std::string(" bar")));
1700 BOOST_TEST(!fs::windows_name(std::string("foo ")));
1701 BOOST_TEST(!fs::portable_name(std::string("foo bar")));
1702 BOOST_TEST(!fs::portable_directory_name(std::string("foo bar")));
1703 BOOST_TEST(!fs::portable_file_name(std::string("foo bar")));
1704
1705 BOOST_TEST(fs::portable_posix_name(std::string("foo.bar")));
1706 BOOST_TEST(fs::windows_name(std::string("foo.bar")));
1707 BOOST_TEST(fs::portable_name(std::string("foo.bar")));
1708 BOOST_TEST(!fs::portable_directory_name(std::string("foo.bar")));
1709 BOOST_TEST(fs::portable_file_name(std::string("foo.bar")));
1710
1711 BOOST_TEST(fs::portable_posix_name(std::string("foo.barf")));
1712 BOOST_TEST(fs::windows_name(std::string("foo.barf")));
1713 BOOST_TEST(fs::portable_name(std::string("foo.barf")));
1714 BOOST_TEST(!fs::portable_directory_name(std::string("foo.barf")));
1715 BOOST_TEST(!fs::portable_file_name(std::string("foo.barf")));
1716
1717 BOOST_TEST(fs::portable_posix_name(std::string(".foo")));
1718 BOOST_TEST(fs::windows_name(std::string(".foo")));
1719 BOOST_TEST(!fs::portable_name(std::string(".foo")));
1720 BOOST_TEST(!fs::portable_directory_name(std::string(".foo")));
1721 BOOST_TEST(!fs::portable_file_name(std::string(".foo")));
1722
1723 BOOST_TEST(fs::portable_posix_name(std::string("foo.")));
1724 BOOST_TEST(!fs::windows_name(std::string("foo.")));
1725 BOOST_TEST(!fs::portable_name(std::string("foo.")));
1726 BOOST_TEST(!fs::portable_directory_name(std::string("foo.")));
1727 BOOST_TEST(!fs::portable_file_name(std::string("foo.")));
1728 }
1729
1730 // replace_extension_tests ---------------------------------------------------------//
1731
replace_extension_tests()1732 void replace_extension_tests()
1733 {
1734 std::cout << "replace_extension_tests..." << std::endl;
1735
1736 BOOST_TEST(path().replace_extension().empty());
1737 BOOST_TEST(path().replace_extension("a") == ".a");
1738 BOOST_TEST(path().replace_extension("a.") == ".a.");
1739 BOOST_TEST(path().replace_extension(".a") == ".a");
1740 BOOST_TEST(path().replace_extension("a.txt") == ".a.txt");
1741 // see the rationale in html docs for explanation why this works:
1742 BOOST_TEST(path().replace_extension(".txt") == ".txt");
1743
1744 BOOST_TEST(path("a.txt").replace_extension() == "a");
1745 BOOST_TEST(path("a.txt").replace_extension("") == "a");
1746 BOOST_TEST(path("a.txt").replace_extension(".") == "a.");
1747 BOOST_TEST(path("a.txt").replace_extension(".tex") == "a.tex");
1748 BOOST_TEST(path("a.txt").replace_extension("tex") == "a.tex");
1749 BOOST_TEST(path("a.").replace_extension(".tex") == "a.tex");
1750 BOOST_TEST(path("a.").replace_extension("tex") == "a.tex");
1751 BOOST_TEST(path("a").replace_extension(".txt") == "a.txt");
1752 BOOST_TEST(path("a").replace_extension("txt") == "a.txt");
1753 BOOST_TEST(path("a.b.txt").replace_extension(".tex") == "a.b.tex");
1754 BOOST_TEST(path("a.b.txt").replace_extension("tex") == "a.b.tex");
1755 BOOST_TEST(path("a/b").replace_extension(".c") == "a/b.c");
1756 PATH_TEST_EQ(path("a.txt/b").replace_extension(".c"), "a.txt/b.c"); // ticket 4702
1757 BOOST_TEST(path("foo.txt").replace_extension("exe") == "foo.exe"); // ticket 5118
1758 BOOST_TEST(path("foo.txt").replace_extension(".tar.bz2")
1759 == "foo.tar.bz2"); // ticket 5118
1760 }
1761
1762 // make_preferred_tests ------------------------------------------------------------//
1763
make_preferred_tests()1764 void make_preferred_tests()
1765 {
1766 std::cout << "make_preferred_tests..." << std::endl;
1767
1768 if (platform == "Windows")
1769 {
1770 BOOST_TEST(path("//abc\\def/ghi").make_preferred().native()
1771 == path("\\\\abc\\def\\ghi").native());
1772 }
1773 else
1774 {
1775 BOOST_TEST(path("//abc\\def/ghi").make_preferred().native()
1776 == path("//abc\\def/ghi").native());
1777 }
1778 }
1779
1780 } // unnamed namespace
1781
1782 static boost::filesystem::path ticket_6737 = "FilePath"; // #6737 reported this crashed
1783 // on VC++ debug mode build
1784 const boost::filesystem::path ticket_6690("test"); // #6690 another V++ static init crash
1785
1786 //--------------------------------------------------------------------------------------//
1787 // //
1788 // main //
1789 // //
1790 //--------------------------------------------------------------------------------------//
1791
cpp_main(int,char * [])1792 int cpp_main(int, char*[])
1793 {
1794 // The choice of platform is make at runtime rather than compile-time
1795 // so that compile errors for all platforms will be detected even though
1796 // only the current platform is runtime tested.
1797 platform = (platform == "Win32" || platform == "Win64" || platform == "Cygwin")
1798 ? "Windows"
1799 : "POSIX";
1800 std::cout << "Platform is " << platform << '\n';
1801
1802 BOOST_TEST(p1.string() != p3.string());
1803 p3 = p2;
1804 BOOST_TEST(p1.string() == p3.string());
1805
1806 path p04("foobar");
1807 BOOST_TEST(p04.string() == "foobar");
1808 p04 = p04; // self-assignment
1809 BOOST_TEST(p04.string() == "foobar");
1810
1811 construction_tests();
1812 append_tests();
1813 self_assign_and_append_tests();
1814 overload_tests();
1815 query_and_decomposition_tests();
1816 composition_tests();
1817 iterator_tests();
1818 non_member_tests();
1819 exception_tests();
1820 name_function_tests();
1821 replace_extension_tests();
1822 make_preferred_tests();
1823
1824 // verify deprecated names still available
1825
1826 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
1827
1828 p1.branch_path();
1829 p1.leaf();
1830 path p_remove_leaf;
1831 p_remove_leaf.remove_leaf();
1832
1833 # endif
1834
1835 std::string s1("//:somestring"); // this used to be treated specially
1836
1837 // check the path member templates
1838 p5.assign(s1.begin(), s1.end());
1839
1840 PATH_TEST_EQ(p5.string(), "//:somestring");
1841 p5 = s1;
1842 PATH_TEST_EQ(p5.string(), "//:somestring");
1843
1844 // this code, courtesy of David Whetstone, detects a now fixed bug that
1845 // derefereced the end iterator (assuming debug build with checked itors)
1846 std::vector<char> v1;
1847 p5.assign(v1.begin(), v1.end());
1848 std::string s2(v1.begin(), v1.end());
1849 PATH_TEST_EQ(p5.string(), s2);
1850 p5.assign(s1.begin(), s1.begin() + 1);
1851 PATH_TEST_EQ(p5.string(), "/");
1852
1853 BOOST_TEST(p1 != p4);
1854 BOOST_TEST(p1.string() == p2.string());
1855 BOOST_TEST(p1.string() == p3.string());
1856 BOOST_TEST(path("foo").filename() == "foo");
1857 BOOST_TEST(path("foo").parent_path().string() == "");
1858 BOOST_TEST(p1.filename() == "fum");
1859 BOOST_TEST(p1.parent_path().string() == "fe/fi/fo");
1860 BOOST_TEST(path("").empty() == true);
1861 BOOST_TEST(path("foo").empty() == false);
1862
1863 // inserter and extractor tests
1864 # if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // bypass VC++ 7.0 and earlier
1865 std::cout << "\nInserter and extractor test...";
1866 std::stringstream ss;
1867 ss << fs::path("foo/bar") << std::endl;
1868 fs::path round_trip;
1869 ss >> round_trip;
1870 BOOST_TEST(round_trip.string() == "foo/bar");
1871 std::cout << round_trip.string() << "..." << round_trip << " complete\n";
1872 # endif
1873
1874 return ::boost::report_errors();
1875 }
1876