xref: /haiku/src/tests/kits/storage/PathTest.cpp (revision 2b76973fa2401f7a5edf68e6470f3d3210cbcff3)
1 // PathTest.cpp
2 #include "PathTest.h"
3 
4 #include <cppunit/Test.h>
5 #include <cppunit/TestCaller.h>
6 #include <cppunit/TestSuite.h>
7 #include <Directory.h>
8 #include <Entry.h>
9 #include <Path.h>
10 #include <TypeConstants.h>
11 #include <stdio.h>
12 #include <string>
13 #include <unistd.h>
14 
15 // Suite
16 CppUnit::Test*
17 PathTest::Suite() {
18 	CppUnit::TestSuite *suite = new CppUnit::TestSuite();
19 	typedef CppUnit::TestCaller<PathTest> TC;
20 
21 	suite->addTest( new TC("BPath::Init Test1", &PathTest::InitTest1) );
22 	suite->addTest( new TC("BPath::Init Test2", &PathTest::InitTest2) );
23 	suite->addTest( new TC("BPath::Append Test", &PathTest::AppendTest) );
24 	suite->addTest( new TC("BPath::Leaf Test", &PathTest::LeafTest) );
25 	suite->addTest( new TC("BPath::Parent Test", &PathTest::ParentTest) );
26 	suite->addTest( new TC("BPath::Comparison Test",
27 						   &PathTest::ComparisonTest) );
28 	suite->addTest( new TC("BPath::Assignment Test",
29 						   &PathTest::AssignmentTest) );
30 	suite->addTest( new TC("BPath::Flattenable Test",
31 						   &PathTest::FlattenableTest) );
32 
33 	return suite;
34 }
35 
36 // setUp
37 void
38 PathTest::setUp()
39 {
40 	BasicTest::setUp();
41 }
42 
43 // tearDown
44 void
45 PathTest::tearDown()
46 {
47 	BasicTest::tearDown();
48 }
49 
50 // InitTest1
51 void
52 PathTest::InitTest1()
53 {
54 	// 1. default constructor
55 	NextSubTest();
56 	{
57 		BPath path;
58 		CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
59 		CPPUNIT_ASSERT( path.Path() == NULL );
60 	}
61 
62 	// 2. BPath(const char*, const char*, bool)
63 	// absolute existing path (root dir), no leaf, no normalization
64 	NextSubTest();
65 	{
66 		const char *pathName = "/";
67 		BPath path(pathName);
68 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
69 		CPPUNIT_ASSERT( string(pathName) == path.Path() );
70 	}
71 	// absolute existing path, no leaf, no normalization
72 	NextSubTest();
73 	{
74 		const char *pathName = "/boot";
75 		BPath path(pathName);
76 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
77 		CPPUNIT_ASSERT( string(pathName) == path.Path() );
78 	}
79 	// absolute non-existing path, no leaf, no normalization
80 	NextSubTest();
81 	{
82 		const char *pathName = "/doesn't/exist/but/who/cares";
83 		BPath path(pathName);
84 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
85 		CPPUNIT_ASSERT( string(pathName) == path.Path() );
86 	}
87 	// absolute existing path (root dir), no leaf, auto normalization
88 	NextSubTest();
89 	{
90 		const char *pathName = "/.///.";
91 		const char *normalizedPathName = "/";
92 		BPath path(pathName);
93 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
94 		CPPUNIT_ASSERT( string(normalizedPathName) == path.Path() );
95 	}
96 	// absolute existing path, no leaf, auto normalization
97 	NextSubTest();
98 	{
99 		const char *pathName = "/boot/";
100 		const char *normalizedPathName = "/boot";
101 		BPath path(pathName);
102 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
103 		CPPUNIT_ASSERT( string(normalizedPathName) == path.Path() );
104 	}
105 	// absolute non-existing path, no leaf, auto normalization
106 	NextSubTest();
107 	{
108 		const char *pathName = "/doesn't/exist/but///who/cares";
109 		BPath path(pathName);
110 		CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
111 		CPPUNIT_ASSERT( path.Path() == NULL );
112 	}
113 	// absolute existing path (root dir), no leaf, normalization forced
114 	NextSubTest();
115 	{
116 		const char *pathName = "/";
117 		BPath path(pathName, NULL, true);
118 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
119 		CPPUNIT_ASSERT( string(pathName) == path.Path() );
120 	}
121 	// absolute existing path, no leaf, normalization forced
122 	NextSubTest();
123 	{
124 		const char *pathName = "/boot";
125 		BPath path(pathName, NULL, true);
126 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
127 		CPPUNIT_ASSERT( string(pathName) == path.Path() );
128 	}
129 	// absolute non-existing path, no leaf, normalization forced
130 	NextSubTest();
131 	{
132 		const char *pathName = "/doesn't/exist/but/who/cares";
133 		BPath path(pathName, NULL, true);
134 		CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
135 		CPPUNIT_ASSERT( path.Path() == NULL );
136 	}
137 	// relative existing path, no leaf, no normalization needed, but done
138 	chdir("/");
139 	NextSubTest();
140 	{
141 		const char *pathName = "boot";
142 		const char *absolutePathName = "/boot";
143 		BPath path(pathName);
144 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
145 		CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
146 	}
147 	// relative non-existing path, no leaf, no normalization needed, but done
148 	chdir("/boot");
149 	NextSubTest();
150 	{
151 		const char *pathName = "doesn't/exist/but/who/cares";
152 		BPath path(pathName);
153 		CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
154 		CPPUNIT_ASSERT( path.Path() == NULL );
155 	}
156 	// relative existing path, no leaf, auto normalization
157 	chdir("/");
158 	NextSubTest();
159 	{
160 		const char *pathName = "boot/";
161 		const char *normalizedPathName = "/boot";
162 		BPath path(pathName);
163 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
164 		CPPUNIT_ASSERT( string(normalizedPathName) == path.Path() );
165 	}
166 	// relative non-existing path, no leaf, auto normalization
167 	chdir("/boot");
168 	NextSubTest();
169 	{
170 		const char *pathName = "doesn't/exist/but///who/cares";
171 		BPath path(pathName);
172 		CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
173 		CPPUNIT_ASSERT( path.Path() == NULL );
174 	}
175 	// relative existing path, no leaf, normalization forced
176 	chdir("/");
177 	NextSubTest();
178 	{
179 		const char *pathName = "boot";
180 		const char *absolutePathName = "/boot";
181 		BPath path(pathName, NULL, true);
182 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
183 		CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
184 	}
185 	// relative non-existing path, no leaf, normalization forced
186 	chdir("/boot");
187 	NextSubTest();
188 	{
189 		const char *pathName = "doesn't/exist/but/who/cares";
190 		BPath path(pathName, NULL, true);
191 		CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
192 		CPPUNIT_ASSERT( path.Path() == NULL );
193 	}
194 	// absolute existing path (root dir), leaf, no normalization
195 	NextSubTest();
196 	{
197 		const char *pathName = "/";
198 		const char *leafName = "boot";
199 		const char *absolutePathName = "/boot";
200 		BPath path(pathName, leafName);
201 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
202 		CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
203 	}
204 	// absolute existing path, leaf, no normalization
205 	NextSubTest();
206 	{
207 		const char *pathName = "/boot";
208 		const char *leafName = "home/Desktop";
209 		const char *absolutePathName = "/boot/home/Desktop";
210 		BPath path(pathName, leafName);
211 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
212 		CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
213 	}
214 	// absolute non-existing path, leaf, no normalization
215 	NextSubTest();
216 	{
217 		const char *pathName = "/doesn't/exist";
218 		const char *leafName = "but/who/cares";
219 		const char *absolutePathName = "/doesn't/exist/but/who/cares";
220 		BPath path(pathName, leafName);
221 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
222 		CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
223 	}
224 	// absolute existing path (root dir), leaf, auto normalization
225 	NextSubTest();
226 	{
227 		const char *pathName = "/.///";
228 		const char *leafName = ".";
229 		const char *absolutePathName = "/";
230 		BPath path(pathName, leafName);
231 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
232 		CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
233 	}
234 	// absolute existing path, leaf, auto normalization
235 	NextSubTest();
236 	{
237 		const char *pathName = "/boot";
238 		const char *leafName = "home/..";
239 		const char *absolutePathName = "/boot";
240 		BPath path(pathName, leafName);
241 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
242 		CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
243 	}
244 	// absolute non-existing path, leaf, auto normalization
245 	NextSubTest();
246 	{
247 		const char *pathName = "/doesn't/exist";
248 		const char *leafName = "but//who/cares";
249 		BPath path(pathName, leafName);
250 		CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
251 		CPPUNIT_ASSERT( path.Path() == NULL );
252 	}
253 	// absolute non-existing path, leaf, normalization forced
254 	NextSubTest();
255 	{
256 		const char *pathName = "/doesn't/exist";
257 		const char *leafName = "but/who/cares";
258 		BPath path(pathName, leafName, true);
259 		CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
260 		CPPUNIT_ASSERT( path.Path() == NULL );
261 	}
262 	// relative existing path, leaf, no normalization needed, but done
263 	chdir("/");
264 	NextSubTest();
265 	{
266 		const char *pathName = "boot";
267 		const char *leafName = "home";
268 		const char *absolutePathName = "/boot/home";
269 		BPath path(pathName, leafName);
270 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
271 		CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
272 	}
273 	// relative non-existing path, leaf, no normalization needed, but done
274 	chdir("/boot");
275 	NextSubTest();
276 	{
277 		const char *pathName = "doesn't/exist";
278 		const char *leafName = "but/who/cares";
279 		BPath path(pathName, leafName);
280 		CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
281 		CPPUNIT_ASSERT( path.Path() == NULL );
282 	}
283 	// relative existing path, leaf, auto normalization
284 	chdir("/boot");
285 	NextSubTest();
286 	{
287 		const char *pathName = "home";
288 		const char *leafName = "Desktop//";
289 		const char *normalizedPathName = "/boot/home/Desktop";
290 		BPath path(pathName, leafName);
291 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
292 		CPPUNIT_ASSERT( string(normalizedPathName) == path.Path() );
293 	}
294 	// bad args (absolute lead)
295 	NextSubTest();
296 	{
297 		const char *pathName = "/";
298 		const char *leafName = "/boot";
299 		BPath path(pathName, leafName);
300 		CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
301 		CPPUNIT_ASSERT( path.Path() == NULL );
302 	}
303 	// bad args
304 	NextSubTest();
305 	{
306 		BPath path((const char*)NULL, "test");
307 		CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
308 		CPPUNIT_ASSERT( path.Path() == NULL );
309 	}
310 	// bad args
311 	NextSubTest();
312 	{
313 		BPath path((const char*)NULL);
314 		CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
315 		CPPUNIT_ASSERT( path.Path() == NULL );
316 	}
317 
318 	// 3. BPath(const BDirectory*, const char*, bool)
319 	// existing dir (root dir), no leaf, no normalization
320 	NextSubTest();
321 	{
322 		const char *pathName = "/";
323 		BDirectory dir(pathName);
324 		BPath path(&dir, NULL);
325 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
326 		CPPUNIT_ASSERT( string(pathName) == path.Path() );
327 	}
328 	// existing dir, no leaf, no normalization
329 	NextSubTest();
330 	{
331 		const char *pathName = "/boot";
332 		BDirectory dir(pathName);
333 		BPath path(&dir, NULL);
334 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
335 		CPPUNIT_ASSERT( string(pathName) == path.Path() );
336 	}
337 	// existing dir (root dir), no leaf, normalization forced
338 	NextSubTest();
339 	{
340 		const char *pathName = "/";
341 		BDirectory dir(pathName);
342 		BPath path(&dir, NULL, true);
343 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
344 		CPPUNIT_ASSERT( string(pathName) == path.Path() );
345 	}
346 	// existing dir, no leaf, normalization forced
347 	NextSubTest();
348 	{
349 		const char *pathName = "/boot";
350 		BDirectory dir(pathName);
351 		BPath path(&dir, NULL, true);
352 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
353 		CPPUNIT_ASSERT( string(pathName) == path.Path() );
354 	}
355 	// existing dir (root dir), leaf, no normalization
356 	NextSubTest();
357 	{
358 		const char *pathName = "/";
359 		const char *leafName = "boot";
360 		const char *absolutePathName = "/boot";
361 		BDirectory dir(pathName);
362 		BPath path(&dir, leafName);
363 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
364 		CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
365 	}
366 	// existing dir, leaf, no normalization
367 	NextSubTest();
368 	{
369 		const char *pathName = "/boot";
370 		const char *leafName = "home/Desktop";
371 		const char *absolutePathName = "/boot/home/Desktop";
372 		BDirectory dir(pathName);
373 		BPath path(&dir, leafName);
374 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
375 		CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
376 	}
377 	// existing dir, leaf, auto normalization
378 	NextSubTest();
379 	{
380 		const char *pathName = "/boot";
381 		const char *leafName = "home/..";
382 		const char *absolutePathName = "/boot";
383 		BDirectory dir(pathName);
384 		BPath path(&dir, leafName);
385 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
386 		CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
387 	}
388 	// bad args (absolute leaf)
389 	NextSubTest();
390 	{
391 		const char *pathName = "/";
392 		const char *leafName = "/boot";
393 		BDirectory dir(pathName);
394 		BPath path(&dir, leafName);
395 		CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
396 		CPPUNIT_ASSERT( path.Path() == NULL );
397 	}
398 	// bad args (uninitialized dir)
399 	NextSubTest();
400 	{
401 		BDirectory dir;
402 		BPath path(&dir, "test");
403 		CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
404 		CPPUNIT_ASSERT( path.Path() == NULL );
405 	}
406 	// bad args (badly initialized dir)
407 	NextSubTest();
408 	{
409 		BDirectory dir("/this/dir/doesn't/exists");
410 		BPath path(&dir, "test");
411 		CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
412 		CPPUNIT_ASSERT( path.Path() == NULL );
413 	}
414 	// bad args (NULL dir)
415 // R5: crashs, when passing a NULL BDirectory
416 #if !TEST_R5
417 	NextSubTest();
418 	{
419 		BPath path((const BDirectory*)NULL, "test");
420 		CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
421 		CPPUNIT_ASSERT( path.Path() == NULL );
422 	}
423 	// bad args (NULL dir)
424 	NextSubTest();
425 	{
426 		BPath path((const BDirectory*)NULL, NULL);
427 		CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
428 		CPPUNIT_ASSERT( path.Path() == NULL );
429 	}
430 #endif
431 
432 	// 4. BPath(const BEntry*)
433 	// existing entry (root dir)
434 	NextSubTest();
435 	{
436 		const char *pathName = "/";
437 		BEntry entry(pathName);
438 		BPath path(&entry);
439 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
440 		CPPUNIT_ASSERT( string(pathName) == path.Path() );
441 	}
442 	// existing entry
443 	NextSubTest();
444 	{
445 		const char *pathName = "/boot";
446 		BEntry entry(pathName);
447 		BPath path(&entry);
448 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
449 		CPPUNIT_ASSERT( string(pathName) == path.Path() );
450 	}
451 	// abstract entry
452 	NextSubTest();
453 	{
454 		const char *pathName = "/boot/shouldn't exist";
455 		BEntry entry(pathName);
456 		BPath path(&entry);
457 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
458 		CPPUNIT_ASSERT( string(pathName) == path.Path() );
459 	}
460 	// bad args (uninitialized BEntry)
461 	NextSubTest();
462 	{
463 		BEntry entry;
464 		BPath path(&entry);
465 		CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
466 		CPPUNIT_ASSERT( path.Path() == NULL );
467 	}
468 	// bad args (badly initialized BEntry)
469 	NextSubTest();
470 	{
471 		BEntry entry("/this/doesn't/exist");
472 		BPath path(&entry);
473 		CPPUNIT_ASSERT( equals(path.InitCheck(), B_NO_INIT, B_ENTRY_NOT_FOUND) );
474 		CPPUNIT_ASSERT( path.Path() == NULL );
475 	}
476 	// bad args (NULL BEntry)
477 	NextSubTest();
478 	{
479 		BPath path((const BEntry*)NULL);
480 		CPPUNIT_ASSERT( equals(path.InitCheck(), B_NO_INIT, B_BAD_VALUE) );
481 		CPPUNIT_ASSERT( path.Path() == NULL );
482 	}
483 
484 	// 5. BPath(const entry_ref*)
485 	// existing entry (root dir)
486 	NextSubTest();
487 	{
488 		const char *pathName = "/";
489 		BEntry entry(pathName);
490 		entry_ref ref;
491 		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
492 		BPath path(&ref);
493 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
494 		CPPUNIT_ASSERT( string(pathName) == path.Path() );
495 	}
496 	// existing entry
497 	NextSubTest();
498 	{
499 		const char *pathName = "/boot";
500 		BEntry entry(pathName);
501 		entry_ref ref;
502 		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
503 		BPath path(&ref);
504 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
505 		CPPUNIT_ASSERT( string(pathName) == path.Path() );
506 	}
507 	// abstract entry
508 	NextSubTest();
509 	{
510 		const char *pathName = "/boot/shouldn't exist";
511 		BEntry entry(pathName);
512 		entry_ref ref;
513 		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
514 		BPath path(&ref);
515 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
516 		CPPUNIT_ASSERT( string(pathName) == path.Path() );
517 	}
518 	// bad args (NULL entry_ref)
519 	NextSubTest();
520 	{
521 		BPath path((const entry_ref*)NULL);
522 		CPPUNIT_ASSERT( equals(path.InitCheck(), B_NO_INIT, B_BAD_VALUE) );
523 		CPPUNIT_ASSERT( path.Path() == NULL );
524 	}
525 }
526 
527 // InitTest2
528 void
529 PathTest::InitTest2()
530 {
531 	BPath path;
532 	const char *pathName;
533 	const char *leafName;
534 	const char *absolutePathName;
535 	const char *normalizedPathName;
536 	BDirectory dir;
537 	BEntry entry;
538 	entry_ref ref;
539 
540 	// 2. SetTo(const char*, const char*, bool)
541 	// absolute existing path (root dir), no leaf, no normalization
542 	NextSubTest();
543 	pathName = "/";
544 	CPPUNIT_ASSERT( path.SetTo(pathName) == B_OK );
545 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
546 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
547 	path.Unset();
548 	// absolute existing path, no leaf, no normalization
549 	NextSubTest();
550 	pathName = "/boot";
551 	CPPUNIT_ASSERT( path.SetTo(pathName) == B_OK );
552 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
553 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
554 	path.Unset();
555 	// absolute non-existing path, no leaf, no normalization
556 	NextSubTest();
557 	pathName = "/doesn't/exist/but/who/cares";
558 	CPPUNIT_ASSERT( path.SetTo(pathName) == B_OK );
559 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
560 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
561 	path.Unset();
562 	// absolute existing path (root dir), no leaf, auto normalization
563 	NextSubTest();
564 	pathName = "/.///.";
565 	normalizedPathName = "/";
566 	CPPUNIT_ASSERT( path.SetTo(pathName) == B_OK );
567 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
568 	CPPUNIT_ASSERT( string(normalizedPathName) == path.Path() );
569 	path.Unset();
570 	// absolute existing path, no leaf, auto normalization
571 	NextSubTest();
572 	pathName = "/boot/";
573 	normalizedPathName = "/boot";
574 	CPPUNIT_ASSERT( path.SetTo(pathName) == B_OK );
575 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
576 	CPPUNIT_ASSERT( string(normalizedPathName) == path.Path() );
577 	path.Unset();
578 	// absolute non-existing path, no leaf, auto normalization
579 	NextSubTest();
580 	pathName = "/doesn't/exist/but///who/cares";
581 	CPPUNIT_ASSERT( path.SetTo(pathName) == B_ENTRY_NOT_FOUND );
582 	CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
583 	CPPUNIT_ASSERT( path.Path() == NULL );
584 	path.Unset();
585 	// absolute existing path (root dir), no leaf, normalization forced
586 	NextSubTest();
587 	pathName = "/";
588 	CPPUNIT_ASSERT( path.SetTo(pathName, NULL, true) == B_OK );
589 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
590 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
591 	path.Unset();
592 	// absolute existing path, no leaf, normalization forced
593 	NextSubTest();
594 	pathName = "/boot";
595 	CPPUNIT_ASSERT( path.SetTo(pathName, NULL, true) == B_OK );
596 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
597 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
598 	path.Unset();
599 	// absolute non-existing path, no leaf, normalization forced
600 	NextSubTest();
601 	pathName = "/doesn't/exist/but/who/cares";
602 	CPPUNIT_ASSERT( path.SetTo(pathName, NULL, true) == B_ENTRY_NOT_FOUND );
603 	CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
604 	CPPUNIT_ASSERT( path.Path() == NULL );
605 	path.Unset();
606 	// relative existing path, no leaf, no normalization needed, but done
607 	chdir("/");
608 	NextSubTest();
609 	pathName = "boot";
610 	absolutePathName = "/boot";
611 	CPPUNIT_ASSERT( path.SetTo(pathName) == B_OK );
612 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
613 	CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
614 	path.Unset();
615 	// relative non-existing path, no leaf, no normalization needed, but done
616 	chdir("/boot");
617 	NextSubTest();
618 	pathName = "doesn't/exist/but/who/cares";
619 	absolutePathName = "/boot/doesn't/exist/but/who/cares";
620 	CPPUNIT_ASSERT( path.SetTo(pathName) == B_ENTRY_NOT_FOUND );
621 	CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
622 	CPPUNIT_ASSERT( path.Path() == NULL );
623 	path.Unset();
624 	// relative existing path, no leaf, auto normalization
625 	chdir("/");
626 	NextSubTest();
627 	pathName = "boot/";
628 	normalizedPathName = "/boot";
629 	CPPUNIT_ASSERT( path.SetTo(pathName) == B_OK );
630 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
631 	CPPUNIT_ASSERT( string(normalizedPathName) == path.Path() );
632 	path.Unset();
633 	// relative non-existing path, no leaf, auto normalization
634 	chdir("/boot");
635 	NextSubTest();
636 	pathName = "doesn't/exist/but///who/cares";
637 	CPPUNIT_ASSERT( path.SetTo(pathName) == B_ENTRY_NOT_FOUND );
638 	CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
639 	CPPUNIT_ASSERT( path.Path() == NULL );
640 	path.Unset();
641 	// relative existing path, no leaf, normalization forced
642 	chdir("/");
643 	NextSubTest();
644 	pathName = "boot";
645 	absolutePathName = "/boot";
646 	CPPUNIT_ASSERT( path.SetTo(pathName, NULL, true) == B_OK );
647 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
648 	CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
649 	path.Unset();
650 	// relative non-existing path, no leaf, normalization forced
651 	chdir("/boot");
652 	NextSubTest();
653 	pathName = "doesn't/exist/but/who/cares";
654 	CPPUNIT_ASSERT( path.SetTo(pathName, NULL, true) == B_ENTRY_NOT_FOUND );
655 	CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
656 	CPPUNIT_ASSERT( path.Path() == NULL );
657 	path.Unset();
658 	// absolute existing path (root dir), leaf, no normalization
659 	NextSubTest();
660 	pathName = "/";
661 	leafName = "boot";
662 	absolutePathName = "/boot";
663 	CPPUNIT_ASSERT( path.SetTo(pathName, leafName) == B_OK );
664 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
665 	CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
666 	path.Unset();
667 	// absolute existing path, leaf, no normalization
668 	NextSubTest();
669 	pathName = "/boot";
670 	leafName = "home/Desktop";
671 	absolutePathName = "/boot/home/Desktop";
672 	CPPUNIT_ASSERT( path.SetTo(pathName, leafName) == B_OK );
673 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
674 	CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
675 	path.Unset();
676 	// absolute non-existing path, leaf, no normalization
677 	NextSubTest();
678 	pathName = "/doesn't/exist";
679 	leafName = "but/who/cares";
680 	absolutePathName = "/doesn't/exist/but/who/cares";
681 	CPPUNIT_ASSERT( path.SetTo(pathName, leafName) == B_OK );
682 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
683 	CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
684 	path.Unset();
685 	// absolute existing path (root dir), leaf, auto normalization
686 	NextSubTest();
687 	pathName = "/.///";
688 	leafName = ".";
689 	absolutePathName = "/";
690 	CPPUNIT_ASSERT( path.SetTo(pathName, leafName) == B_OK );
691 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
692 	CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
693 	path.Unset();
694 	// absolute existing path, leaf, auto normalization
695 	NextSubTest();
696 	pathName = "/boot";
697 	leafName = "home/..";
698 	absolutePathName = "/boot";
699 	CPPUNIT_ASSERT( path.SetTo(pathName, leafName) == B_OK );
700 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
701 	CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
702 	path.Unset();
703 	// absolute existing path, leaf, self assignment
704 	NextSubTest();
705 	pathName = "/boot/home";
706 	leafName = "home/Desktop";
707 	absolutePathName = "/boot/home/Desktop";
708 	CPPUNIT_ASSERT( path.SetTo(pathName) == B_OK );
709 	CPPUNIT_ASSERT( path.SetTo(path.Path(), ".///./") == B_OK );
710 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
711 	CPPUNIT_ASSERT( path.SetTo(path.Path(), "..") == B_OK );
712 	CPPUNIT_ASSERT( string("/boot") == path.Path() );
713 	CPPUNIT_ASSERT( path.SetTo(path.Path(), leafName) == B_OK );
714 	CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
715 	path.Unset();
716 	// absolute non-existing path, leaf, auto normalization
717 	NextSubTest();
718 	pathName = "/doesn't/exist";
719 	leafName = "but//who/cares";
720 	CPPUNIT_ASSERT( path.SetTo(pathName, leafName) == B_ENTRY_NOT_FOUND );
721 	CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
722 	CPPUNIT_ASSERT( path.Path() == NULL );
723 	path.Unset();
724 	// absolute non-existing path, leaf, normalization forced
725 	NextSubTest();
726 	pathName = "/doesn't/exist";
727 	leafName = "but/who/cares";
728 	CPPUNIT_ASSERT( path.SetTo(pathName, leafName, true) == B_ENTRY_NOT_FOUND );
729 	CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
730 	CPPUNIT_ASSERT( path.Path() == NULL );
731 	path.Unset();
732 	// relative existing path, leaf, no normalization needed, but done
733 	chdir("/");
734 	NextSubTest();
735 	pathName = "boot";
736 	leafName = "home";
737 	absolutePathName = "/boot/home";
738 	CPPUNIT_ASSERT( path.SetTo(pathName, leafName) == B_OK );
739 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
740 	CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
741 	path.Unset();
742 	// relative non-existing path, leaf, no normalization needed, but done
743 	chdir("/boot");
744 	NextSubTest();
745 	pathName = "doesn't/exist";
746 	leafName = "but/who/cares";
747 	CPPUNIT_ASSERT( path.SetTo(pathName, leafName) == B_ENTRY_NOT_FOUND );
748 	CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
749 	CPPUNIT_ASSERT( path.Path() == NULL );
750 	path.Unset();
751 	// relative existing path, leaf, auto normalization
752 	chdir("/boot");
753 	NextSubTest();
754 	pathName = "home";
755 	leafName = "Desktop//";
756 	normalizedPathName = "/boot/home/Desktop";
757 	CPPUNIT_ASSERT( path.SetTo(pathName, leafName) == B_OK );
758 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
759 	CPPUNIT_ASSERT( string(normalizedPathName) == path.Path() );
760 	path.Unset();
761 	// bad args (absolute leaf)
762 	NextSubTest();
763 	CPPUNIT_ASSERT( path.SetTo("/", "/boot") == B_BAD_VALUE );
764 	CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
765 	CPPUNIT_ASSERT( path.Path() == NULL );
766 	path.Unset();
767 	// bad args
768 	NextSubTest();
769 	CPPUNIT_ASSERT( path.SetTo((const char*)NULL, "test") == B_BAD_VALUE );
770 	CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
771 	CPPUNIT_ASSERT( path.Path() == NULL );
772 	path.Unset();
773 	// bad args
774 	NextSubTest();
775 	CPPUNIT_ASSERT( path.SetTo((const char*)NULL) == B_BAD_VALUE );
776 	CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
777 	CPPUNIT_ASSERT( path.Path() == NULL );
778 	path.Unset();
779 
780 	// 3. SetTo(const BDirectory*, const char*, bool)
781 	// existing dir (root dir), no leaf, no normalization
782 	NextSubTest();
783 	pathName = "/";
784 	CPPUNIT_ASSERT( dir.SetTo(pathName) == B_OK );
785 	CPPUNIT_ASSERT( path.SetTo(&dir, NULL) == B_OK );
786 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
787 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
788 	path.Unset();
789 	dir.Unset();
790 	// existing dir, no leaf, no normalization
791 	NextSubTest();
792 	pathName = "/boot";
793 	CPPUNIT_ASSERT( dir.SetTo(pathName) == B_OK );
794 	CPPUNIT_ASSERT( path.SetTo(&dir, NULL) == B_OK );
795 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
796 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
797 	path.Unset();
798 	dir.Unset();
799 	// existing dir (root dir), no leaf, normalization forced
800 	NextSubTest();
801 	pathName = "/";
802 	CPPUNIT_ASSERT( dir.SetTo(pathName) == B_OK );
803 	CPPUNIT_ASSERT( path.SetTo(&dir, NULL, true) == B_OK );
804 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
805 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
806 	path.Unset();
807 	dir.Unset();
808 	// existing dir, no leaf, normalization forced
809 	NextSubTest();
810 	pathName = "/boot";
811 	CPPUNIT_ASSERT( dir.SetTo(pathName) == B_OK );
812 	CPPUNIT_ASSERT( path.SetTo(&dir, NULL, true) == B_OK );
813 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
814 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
815 	path.Unset();
816 	dir.Unset();
817 	// existing dir (root dir), leaf, no normalization
818 	NextSubTest();
819 	pathName = "/";
820 	leafName = "boot";
821 	absolutePathName = "/boot";
822 	CPPUNIT_ASSERT( dir.SetTo(pathName) == B_OK );
823 	CPPUNIT_ASSERT( path.SetTo(&dir, leafName) == B_OK );
824 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
825 	CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
826 	path.Unset();
827 	dir.Unset();
828 	// existing dir, leaf, no normalization
829 	NextSubTest();
830 	pathName = "/boot";
831 	leafName = "home/Desktop";
832 	absolutePathName = "/boot/home/Desktop";
833 	CPPUNIT_ASSERT( dir.SetTo(pathName) == B_OK );
834 	CPPUNIT_ASSERT( path.SetTo(&dir, leafName) == B_OK );
835 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
836 	CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
837 	path.Unset();
838 	dir.Unset();
839 	// existing dir, leaf, auto normalization
840 	NextSubTest();
841 	pathName = "/boot";
842 	leafName = "home/..";
843 	absolutePathName = "/boot";
844 	CPPUNIT_ASSERT( dir.SetTo(pathName) == B_OK );
845 	CPPUNIT_ASSERT( path.SetTo(&dir, leafName) == B_OK );
846 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
847 	CPPUNIT_ASSERT( string(absolutePathName) == path.Path() );
848 	path.Unset();
849 	dir.Unset();
850 	// bad args (absolute leaf)
851 	NextSubTest();
852 	pathName = "/";
853 	leafName = "/boot";
854 	CPPUNIT_ASSERT( dir.SetTo(pathName) == B_OK );
855 	CPPUNIT_ASSERT( path.SetTo(&dir, leafName) == B_BAD_VALUE );
856 	CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
857 	CPPUNIT_ASSERT( path.Path() == NULL );
858 	path.Unset();
859 	dir.Unset();
860 	// bad args (uninitialized dir)
861 	NextSubTest();
862 	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
863 	CPPUNIT_ASSERT( path.SetTo(&dir, "test") == B_BAD_VALUE );
864 	CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
865 	CPPUNIT_ASSERT( path.Path() == NULL );
866 	path.Unset();
867 	dir.Unset();
868 	// bad args (badly initialized dir)
869 	NextSubTest();
870 	CPPUNIT_ASSERT( dir.SetTo("/this/dir/doesn't/exists") == B_ENTRY_NOT_FOUND );
871 	CPPUNIT_ASSERT( path.SetTo(&dir, "test") == B_BAD_VALUE );
872 	CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
873 	CPPUNIT_ASSERT( path.Path() == NULL );
874 	path.Unset();
875 	dir.Unset();
876 // R5: crashs, when passing a NULL BDirectory
877 #if !TEST_R5
878 	// bad args (NULL dir)
879 	NextSubTest();
880 	CPPUNIT_ASSERT( path.SetTo((const BDirectory*)NULL, "test") == B_BAD_VALUE );
881 	CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
882 	CPPUNIT_ASSERT( path.Path() == NULL );
883 	path.Unset();
884 	dir.Unset();
885 	// bad args (NULL dir)
886 	NextSubTest();
887 	CPPUNIT_ASSERT( path.SetTo((const BDirectory*)NULL, NULL) == B_BAD_VALUE );
888 	CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
889 	CPPUNIT_ASSERT( path.Path() == NULL );
890 	path.Unset();
891 	dir.Unset();
892 #endif
893 
894 	// 4. SetTo(const BEntry*)
895 	// existing entry (root dir)
896 	NextSubTest();
897 	pathName = "/";
898 	CPPUNIT_ASSERT( entry.SetTo(pathName) == B_OK );
899 	CPPUNIT_ASSERT( path.SetTo(&entry) == B_OK );
900 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
901 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
902 	path.Unset();
903 	entry.Unset();
904 	// existing entry
905 	NextSubTest();
906 	pathName = "/boot";
907 	CPPUNIT_ASSERT( entry.SetTo(pathName) == B_OK );
908 	CPPUNIT_ASSERT( path.SetTo(&entry) == B_OK );
909 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
910 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
911 	path.Unset();
912 	entry.Unset();
913 	// abstract entry
914 	NextSubTest();
915 	pathName = "/boot/shouldn't exist";
916 	CPPUNIT_ASSERT( entry.SetTo(pathName) == B_OK );
917 	CPPUNIT_ASSERT( path.SetTo(&entry) == B_OK );
918 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
919 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
920 	path.Unset();
921 	entry.Unset();
922 	// bad args (uninitialized BEntry)
923 	NextSubTest();
924 	CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
925 	CPPUNIT_ASSERT( path.SetTo(&entry) == B_NO_INIT );
926 	CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
927 	CPPUNIT_ASSERT( path.Path() == NULL );
928 	path.Unset();
929 	entry.Unset();
930 	// bad args (badly initialized BEntry)
931 	NextSubTest();
932 	CPPUNIT_ASSERT( entry.SetTo("/this/doesn't/exist") == B_ENTRY_NOT_FOUND );
933 	CPPUNIT_ASSERT( equals(path.SetTo(&entry), B_NO_INIT, B_ENTRY_NOT_FOUND) );
934 	CPPUNIT_ASSERT( equals(path.InitCheck(), B_NO_INIT, B_ENTRY_NOT_FOUND) );
935 	CPPUNIT_ASSERT( path.Path() == NULL );
936 	path.Unset();
937 	entry.Unset();
938 	// bad args (NULL BEntry)
939 	NextSubTest();
940 	CPPUNIT_ASSERT( equals(path.SetTo((const BEntry*)NULL), B_NO_INIT,
941 									  B_BAD_VALUE) );
942 	CPPUNIT_ASSERT( equals(path.InitCheck(), B_NO_INIT, B_BAD_VALUE) );
943 	CPPUNIT_ASSERT( path.Path() == NULL );
944 	path.Unset();
945 	entry.Unset();
946 
947 	// 5. SetTo(const entry_ref*)
948 	// existing entry (root dir)
949 	NextSubTest();
950 	pathName = "/";
951 	CPPUNIT_ASSERT( entry.SetTo(pathName) == B_OK );
952 	CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
953 	CPPUNIT_ASSERT( path.SetTo(&ref) == B_OK );
954 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
955 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
956 	path.Unset();
957 	entry.Unset();
958 	// existing entry
959 	NextSubTest();
960 	pathName = "/boot";
961 	CPPUNIT_ASSERT( entry.SetTo(pathName) == B_OK );
962 	CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
963 	CPPUNIT_ASSERT( path.SetTo(&ref) == B_OK );
964 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
965 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
966 	path.Unset();
967 	entry.Unset();
968 	// abstract entry
969 	NextSubTest();
970 	pathName = "/boot/shouldn't exist";
971 	CPPUNIT_ASSERT( entry.SetTo(pathName) == B_OK );
972 	CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
973 	CPPUNIT_ASSERT( path.SetTo(&ref) == B_OK );
974 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
975 	CPPUNIT_ASSERT( string(pathName) == path.Path() );
976 	path.Unset();
977 	entry.Unset();
978 	// bad args (NULL entry_ref)
979 	NextSubTest();
980 	CPPUNIT_ASSERT( equals(path.SetTo((const entry_ref*)NULL), B_NO_INIT,
981 						   B_BAD_VALUE) );
982 	CPPUNIT_ASSERT( equals(path.InitCheck(), B_NO_INIT, B_BAD_VALUE) );
983 	CPPUNIT_ASSERT( path.Path() == NULL );
984 	path.Unset();
985 	entry.Unset();
986 }
987 
988 // AppendTest
989 void
990 PathTest::AppendTest()
991 {
992 	BPath path;
993 	// uninitialized BPath
994 	NextSubTest();
995 	CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
996 	CPPUNIT_ASSERT( path.Append("test") == B_BAD_VALUE );
997 	CPPUNIT_ASSERT( path.Path() == NULL );
998 	path.Unset();
999 	// dir hierarchy, from existing to non-existing
1000 	NextSubTest();
1001 	CPPUNIT_ASSERT( path.SetTo("/") == B_OK );
1002 	CPPUNIT_ASSERT( string("/") == path.Path() );
1003 	CPPUNIT_ASSERT( path.Append("boot") == B_OK );
1004 	CPPUNIT_ASSERT( string("/boot") == path.Path() );
1005 	CPPUNIT_ASSERT( path.Append("home/Desktop") == B_OK );
1006 	CPPUNIT_ASSERT( string("/boot/home/Desktop") == path.Path() );
1007 	CPPUNIT_ASSERT( path.Append("non/existing") == B_OK );
1008 	CPPUNIT_ASSERT( string("/boot/home/Desktop/non/existing") == path.Path() );
1009 	// trigger normalization
1010 	CPPUNIT_ASSERT( path.Append("at/least/not//now") == B_ENTRY_NOT_FOUND );
1011 	CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
1012 	CPPUNIT_ASSERT( path.Path() == NULL );
1013 	path.Unset();
1014 	// force normalization
1015 	NextSubTest();
1016 	CPPUNIT_ASSERT( path.SetTo("/boot") == B_OK );
1017 	CPPUNIT_ASSERT( string("/boot") == path.Path() );
1018 	CPPUNIT_ASSERT( path.Append("home/non-existing", true) == B_OK );
1019 	CPPUNIT_ASSERT( string("/boot/home/non-existing") == path.Path() );
1020 	CPPUNIT_ASSERT( path.Append("not/now", true) == B_ENTRY_NOT_FOUND );
1021 	CPPUNIT_ASSERT( path.InitCheck() == B_ENTRY_NOT_FOUND );
1022 	CPPUNIT_ASSERT( path.Path() == NULL );
1023 	path.Unset();
1024 	// bad/strange args
1025 	NextSubTest();
1026 	CPPUNIT_ASSERT( path.SetTo("/boot") == B_OK );
1027 	CPPUNIT_ASSERT( path.Append(NULL) == B_OK );
1028 	CPPUNIT_ASSERT( string("/boot") == path.Path() );
1029 	CPPUNIT_ASSERT( path.SetTo("/boot") == B_OK );
1030 	CPPUNIT_ASSERT( path.Append("/tmp") == B_BAD_VALUE );
1031 	CPPUNIT_ASSERT( path.InitCheck() == B_BAD_VALUE );
1032 	CPPUNIT_ASSERT( path.SetTo("/boot") == B_OK );
1033 	CPPUNIT_ASSERT( path.Append("") == B_OK );
1034 	CPPUNIT_ASSERT( string("/boot") == path.Path() );
1035 	path.Unset();
1036 }
1037 
1038 // LeafTest
1039 void
1040 PathTest::LeafTest()
1041 {
1042 	BPath path;
1043 	// uninitialized BPath
1044 	NextSubTest();
1045 	CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
1046 	CPPUNIT_ASSERT( path.Leaf() == NULL );
1047 	path.Unset();
1048 	// root dir
1049 	NextSubTest();
1050 	CPPUNIT_ASSERT( path.SetTo("/") == B_OK );
1051 	CPPUNIT_ASSERT( string("") == path.Leaf() );
1052 	path.Unset();
1053 	// existing dirs
1054 	NextSubTest();
1055 	CPPUNIT_ASSERT( path.SetTo("/boot") == B_OK );
1056 	CPPUNIT_ASSERT( string("boot") == path.Leaf() );
1057 	CPPUNIT_ASSERT( path.SetTo("/boot/home") == B_OK );
1058 	CPPUNIT_ASSERT( string("home") == path.Leaf() );
1059 	CPPUNIT_ASSERT( path.SetTo("/boot/home/Desktop") == B_OK );
1060 	CPPUNIT_ASSERT( string("Desktop") == path.Leaf() );
1061 	path.Unset();
1062 	// non-existing dirs
1063 	NextSubTest();
1064 	CPPUNIT_ASSERT( path.SetTo("/non-existing") == B_OK );
1065 	CPPUNIT_ASSERT( string("non-existing") == path.Leaf() );
1066 	CPPUNIT_ASSERT( path.SetTo("/non/existing/dir") == B_OK );
1067 	CPPUNIT_ASSERT( string("dir") == path.Leaf() );
1068 	path.Unset();
1069 }
1070 
1071 // ParentTest
1072 void
1073 PathTest::ParentTest()
1074 {
1075 	BPath path;
1076 	BPath parent;
1077 // R5: crashs, when GetParent() is called on uninitialized BPath
1078 #if !TEST_R5
1079 	// uninitialized BPath
1080 	NextSubTest();
1081 	CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
1082 	CPPUNIT_ASSERT( path.GetParent(&parent) == B_NO_INIT );
1083 	path.Unset();
1084 	parent.Unset();
1085 #endif
1086 	// root dir
1087 	NextSubTest();
1088 	CPPUNIT_ASSERT( path.SetTo("/") == B_OK );
1089 	CPPUNIT_ASSERT( path.GetParent(&parent) == B_ENTRY_NOT_FOUND );
1090 	path.Unset();
1091 	parent.Unset();
1092 	// existing dirs
1093 	NextSubTest();
1094 	CPPUNIT_ASSERT( path.SetTo("/boot") == B_OK );
1095 	CPPUNIT_ASSERT( path.GetParent(&parent) == B_OK );
1096 	CPPUNIT_ASSERT( string("/") == parent.Path() );
1097 	CPPUNIT_ASSERT( path.SetTo("/boot/home") == B_OK );
1098 	CPPUNIT_ASSERT( path.GetParent(&parent) == B_OK );
1099 	CPPUNIT_ASSERT( string("/boot") == parent.Path() );
1100 	CPPUNIT_ASSERT( path.SetTo("/boot/home/Desktop") == B_OK );
1101 	CPPUNIT_ASSERT( path.GetParent(&parent) == B_OK );
1102 	CPPUNIT_ASSERT( string("/boot/home") == parent.Path() );
1103 	path.Unset();
1104 	parent.Unset();
1105 	// non-existing dirs
1106 	NextSubTest();
1107 	CPPUNIT_ASSERT( path.SetTo("/non-existing") == B_OK );
1108 	CPPUNIT_ASSERT( path.GetParent(&parent) == B_OK );
1109 	CPPUNIT_ASSERT( string("/") == parent.Path() );
1110 	CPPUNIT_ASSERT( path.SetTo("/non/existing/dir") == B_OK );
1111 	CPPUNIT_ASSERT( path.GetParent(&parent) == B_OK );
1112 	CPPUNIT_ASSERT( string("/non/existing") == parent.Path() );
1113 	path.Unset();
1114 	parent.Unset();
1115 	// destructive parenting
1116 	NextSubTest();
1117 	CPPUNIT_ASSERT( path.SetTo("/non/existing/dir") == B_OK );
1118 	CPPUNIT_ASSERT( path.GetParent(&path) == B_OK );
1119 	CPPUNIT_ASSERT( string("/non/existing") == path.Path() );
1120 	CPPUNIT_ASSERT( path.GetParent(&path) == B_OK );
1121 	CPPUNIT_ASSERT( string("/non") == path.Path() );
1122 	CPPUNIT_ASSERT( path.GetParent(&path) == B_OK );
1123 	CPPUNIT_ASSERT( string("/") == path.Path() );
1124 	CPPUNIT_ASSERT( path.GetParent(&path) == B_ENTRY_NOT_FOUND );
1125 	path.Unset();
1126 	parent.Unset();
1127 // R5: crashs, when passing a NULL BPath
1128 #if !TEST_R5
1129 	// bad args
1130 	NextSubTest();
1131 	CPPUNIT_ASSERT( path.SetTo("/non/existing/dir") == B_OK );
1132 	CPPUNIT_ASSERT( path.GetParent(NULL) == B_BAD_VALUE );
1133 	path.Unset();
1134 	parent.Unset();
1135 #endif
1136 }
1137 
1138 // ComparisonTest
1139 void
1140 PathTest::ComparisonTest()
1141 {
1142 	BPath path;
1143 	// 1. ==/!= const BPath &
1144 	BPath path2;
1145 	// uninitialized BPaths
1146 // R5: uninitialized paths are unequal
1147 	NextSubTest();
1148 	CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
1149 	CPPUNIT_ASSERT( path2.InitCheck() == B_NO_INIT );
1150 #if !TEST_R5
1151 	CPPUNIT_ASSERT( (path == path2) == true );
1152 	CPPUNIT_ASSERT( (path != path2) == false );
1153 #endif
1154 	path.Unset();
1155 	path2.Unset();
1156 	// uninitialized argument BPath
1157 	NextSubTest();
1158 	CPPUNIT_ASSERT( path.SetTo("/") == B_OK );
1159 	CPPUNIT_ASSERT( path2.InitCheck() == B_NO_INIT );
1160 	CPPUNIT_ASSERT( (path == path2) == false );
1161 	CPPUNIT_ASSERT( (path != path2) == true );
1162 	path.Unset();
1163 	path2.Unset();
1164 	// uninitialized this BPath
1165 	NextSubTest();
1166 	CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
1167 	CPPUNIT_ASSERT( path2.SetTo("/") == B_OK );
1168 	CPPUNIT_ASSERT( (path == path2) == false );
1169 	CPPUNIT_ASSERT( (path != path2) == true );
1170 	path.Unset();
1171 	path2.Unset();
1172 	// various paths
1173 	NextSubTest();
1174 	const char *paths[] = { "/", "/boot", "/boot/home", "/boot/home/Desktop" };
1175 	int32 pathCount = sizeof(paths) / sizeof(const char*);
1176 	for (int32 i = 0; i < pathCount; i++) {
1177 		for (int32 k = 0; k < pathCount; k++) {
1178 			CPPUNIT_ASSERT( path.SetTo(paths[i]) == B_OK );
1179 			CPPUNIT_ASSERT( path2.SetTo(paths[k]) == B_OK );
1180 			CPPUNIT_ASSERT( (path == path2) == (i == k) );
1181 			CPPUNIT_ASSERT( (path != path2) == (i != k) );
1182 		}
1183 	}
1184 	path.Unset();
1185 	path2.Unset();
1186 
1187 	// 2. ==/!= const char *
1188 	const char *pathName;
1189 	// uninitialized BPath
1190 	NextSubTest();
1191 	CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
1192 	pathName = "/";
1193 	CPPUNIT_ASSERT( (path == pathName) == false );
1194 	CPPUNIT_ASSERT( (path != pathName) == true );
1195 	path.Unset();
1196 	// various paths
1197 	NextSubTest();
1198 	for (int32 i = 0; i < pathCount; i++) {
1199 		for (int32 k = 0; k < pathCount; k++) {
1200 			CPPUNIT_ASSERT( path.SetTo(paths[i]) == B_OK );
1201 			pathName = paths[k];
1202 			CPPUNIT_ASSERT( (path == pathName) == (i == k) );
1203 			CPPUNIT_ASSERT( (path != pathName) == (i != k) );
1204 		}
1205 	}
1206 	path.Unset();
1207 	// bad args (NULL const char*)
1208 // R5: initialized path equals NULL argument!
1209 // R5: uninitialized path does not equal NULL argument!
1210 	NextSubTest();
1211 	CPPUNIT_ASSERT( path.SetTo("/") == B_OK );
1212 	pathName = NULL;
1213 #if !TEST_R5
1214 	CPPUNIT_ASSERT( (path == pathName) == false );
1215 	CPPUNIT_ASSERT( (path != pathName) == true );
1216 #endif
1217 	path.Unset();
1218 	CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
1219 #if !TEST_R5
1220 	CPPUNIT_ASSERT( (path == pathName) == true );
1221 	CPPUNIT_ASSERT( (path != pathName) == false );
1222 #endif
1223 	path.Unset();
1224 }
1225 
1226 // AssignmentTest
1227 void
1228 PathTest::AssignmentTest()
1229 {
1230 	// 1. copy constructor
1231 	// uninitialized
1232 	NextSubTest();
1233 	{
1234 		BPath path;
1235 		CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
1236 		BPath path2(path);
1237 		CPPUNIT_ASSERT( path2.InitCheck() == B_NO_INIT );
1238 	}
1239 	// initialized
1240 	NextSubTest();
1241 	{
1242 		BPath path("/boot/home/Desktop");
1243 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
1244 		BPath path2(path);
1245 		CPPUNIT_ASSERT( path2.InitCheck() == B_OK );
1246 		CPPUNIT_ASSERT( path == path2 );
1247 	}
1248 
1249 	// 2. assignment operator, const BPath &
1250 	// uninitialized
1251 	NextSubTest();
1252 	{
1253 		BPath path;
1254 		BPath path2;
1255 		path2 = path;
1256 		CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
1257 		CPPUNIT_ASSERT( path2.InitCheck() == B_NO_INIT );
1258 	}
1259 	NextSubTest();
1260 	{
1261 		BPath path;
1262 		BPath path2("/");
1263 		CPPUNIT_ASSERT( path2.InitCheck() == B_OK );
1264 		path2 = path;
1265 		CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
1266 		CPPUNIT_ASSERT( path2.InitCheck() == B_NO_INIT );
1267 	}
1268 	// initialized
1269 	NextSubTest();
1270 	{
1271 		BPath path("/boot/home");
1272 		CPPUNIT_ASSERT( path.InitCheck() == B_OK );
1273 		BPath path2;
1274 		path2 = path;
1275 		CPPUNIT_ASSERT( path2.InitCheck() == B_OK );
1276 		CPPUNIT_ASSERT( path == path2 );
1277 	}
1278 
1279 	// 2. assignment operator, const char *
1280 	// initialized
1281 	NextSubTest();
1282 	{
1283 		const char *pathName = "/boot/home";
1284 		BPath path2;
1285 		path2 = pathName;
1286 		CPPUNIT_ASSERT( path2.InitCheck() == B_OK );
1287 		CPPUNIT_ASSERT( path2 == pathName );
1288 	}
1289 	// bad args
1290 	NextSubTest();
1291 	{
1292 		const char *pathName = NULL;
1293 		BPath path2;
1294 		path2 = pathName;
1295 		CPPUNIT_ASSERT( path2.InitCheck() == B_NO_INIT );
1296 	}
1297 }
1298 
1299 // FlattenableTest
1300 void
1301 PathTest::FlattenableTest()
1302 {
1303 	BPath path;
1304 	// 1. trivial methods (IsFixedSize(), TypeCode(), AllowsTypeCode)
1305 	// uninitialized
1306 	NextSubTest();
1307 	CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
1308 	CPPUNIT_ASSERT( path.IsFixedSize() == false );
1309 	CPPUNIT_ASSERT( path.TypeCode() == B_REF_TYPE );
1310 	CPPUNIT_ASSERT( path.AllowsTypeCode(B_REF_TYPE) == true );
1311 	CPPUNIT_ASSERT( path.AllowsTypeCode(B_STRING_TYPE) == false );
1312 	CPPUNIT_ASSERT( path.AllowsTypeCode(B_FLOAT_TYPE) == false );
1313 	path.Unset();
1314 	// initialized
1315 	NextSubTest();
1316 	CPPUNIT_ASSERT( path.SetTo("/boot/home") == B_OK );
1317 	CPPUNIT_ASSERT( path.IsFixedSize() == false );
1318 	CPPUNIT_ASSERT( path.TypeCode() == B_REF_TYPE );
1319 	CPPUNIT_ASSERT( path.AllowsTypeCode(B_REF_TYPE) == true );
1320 	CPPUNIT_ASSERT( path.AllowsTypeCode(B_STRING_TYPE) == false );
1321 	CPPUNIT_ASSERT( path.AllowsTypeCode(B_FLOAT_TYPE) == false );
1322 	path.Unset();
1323 
1324 	// 2. non-trivial methods
1325 	char buffer[1024];
1326 	// uninitialized
1327 	NextSubTest();
1328 	CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
1329 	ssize_t size = path.FlattenedSize();
1330 	CPPUNIT_ASSERT( size == sizeof(dev_t) + sizeof(ino_t) );
1331 	CPPUNIT_ASSERT( path.Flatten(buffer, sizeof(buffer)) == B_OK );
1332 	CPPUNIT_ASSERT( path.Unflatten(B_REF_TYPE, buffer, size) == B_OK );
1333 	CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
1334 	path.Unset();
1335 	// some flatten/unflatten tests
1336 	NextSubTest();
1337 	const char *paths[] = { "/", "/boot", "/boot/home", "/boot/home/Desktop",
1338 							"/boot/home/non-existing" };
1339 	int32 pathCount = sizeof(paths) / sizeof(const char*);
1340 	for (int32 i = 0; i < pathCount; i++) {
1341 		const char *pathName = paths[i];
1342 		// init the path and get an equivalent entry ref
1343 		CPPUNIT_ASSERT( path.SetTo(pathName) == B_OK );
1344 		BEntry entry;
1345 		CPPUNIT_ASSERT( entry.SetTo(pathName) == B_OK );
1346 		entry_ref ref;
1347 		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
1348 		// flatten the path
1349 		struct flattened_ref { dev_t device; ino_t directory; char name[1]; };
1350 		size = path.FlattenedSize();
1351 		int32 expectedSize	// hehe, that's hacky ;-)
1352 			= (int32)((flattened_ref*)NULL)->name + strlen(ref.name) + 1;
1353 		CPPUNIT_ASSERT( size ==  expectedSize);
1354 		CPPUNIT_ASSERT( path.Flatten(buffer, sizeof(buffer)) == B_OK );
1355 		// check the flattened data
1356 		const flattened_ref &fref = *(flattened_ref*)buffer;
1357 		CPPUNIT_ASSERT( ref.device == fref.device );
1358 		CPPUNIT_ASSERT( ref.directory == fref.directory );
1359 		CPPUNIT_ASSERT( strcmp(ref.name, fref.name) == 0 );
1360 		// unflatten the path
1361 		path.Unset();
1362 		CPPUNIT_ASSERT( path.InitCheck() == B_NO_INIT );
1363 		CPPUNIT_ASSERT( path.Unflatten(B_REF_TYPE, buffer, size) == B_OK );
1364 		CPPUNIT_ASSERT( path == pathName );
1365 		path.Unset();
1366 	}
1367 	// bad args
1368 	NextSubTest();
1369 // R5: crashs, when passing a NULL buffer
1370 // R5: doesn't check the buffer size
1371 	CPPUNIT_ASSERT( path.SetTo("/boot/home") == B_OK );
1372 #if !TEST_R5
1373 	CPPUNIT_ASSERT( path.Flatten(NULL, sizeof(buffer)) == B_BAD_VALUE );
1374 	CPPUNIT_ASSERT( path.Flatten(buffer, path.FlattenedSize() - 2)
1375 					== B_BAD_VALUE );
1376 #endif
1377 	path.Unset();
1378 }
1379 
1380