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>
16using std::string;
17
18
19// Suite
20CppUnit::Test*
21PathTest::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
41void
42PathTest::setUp()
43{
44	BasicTest::setUp();
45}
46
47// tearDown
48void
49PathTest::tearDown()
50{
51	BasicTest::tearDown();
52}
53
54// InitTest1
55void
56PathTest::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
532void
533PathTest::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
993void
994PathTest::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
1043void
1044PathTest::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
1076void
1077PathTest::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
1143void
1144PathTest::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
1231void
1232PathTest::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
1304void
1305PathTest::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
1356			= sizeof(dev_t) + sizeof(ino_t) + 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