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
16CppUnit::Test*
17PathTest::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
37void
38PathTest::setUp()
39{
40	BasicTest::setUp();
41}
42
43// tearDown
44void
45PathTest::tearDown()
46{
47	BasicTest::tearDown();
48}
49
50// InitTest1
51void
52PathTest::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
528void
529PathTest::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
989void
990PathTest::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
1039void
1040PathTest::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
1072void
1073PathTest::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
1139void
1140PathTest::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
1227void
1228PathTest::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
1300void
1301PathTest::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