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