1 // NodeInfoTest.cpp
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <unistd.h>
6
7 #include <string>
8 using std::string;
9
10 #include <Application.h>
11 #include <Bitmap.h>
12 #include <Directory.h>
13 #include <Entry.h>
14 #include <fs_attr.h>
15 #include <Node.h>
16 #include <NodeInfo.h>
17 #include <Path.h>
18 #include <TypeConstants.h>
19 #include <MimeTypes.h>
20
21 #include <cppunit/Test.h>
22 #include <cppunit/TestCaller.h>
23 #include <cppunit/TestSuite.h>
24 #include <TestShell.h>
25 #include <TestUtils.h>
26 #include <cppunit/TestAssert.h>
27
28 #include "NodeInfoTest.h"
29 #include "../app/bmessenger/Helpers.h"
30
31 // test dirs/files/types
32 static const char *testDir = "/tmp/testDir";
33 static const char *testFile1 = "/tmp/testDir/file1";
34 static const char *testFile2 = "/tmp/testDir/file2";
35 static const char *testFile3 = "/tmp/testDir/file3";
36 static const char *testFile4 = "/tmp/testDir/file4";
37 static const char *abstractTestEntry = "/tmp/testDir/abstract-entry";
38 static const char *testType1 = "application/x-vnd.obos.node-info-test1";
39 static const char *testType2 = "application/x-vnd.obos.node-info-test2";
40 static const char *invalidTestType = "invalid-mime-type";
41 static const char *tooLongTestType =
42 "0123456789012345678901234567890123456789012345678901234567890123456789"
43 "0123456789012345678901234567890123456789012345678901234567890123456789"
44 "0123456789012345678901234567890123456789012345678901234567890123456789"
45 "0123456789012345678901234567890123456789012345678901234567890123456789"
46 ;
47 static const char *testAppSignature1
48 = "application/x-vnd.obos.node-info-test-app1";
49 static const char *testAppSignature2
50 = "application/x-vnd.obos.node-info-test-app2";
51
52
53 // attributes
54 static const char *kTypeAttribute = "BEOS:TYPE";
55 static const char *kMiniIconAttribute = "BEOS:M:STD_ICON";
56 static const char *kLargeIconAttribute = "BEOS:L:STD_ICON";
57 static const char *kPreferredAppAttribute = "BEOS:PREF_APP";
58 static const char *kAppHintAttribute = "BEOS:PPATH";
59
60 enum {
61 MINI_ICON_TYPE = 'MICN',
62 LARGE_ICON_TYPE = 'ICON',
63 };
64
65 // create_test_icon
66 static
67 BBitmap *
create_test_icon(icon_size size,int fill)68 create_test_icon(icon_size size, int fill)
69 {
70 BBitmap *icon = NULL;
71 // create
72 switch (size) {
73 case B_MINI_ICON:
74 icon = new BBitmap(BRect(0, 0, 15, 15), B_CMAP8);
75 break;
76 case B_LARGE_ICON:
77 icon = new BBitmap(BRect(0, 0, 31, 31), B_CMAP8);
78 break;
79 }
80 // fill
81 if (icon)
82 memset(icon->Bits(), fill, icon->BitsLength());
83 return icon;
84 }
85
86 // icon_equal
87 static
88 bool
icon_equal(const BBitmap * icon1,const BBitmap * icon2)89 icon_equal(const BBitmap *icon1, const BBitmap *icon2)
90 {
91 return (icon1->Bounds() == icon2->Bounds()
92 && icon1->BitsLength() == icon2->BitsLength()
93 && memcmp(icon1->Bits(), icon2->Bits(), icon1->BitsLength()) == 0);
94 }
95
96
97 // Suite
98 CppUnit::Test*
Suite()99 NodeInfoTest::Suite() {
100 CppUnit::TestSuite *suite = new CppUnit::TestSuite();
101 typedef CppUnit::TestCaller<NodeInfoTest> TC;
102
103 suite->addTest( new TC("BNodeInfo::Init Test1", &NodeInfoTest::InitTest1) );
104 suite->addTest( new TC("BNodeInfo::Init Test2", &NodeInfoTest::InitTest2) );
105 suite->addTest( new TC("BNodeInfo::Type Test", &NodeInfoTest::TypeTest) );
106 suite->addTest( new TC("BNodeInfo::Icon Test", &NodeInfoTest::IconTest) );
107 suite->addTest( new TC("BNodeInfo::Preferred App Test",
108 &NodeInfoTest::PreferredAppTest) );
109 suite->addTest( new TC("BNodeInfo::App Hint Test",
110 &NodeInfoTest::AppHintTest) );
111 suite->addTest( new TC("BNodeInfo::Tracker Icon Test",
112 &NodeInfoTest::TrackerIconTest) );
113
114 return suite;
115 }
116
117 // setUp
118 void
setUp()119 NodeInfoTest::setUp()
120 {
121 BasicTest::setUp();
122 // create test dir and files
123 execCommand(
124 string("mkdir ") + testDir
125 + "; touch " + testFile1
126 + " " + testFile2
127 + " " + testFile3
128 + " " + testFile4
129 );
130 // create app
131 fApplication = new BApplication("application/x-vnd.obos.node-info-test");
132 // create icons
133 fIconM1 = create_test_icon(B_MINI_ICON, 1);
134 fIconM2 = create_test_icon(B_MINI_ICON, 2);
135 fIconM3 = create_test_icon(B_MINI_ICON, 3);
136 fIconM4 = create_test_icon(B_MINI_ICON, 4);
137 fIconL1 = create_test_icon(B_LARGE_ICON, 1);
138 fIconL2 = create_test_icon(B_LARGE_ICON, 2);
139 fIconL3 = create_test_icon(B_LARGE_ICON, 3);
140 fIconL4 = create_test_icon(B_LARGE_ICON, 4);
141 }
142
143 // tearDown
144 void
tearDown()145 NodeInfoTest::tearDown()
146 {
147 // delete the icons
148 delete fIconM1;
149 delete fIconM2;
150 delete fIconM3;
151 delete fIconM4;
152 delete fIconL1;
153 delete fIconL2;
154 delete fIconL3;
155 delete fIconL4;
156 fIconM1 = fIconM2 = fIconL1 = fIconL2 = NULL;
157 // delete the application
158 delete fApplication;
159 fApplication = NULL;
160 // remove the types we've added
161 const char * const testTypes[] = {
162 testType1, testType2, testAppSignature1, testAppSignature2
163 };
164 for (uint32 i = 0; i < sizeof(testTypes) / sizeof(const char*); i++) {
165 BMimeType type(testTypes[i]);
166 type.Delete();
167 }
168
169 // delete the test dir
170 execCommand(string("rm -rf ") + testDir);
171
172 BasicTest::tearDown();
173 }
174
175 // InitTest1
176 void
InitTest1()177 NodeInfoTest::InitTest1()
178 {
179 // BNodeInfo()
180 // * InitCheck() == B_NO_INIT
181 NextSubTest();
182 {
183 BNodeInfo nodeInfo;
184 CHK(nodeInfo.InitCheck() == B_NO_INIT);
185 }
186
187 // BNodeInfo(BNode *node)
188 // * NULL node => InitCheck() == B_BAD_VALUE
189 NextSubTest();
190 {
191 BNodeInfo nodeInfo(NULL);
192 CHK(nodeInfo.InitCheck() == B_BAD_VALUE);
193 }
194 // * invalid node => InitCheck() == B_BAD_VALUE
195 NextSubTest();
196 {
197 BNode node;
198 BNodeInfo nodeInfo(&node);
199 CHK(nodeInfo.InitCheck() == B_BAD_VALUE);
200 }
201 // * valid node => InitCheck() == B_OK
202 NextSubTest();
203 {
204 BNode node(testFile1);
205 BNodeInfo nodeInfo(&node);
206 CHK(nodeInfo.InitCheck() == B_OK);
207 }
208 }
209
210 // InitTest2
211 void
InitTest2()212 NodeInfoTest::InitTest2()
213 {
214 // status_t SetTo(BNode *node)
215 // * NULL node => InitCheck() == B_NO_INIT
216 NextSubTest();
217 {
218 BNodeInfo nodeInfo;
219 CHK(nodeInfo.SetTo(NULL) == B_BAD_VALUE);
220 CHK(nodeInfo.InitCheck() == B_BAD_VALUE);
221 }
222 // * invalid node => InitCheck() == B_BAD_VALUE
223 NextSubTest();
224 {
225 BNode node;
226 BNodeInfo nodeInfo;
227 CHK(nodeInfo.SetTo(&node) == B_BAD_VALUE);
228 CHK(nodeInfo.InitCheck() == B_BAD_VALUE);
229 }
230 // * valid node => InitCheck() == B_OK
231 // * reinitialize invalid/valid => InitCheck() == B_BAD_VALUE/B_OK
232 NextSubTest();
233 {
234 BNode node(testFile1);
235 BNodeInfo nodeInfo;
236 CHK(nodeInfo.SetTo(&node) == B_OK);
237 CHK(nodeInfo.InitCheck() == B_OK);
238 // reinit with NULL node
239 CHK(nodeInfo.SetTo(NULL) == B_BAD_VALUE);
240 CHK(nodeInfo.InitCheck() == B_BAD_VALUE);
241 // reinit with valid node
242 BNode node2(testFile2);
243 CHK(nodeInfo.SetTo(&node2) == B_OK);
244 CHK(nodeInfo.InitCheck() == B_OK);
245 }
246 }
247
248 // CheckAttr
249 static
250 void
CheckAttr(BNode & node,const char * name,type_code type,const void * data,int32 dataSize)251 CheckAttr(BNode &node, const char *name, type_code type, const void *data,
252 int32 dataSize)
253 {
254 attr_info info;
255 CHK(node.GetAttrInfo(name, &info) == B_OK);
256 CHK(info.type == type);
257 CHK(info.size == dataSize);
258 char *buffer = new char[dataSize];
259 AutoDeleter<char> deleter(buffer, true);
260 CHK(node.ReadAttr(name, type, 0, buffer, dataSize) == dataSize);
261 CHK(memcmp(buffer, data, dataSize) == 0);
262 }
263
264 // CheckNoAttr
265 static
266 void
CheckNoAttr(BNode & node,const char * name)267 CheckNoAttr(BNode &node, const char *name)
268 {
269 attr_info info;
270 CHK(node.GetAttrInfo(name, &info) == B_ENTRY_NOT_FOUND);
271 }
272
273 // CheckStringAttr
274 /*static
275 void
276 CheckStringAttr(BNode &node, const char *name, const char *data)
277 {
278 CheckAttr(node, name, B_STRING_TYPE, data, strlen(data) + 1);
279 }*/
280
281 // CheckTypeAttr
282 static
283 void
CheckTypeAttr(BNode & node,const char * data)284 CheckTypeAttr(BNode &node, const char *data)
285 {
286 CheckAttr(node, kTypeAttribute, B_MIME_STRING_TYPE, data,
287 strlen(data) + 1);
288 }
289
290 // CheckIconAttr
291 static
292 void
CheckIconAttr(BNode & node,BBitmap * data)293 CheckIconAttr(BNode &node, BBitmap *data)
294 {
295 const char *attribute = NULL;
296 uint32 type = 0;
297 switch (data->Bounds().IntegerWidth()) {
298 case 15:
299 attribute = kMiniIconAttribute;
300 type = MINI_ICON_TYPE;
301 break;
302 case 31:
303 attribute = kLargeIconAttribute;
304 type = LARGE_ICON_TYPE;
305 break;
306 default:
307 CHK(false);
308 break;
309 }
310 CheckAttr(node, attribute, type, data->Bits(), data->BitsLength());
311 }
312
313 // CheckPreferredAppAttr
314 static
315 void
CheckPreferredAppAttr(BNode & node,const char * data)316 CheckPreferredAppAttr(BNode &node, const char *data)
317 {
318 CheckAttr(node, kPreferredAppAttribute, B_MIME_STRING_TYPE, data,
319 strlen(data) + 1);
320 }
321
322 // CheckAppHintAttr
323 static
324 void
CheckAppHintAttr(BNode & node,const entry_ref * ref)325 CheckAppHintAttr(BNode &node, const entry_ref *ref)
326 {
327 BPath path;
328 CHK(path.SetTo(ref) == B_OK);
329 const char *data = path.Path();
330 // R5: Attribute is of type B_MIME_STRING_TYPE though it contains a path name!
331 CheckAttr(node, kAppHintAttribute, B_MIME_STRING_TYPE, data,
332 strlen(data) + 1);
333 }
334
335 // TypeTest
336 void
TypeTest()337 NodeInfoTest::TypeTest()
338 {
339 // status_t GetType(char *type) const
340 // * NULL type => B_BAD_ADDRESS/B_BAD_VALUE
341 NextSubTest();
342 {
343 BNode node(testFile1);
344 BNodeInfo nodeInfo;
345 CHK(nodeInfo.SetTo(&node) == B_OK);
346 CHK(equals(nodeInfo.GetType(NULL), B_BAD_ADDRESS, B_BAD_VALUE));
347 }
348 // * uninitialized => B_NO_INIT
349 NextSubTest();
350 {
351 BNodeInfo nodeInfo;
352 char type[B_MIME_TYPE_LENGTH];
353 CHK(nodeInfo.GetType(type) == B_NO_INIT);
354 }
355 // * has no type => B_ENTRY_NOT_FOUND
356 NextSubTest();
357 {
358 BNode node(testFile1);
359 BNodeInfo nodeInfo;
360 CHK(nodeInfo.SetTo(&node) == B_OK);
361 char type[B_MIME_TYPE_LENGTH];
362 CHK(nodeInfo.GetType(type) == B_ENTRY_NOT_FOUND);
363 }
364 // * set, get, reset, get
365 NextSubTest();
366 {
367 BNode node(testFile1);
368 BNodeInfo nodeInfo;
369 CHK(nodeInfo.SetTo(&node) == B_OK);
370 // set
371 CHK(nodeInfo.SetType(testType1) == B_OK);
372 // get
373 char type[B_MIME_TYPE_LENGTH];
374 CHK(nodeInfo.GetType(type) == B_OK);
375 CHK(strcmp(testType1, type) == 0);
376 CheckTypeAttr(node, testType1);
377 // reset
378 CHK(nodeInfo.SetType(testType2) == B_OK);
379 // get
380 CHK(nodeInfo.GetType(type) == B_OK);
381 CHK(strcmp(testType2, type) == 0);
382 CheckTypeAttr(node, testType2);
383 }
384
385 // status_t SetType(const char *type)
386 // * NULL type => B_OK, unsets the type
387 NextSubTest();
388 {
389 BNode node(testFile1);
390 BNodeInfo nodeInfo;
391 CHK(nodeInfo.SetTo(&node) == B_OK);
392 CHK(nodeInfo.SetType(NULL) == B_OK);
393 // get
394 char type[B_MIME_TYPE_LENGTH];
395 CHK(nodeInfo.GetType(type) == B_ENTRY_NOT_FOUND);
396 CheckNoAttr(node, kTypeAttribute);
397 }
398 // * uninitialized => B_NO_INIT
399 NextSubTest();
400 {
401 BNodeInfo nodeInfo;
402 CHK(nodeInfo.SetType(testType1) == B_NO_INIT);
403 }
404 // * invalid MIME type => B_OK
405 NextSubTest();
406 {
407 BNode node(testFile1);
408 BNodeInfo nodeInfo;
409 CHK(nodeInfo.SetTo(&node) == B_OK);
410 CHK(nodeInfo.SetType(invalidTestType) == B_OK);
411 // get
412 char type[B_MIME_TYPE_LENGTH];
413 CHK(nodeInfo.GetType(type) == B_OK);
414 CHK(strcmp(invalidTestType, type) == 0);
415 CheckTypeAttr(node, invalidTestType);
416 }
417 // * type string too long => B_OK/B_BAD_VALUE
418 NextSubTest();
419 {
420 BNode node(testFile1);
421 BNodeInfo nodeInfo;
422 CHK(nodeInfo.SetTo(&node) == B_OK);
423 // remove attr first
424 CHK(nodeInfo.SetType(NULL) == B_OK);
425 // R5: Doesn't complain when setting a too long string.
426 // Haiku: Handles this as an error case.
427 #ifdef TEST_R5
428 CHK(nodeInfo.SetType(tooLongTestType) == B_OK);
429 // get
430 char type[1024];
431 CHK(nodeInfo.GetType(type) == B_OK);
432 // R5: Returns a string one character shorter than the original string
433 // CHK(strcmp(tooLongTestType, type) == 0);
434 CheckTypeAttr(node, tooLongTestType);
435 #else
436 CHK(nodeInfo.SetType(tooLongTestType) == B_BAD_VALUE);
437 CheckNoAttr(node, kTypeAttribute);
438 #endif
439 }
440 }
441
442 // IconTest
443 void
IconTest()444 NodeInfoTest::IconTest()
445 {
446 // status_t GetIcon(BBitmap *icon, icon_size k) const
447 // * NULL icon => B_BAD_VALUE
448 // R5: Crashes when passing a NULL icon.
449 #ifndef TEST_R5
450 NextSubTest();
451 {
452 BNode node(testFile1);
453 BNodeInfo nodeInfo;
454 CHK(nodeInfo.SetTo(&node) == B_OK);
455 CHK(nodeInfo.GetIcon(NULL, B_MINI_ICON) == B_BAD_VALUE);
456 CHK(nodeInfo.GetIcon(NULL, B_LARGE_ICON) == B_BAD_VALUE);
457 }
458 #endif
459 // * uninitialized => B_NO_INIT
460 NextSubTest();
461 {
462 BNodeInfo nodeInfo;
463 BBitmap icon(BRect(0, 0, 15, 15), B_CMAP8);
464 CHK(nodeInfo.GetIcon(&icon, B_MINI_ICON) == B_NO_INIT);
465 BBitmap icon2(BRect(0, 0, 31, 31), B_CMAP8);
466 CHK(nodeInfo.GetIcon(&icon2, B_LARGE_ICON) == B_NO_INIT);
467 }
468 // * icon dimensions != icon size => B_BAD_VALUE
469 NextSubTest();
470 {
471 BNode node(testFile1);
472 BNodeInfo nodeInfo;
473 CHK(nodeInfo.SetTo(&node) == B_OK);
474 BBitmap icon(BRect(0, 0, 31, 31), B_CMAP8);
475 CHK(nodeInfo.GetIcon(&icon, B_MINI_ICON) == B_BAD_VALUE);
476 BBitmap icon2(BRect(0, 0, 15, 15), B_CMAP8);
477 CHK(nodeInfo.GetIcon(&icon2, B_LARGE_ICON) == B_BAD_VALUE);
478 }
479 // * has no icon => B_ENTRY_NOT_FOUND
480 NextSubTest();
481 {
482 BNode node(testFile1);
483 BNodeInfo nodeInfo;
484 CHK(nodeInfo.SetTo(&node) == B_OK);
485 BBitmap icon(BRect(0, 0, 15, 15), B_CMAP8);
486 CHK(nodeInfo.GetIcon(&icon, B_MINI_ICON) == B_ENTRY_NOT_FOUND);
487 }
488 // * set, get, reset, get
489 NextSubTest();
490 {
491 BNode node(testFile1);
492 BNodeInfo nodeInfo;
493 CHK(nodeInfo.SetTo(&node) == B_OK);
494 // mini
495 // set
496 CHK(nodeInfo.SetIcon(fIconM1, B_MINI_ICON) == B_OK);
497 // get
498 BBitmap icon(BRect(0, 0, 15, 15), B_CMAP8);
499 CHK(nodeInfo.GetIcon(&icon, B_MINI_ICON) == B_OK);
500 CHK(icon_equal(fIconM1, &icon));
501 CheckIconAttr(node, fIconM1);
502 // reset
503 CHK(nodeInfo.SetIcon(fIconM2, B_MINI_ICON) == B_OK);
504 // get
505 BBitmap icon2(BRect(0, 0, 15, 15), B_CMAP8);
506 CHK(nodeInfo.GetIcon(&icon2, B_MINI_ICON) == B_OK);
507 CHK(icon_equal(fIconM2, &icon2));
508 CheckIconAttr(node, fIconM2);
509 // large
510 // set
511 CHK(nodeInfo.SetIcon(fIconL1, B_LARGE_ICON) == B_OK);
512 // get
513 BBitmap icon3(BRect(0, 0, 31, 31), B_CMAP8);
514 CHK(nodeInfo.GetIcon(&icon3, B_LARGE_ICON) == B_OK);
515 CHK(icon_equal(fIconL1, &icon3));
516 CheckIconAttr(node, fIconL1);
517 // reset
518 CHK(nodeInfo.SetIcon(fIconL2, B_LARGE_ICON) == B_OK);
519 // get
520 BBitmap icon4(BRect(0, 0, 31, 31), B_CMAP8);
521 CHK(nodeInfo.GetIcon(&icon4, B_LARGE_ICON) == B_OK);
522 CHK(icon_equal(fIconL2, &icon4));
523 CheckIconAttr(node, fIconL2);
524 }
525 // * bitmap color_space != B_CMAP8 => B_OK
526 NextSubTest();
527 {
528 BNode node(testFile1);
529 BNodeInfo nodeInfo;
530 CHK(nodeInfo.SetTo(&node) == B_OK);
531 // mini
532 BBitmap icon(BRect(0, 0, 15, 15), B_RGB32);
533 CHK(nodeInfo.GetIcon(&icon, B_MINI_ICON) == B_OK);
534 BBitmap icon2(BRect(0, 0, 15, 15), B_RGB32);
535 // SetBits() can be used, since there's no row padding for 16x16.
536 icon2.SetBits(fIconM2->Bits(), fIconM2->BitsLength(), 0, B_CMAP8);
537 CHK(icon_equal(&icon, &icon2));
538 // large
539 // R5: Crashes for some weird reason in GetIcon().
540 #ifndef TEST_R5
541 BBitmap icon3(BRect(0, 0, 31, 31), B_RGB32);
542 CHK(nodeInfo.GetIcon(&icon3, B_LARGE_ICON) == B_OK);
543 BBitmap icon4(BRect(0, 0, 31, 31), B_RGB32);
544 // SetBits() can be used, since there's no row padding for 32x32.
545 icon4.SetBits(fIconL2->Bits(), fIconL2->BitsLength(), 0, B_CMAP8);
546 CHK(icon_equal(&icon3, &icon4));
547 #endif
548 }
549
550 // status_t SetIcon(const BBitmap *icon, icon_size k)
551 // * NULL icon => unsets icon, B_OK
552 NextSubTest();
553 {
554 BNode node(testFile1);
555 BNodeInfo nodeInfo;
556 CHK(nodeInfo.SetTo(&node) == B_OK);
557 // mini
558 // set
559 CHK(nodeInfo.SetIcon(NULL, B_MINI_ICON) == B_OK);
560 // get
561 BBitmap icon(BRect(0, 0, 15, 15), B_CMAP8);
562 CHK(nodeInfo.GetIcon(&icon, B_MINI_ICON) == B_ENTRY_NOT_FOUND);
563 CheckNoAttr(node, kMiniIconAttribute);
564 // large
565 // set
566 CHK(nodeInfo.SetIcon(NULL, B_LARGE_ICON) == B_OK);
567 // get
568 BBitmap icon2(BRect(0, 0, 31, 31), B_CMAP8);
569 CHK(nodeInfo.GetIcon(&icon2, B_LARGE_ICON) == B_ENTRY_NOT_FOUND);
570 CheckNoAttr(node, kLargeIconAttribute);
571 }
572 // * uninitialized => B_NO_INIT
573 NextSubTest();
574 {
575 BNodeInfo nodeInfo;
576 BBitmap icon(BRect(0, 0, 15, 15), B_CMAP8);
577 CHK(nodeInfo.SetIcon(&icon, B_MINI_ICON) == B_NO_INIT);
578 BBitmap icon2(BRect(0, 0, 31, 31), B_CMAP8);
579 CHK(nodeInfo.SetIcon(&icon2, B_LARGE_ICON) == B_NO_INIT);
580 }
581 // * icon dimensions != icon size => B_BAD_VALUE
582 NextSubTest();
583 {
584 BNode node(testFile1);
585 BNodeInfo nodeInfo;
586 CHK(nodeInfo.SetTo(&node) == B_OK);
587 BBitmap icon(BRect(0, 0, 31, 31), B_CMAP8);
588 CHK(nodeInfo.SetIcon(&icon, B_MINI_ICON) == B_BAD_VALUE);
589 BBitmap icon2(BRect(0, 0, 15, 15), B_CMAP8);
590 CHK(nodeInfo.SetIcon(&icon2, B_LARGE_ICON) == B_BAD_VALUE);
591 }
592 }
593
594 // PreferredAppTest
595 void
PreferredAppTest()596 NodeInfoTest::PreferredAppTest()
597 {
598 // status_t GetPreferredApp(char *signature, app_verb verb = B_OPEN) const
599 // * NULL signature => B_BAD_ADDRESS/B_BAD_VALUE
600 NextSubTest();
601 {
602 BNode node(testFile1);
603 BNodeInfo nodeInfo;
604 CHK(nodeInfo.SetTo(&node) == B_OK);
605 CHK(equals(nodeInfo.GetPreferredApp(NULL), B_BAD_ADDRESS,
606 B_BAD_VALUE));
607 }
608 // * uninitialized => B_NO_INIT
609 NextSubTest();
610 {
611 BNodeInfo nodeInfo;
612 char signature[B_MIME_TYPE_LENGTH];
613 CHK(nodeInfo.GetPreferredApp(signature) == B_NO_INIT);
614 }
615 // * has no preferred app => B_ENTRY_NOT_FOUND
616 NextSubTest();
617 {
618 BNode node(testFile1);
619 BNodeInfo nodeInfo;
620 CHK(nodeInfo.SetTo(&node) == B_OK);
621 char signature[B_MIME_TYPE_LENGTH];
622 CHK(nodeInfo.GetPreferredApp(signature) == B_ENTRY_NOT_FOUND);
623 }
624 // * set, get, reset, get
625 NextSubTest();
626 {
627 BNode node(testFile1);
628 BNodeInfo nodeInfo;
629 CHK(nodeInfo.SetTo(&node) == B_OK);
630 // set
631 CHK(nodeInfo.SetPreferredApp(testAppSignature1) == B_OK);
632 // get
633 char signature[B_MIME_TYPE_LENGTH];
634 CHK(nodeInfo.GetPreferredApp(signature) == B_OK);
635 CHK(strcmp(testAppSignature1, signature) == 0);
636 CheckPreferredAppAttr(node, testAppSignature1);
637 // reset
638 CHK(nodeInfo.SetPreferredApp(testAppSignature2) == B_OK);
639 // get
640 CHK(nodeInfo.GetPreferredApp(signature) == B_OK);
641 CHK(strcmp(testAppSignature2, signature) == 0);
642 CheckPreferredAppAttr(node, testAppSignature2);
643 }
644
645 // status_t SetPreferredApp(const char *signature, app_verb verb = B_OPEN)
646 // * NULL signature => unsets the preferred app
647 NextSubTest();
648 {
649 BNode node(testFile1);
650 BNodeInfo nodeInfo;
651 CHK(nodeInfo.SetTo(&node) == B_OK);
652 CHK(nodeInfo.SetPreferredApp(NULL) == B_OK);
653 // get
654 char signature[B_MIME_TYPE_LENGTH];
655 CHK(nodeInfo.GetPreferredApp(signature) == B_ENTRY_NOT_FOUND);
656 CheckNoAttr(node, kPreferredAppAttribute);
657 }
658 // * uninitialized => B_NO_INIT
659 NextSubTest();
660 {
661 BNodeInfo nodeInfo;
662 CHK(nodeInfo.SetPreferredApp(testAppSignature1) == B_NO_INIT);
663 }
664 // * invalid MIME type => B_OK
665 NextSubTest();
666 {
667 BNode node(testFile1);
668 BNodeInfo nodeInfo;
669 CHK(nodeInfo.SetTo(&node) == B_OK);
670 CHK(nodeInfo.SetPreferredApp(invalidTestType) == B_OK);
671 // get
672 char signature[B_MIME_TYPE_LENGTH];
673 CHK(nodeInfo.GetPreferredApp(signature) == B_OK);
674 CHK(strcmp(invalidTestType, signature) == 0);
675 CheckPreferredAppAttr(node, invalidTestType);
676 }
677 // * signature string too long => B_BAD_VALUE
678 NextSubTest();
679 {
680 BNode node(testFile1);
681 BNodeInfo nodeInfo;
682 CHK(nodeInfo.SetTo(&node) == B_OK);
683 // unset
684 CHK(nodeInfo.SetPreferredApp(NULL) == B_OK);
685 // try to set
686 CHK(nodeInfo.SetPreferredApp(tooLongTestType) == B_BAD_VALUE);
687 // get
688 char signature[1024];
689 CHK(nodeInfo.GetPreferredApp(signature) == B_ENTRY_NOT_FOUND);
690 CheckNoAttr(node, kPreferredAppAttribute);
691 }
692 }
693
694 // AppHintTest
695 void
AppHintTest()696 NodeInfoTest::AppHintTest()
697 {
698 // init test refs
699 entry_ref testRef1, testRef2, abstractRef;
700 CHK(get_ref_for_path(testFile3, &testRef1) == B_OK);
701 CHK(get_ref_for_path(testFile4, &testRef2) == B_OK);
702 CHK(get_ref_for_path(abstractTestEntry, &abstractRef) == B_OK);
703
704 // status_t GetAppHint(entry_ref *ref) const
705 // * NULL ref => B_BAD_VALUE
706 NextSubTest();
707 {
708 BNode node(testFile1);
709 BNodeInfo nodeInfo;
710 CHK(nodeInfo.SetTo(&node) == B_OK);
711 CHK(nodeInfo.GetAppHint(NULL) == B_BAD_VALUE);
712 }
713 // * uninitialized => B_NO_INIT
714 NextSubTest();
715 {
716 BNodeInfo nodeInfo;
717 entry_ref ref;
718 CHK(nodeInfo.GetAppHint(&ref) == B_NO_INIT);
719 }
720 // * has no app hint => B_ENTRY_NOT_FOUND
721 NextSubTest();
722 {
723 BNode node(testFile1);
724 BNodeInfo nodeInfo;
725 CHK(nodeInfo.SetTo(&node) == B_OK);
726 entry_ref ref;
727 CHK(nodeInfo.GetAppHint(&ref) == B_ENTRY_NOT_FOUND);
728 }
729 // * set, get, reset, get
730 NextSubTest();
731 {
732 BNode node(testFile1);
733 BNodeInfo nodeInfo;
734 CHK(nodeInfo.SetTo(&node) == B_OK);
735 // set
736 CHK(nodeInfo.SetAppHint(&testRef1) == B_OK);
737 // get
738 entry_ref ref;
739 CHK(nodeInfo.GetAppHint(&ref) == B_OK);
740 CHK(ref == testRef1);
741 CheckAppHintAttr(node, &testRef1);
742 // reset
743 CHK(nodeInfo.SetAppHint(&testRef2) == B_OK);
744 // get
745 CHK(nodeInfo.GetAppHint(&ref) == B_OK);
746 CHK(ref == testRef2);
747 CheckAppHintAttr(node, &testRef2);
748 }
749
750 // status_t SetAppHint(const entry_ref *ref)
751 // * NULL ref => B_OK
752 NextSubTest();
753 {
754 BNode node(testFile1);
755 BNodeInfo nodeInfo;
756 CHK(nodeInfo.SetTo(&node) == B_OK);
757 CHK(nodeInfo.SetAppHint(NULL) == B_OK);
758 // get
759 entry_ref ref;
760 CHK(nodeInfo.GetAppHint(&ref) == B_ENTRY_NOT_FOUND);
761 CheckNoAttr(node, kAppHintAttribute);
762 }
763 // * uninitialized => B_NO_INIT
764 NextSubTest();
765 {
766 BNodeInfo nodeInfo;
767 CHK(nodeInfo.SetAppHint(&testRef1) == B_NO_INIT);
768 }
769 // * invalid/abstract ref => != B_OK
770 NextSubTest();
771 {
772 BNode node(testFile1);
773 BNodeInfo nodeInfo;
774 CHK(nodeInfo.SetTo(&node) == B_OK);
775 // invalid ref
776 entry_ref invalidRef;
777 CHK(nodeInfo.SetAppHint(&invalidRef) != B_OK);
778 // abstract ref
779 CHK(nodeInfo.SetAppHint(&abstractRef) == B_OK);
780 // get
781 entry_ref ref;
782 CHK(nodeInfo.GetAppHint(&ref) == B_OK);
783 CHK(ref == abstractRef);
784 CheckAppHintAttr(node, &abstractRef);
785 }
786 }
787
788 // TestTrackerIcon
789 static
790 void
TestTrackerIcon(BNodeInfo & nodeInfo,entry_ref * ref,icon_size size,BBitmap * expectedIcon)791 TestTrackerIcon(BNodeInfo &nodeInfo, entry_ref *ref, icon_size size,
792 BBitmap *expectedIcon)
793 {
794 // mini
795 if (size == B_MINI_ICON) {
796 // non-static
797 BBitmap icon(BRect(0, 0, 15, 15), B_CMAP8);
798 CHK(nodeInfo.GetTrackerIcon(&icon, B_MINI_ICON) == B_OK);
799 CHK(icon_equal(expectedIcon, &icon));
800 // static
801 BBitmap icon1(BRect(0, 0, 15, 15), B_CMAP8);
802 CHK(BNodeInfo::GetTrackerIcon(ref, &icon1, B_MINI_ICON) == B_OK);
803 CHK(icon_equal(expectedIcon, &icon1));
804 } else {
805 // large
806 // non-static
807 BBitmap icon2(BRect(0, 0, 31, 31), B_CMAP8);
808 CHK(nodeInfo.GetTrackerIcon(&icon2, B_LARGE_ICON) == B_OK);
809 CHK(icon_equal(expectedIcon, &icon2));
810 // static
811 BBitmap icon3(BRect(0, 0, 31, 31), B_CMAP8);
812 CHK(BNodeInfo::GetTrackerIcon(ref, &icon3, B_LARGE_ICON) == B_OK);
813 CHK(icon_equal(expectedIcon, &icon3));
814 }
815 }
816
817
818 static void
TestTrackerIcon(const char * path,const char * type)819 TestTrackerIcon(const char *path, const char *type)
820 {
821 // preparation for next tests: get icons for specified type
822 BBitmap miniIcon(BRect(0, 0, 15, 15), B_CMAP8);
823 BBitmap largeIcon(BRect(0, 0, 31, 31), B_CMAP8);
824 BMimeType mimeType(type);
825 CHK(mimeType.GetIcon(&miniIcon, B_MINI_ICON) == B_OK);
826 CHK(mimeType.GetIcon(&largeIcon, B_LARGE_ICON) == B_OK);
827
828 BNode node(path);
829 CHK(node.InitCheck() == B_OK);
830 BEntry entry(path);
831 CHK(entry.InitCheck() == B_OK);
832 entry_ref ref;
833 CHK(entry.GetRef(&ref) == B_OK);
834 BNodeInfo info(&node);
835 CHK(info.InitCheck() == B_OK);
836
837 // test GetTrackerIcon()
838 TestTrackerIcon(info, &ref, B_MINI_ICON, &miniIcon);
839 TestTrackerIcon(info, &ref, B_LARGE_ICON, &largeIcon);
840 }
841
842
843 // TrackerIconTest
844 void
TrackerIconTest()845 NodeInfoTest::TrackerIconTest()
846 {
847 entry_ref testRef1;
848 CHK(get_ref_for_path(testFile1, &testRef1) == B_OK);
849 BBitmap octetMIcon(BRect(0, 0, 15, 15), B_CMAP8);
850 BBitmap octetLIcon(BRect(0, 0, 31, 31), B_CMAP8);
851 BMimeType octetType(B_FILE_MIME_TYPE);
852 CHK(octetType.GetIcon(&octetMIcon, B_MINI_ICON) == B_OK);
853 CHK(octetType.GetIcon(&octetLIcon, B_LARGE_ICON) == B_OK);
854
855 // static status_t GetTrackerIcon(const entry_ref *ref, BBitmap *icon,
856 // icon_size k = B_LARGE_ICON)
857 // * NULL ref => B_BAD_VALUE
858 NextSubTest();
859 {
860 BBitmap icon(BRect(0, 0, 15, 15), B_CMAP8);
861 CHK(BNodeInfo::GetTrackerIcon(NULL, &icon, B_MINI_ICON)
862 == B_BAD_VALUE);
863 BBitmap icon2(BRect(0, 0, 31, 31), B_CMAP8);
864 CHK(BNodeInfo::GetTrackerIcon(NULL, &icon2, B_LARGE_ICON)
865 == B_BAD_VALUE);
866 }
867
868 // status_t GetTrackerIcon(BBitmap *icon, icon_size k = B_LARGE_ICON) const
869 // * uninitialized => B_NO_INIT
870 NextSubTest();
871 {
872 BNodeInfo nodeInfo;
873 BBitmap icon(BRect(0, 0, 15, 15), B_CMAP8);
874 CHK(nodeInfo.GetTrackerIcon(&icon, B_MINI_ICON) == B_NO_INIT);
875 BBitmap icon2(BRect(0, 0, 31, 31), B_CMAP8);
876 CHK(nodeInfo.GetTrackerIcon(&icon2, B_LARGE_ICON) == B_NO_INIT);
877 }
878
879 // status_t GetTrackerIcon(BBitmap *icon, icon_size k = B_LARGE_ICON) const
880 // static status_t GetTrackerIcon(const entry_ref *ref, BBitmap *icon,
881 // icon_size k = B_LARGE_ICON)
882 // * NULL icon => B_BAD_VALUE
883 NextSubTest();
884 {
885 // non-static
886 BNode node(testFile1);
887 BNodeInfo nodeInfo;
888 CHK(nodeInfo.SetTo(&node) == B_OK);
889 CHK(nodeInfo.GetTrackerIcon(NULL, B_MINI_ICON) == B_BAD_VALUE);
890 CHK(nodeInfo.GetTrackerIcon(NULL, B_LARGE_ICON) == B_BAD_VALUE);
891 // static
892 CHK(BNodeInfo::GetTrackerIcon(&testRef1, NULL, B_MINI_ICON)
893 == B_BAD_VALUE);
894 BBitmap icon2(BRect(0, 0, 31, 31), B_CMAP8);
895 CHK(BNodeInfo::GetTrackerIcon(&testRef1, NULL, B_LARGE_ICON)
896 == B_BAD_VALUE);
897 }
898 // * icon dimensions != icon size => B_BAD_VALUE
899 NextSubTest();
900 {
901 // non-static
902 BNode node(testFile1);
903 BNodeInfo nodeInfo;
904 CHK(nodeInfo.SetTo(&node) == B_OK);
905 BBitmap icon(BRect(0, 0, 31, 31), B_CMAP8);
906 CHK(nodeInfo.GetTrackerIcon(&icon, B_MINI_ICON) == B_BAD_VALUE);
907 BBitmap icon2(BRect(0, 0, 15, 15), B_CMAP8);
908 CHK(nodeInfo.GetTrackerIcon(&icon2, B_LARGE_ICON) == B_BAD_VALUE);
909 // static
910 CHK(BNodeInfo::GetTrackerIcon(&testRef1, &icon, B_MINI_ICON)
911 == B_BAD_VALUE);
912 CHK(BNodeInfo::GetTrackerIcon(&testRef1, &icon2, B_LARGE_ICON)
913 == B_BAD_VALUE);
914 }
915
916 // initialization for further tests
917 BNode node(testFile1);
918 BNodeInfo nodeInfo;
919 CHK(nodeInfo.SetTo(&node) == B_OK);
920 // install file type
921 BMimeType type(testType1);
922 CHK(type.Install() == B_OK);
923 // set icons for file
924 CHK(nodeInfo.SetIcon(fIconM1, B_MINI_ICON) == B_OK);
925 CHK(nodeInfo.SetIcon(fIconL1, B_LARGE_ICON) == B_OK);
926 // install application type with icons for type, and make it the file's
927 // preferred application
928 BMimeType appType(testAppSignature1);
929 CHK(appType.Install() == B_OK);
930 CHK(appType.SetIconForType(testType1, fIconM2, B_MINI_ICON) == B_OK);
931 CHK(appType.SetIconForType(testType1, fIconL2, B_LARGE_ICON) == B_OK);
932 CHK(nodeInfo.SetPreferredApp(testAppSignature1) == B_OK);
933 // set icons for type in MIME database
934 CHK(type.SetIcon(fIconM3, B_MINI_ICON) == B_OK);
935 CHK(type.SetIcon(fIconL3, B_LARGE_ICON) == B_OK);
936 // install application type with icons for type, and make it the type's
937 // preferred application
938 BMimeType appType2(testAppSignature2);
939 CHK(appType2.Install() == B_OK);
940 CHK(appType2.SetIconForType(testType1, fIconM4, B_MINI_ICON) == B_OK);
941 CHK(appType2.SetIconForType(testType1, fIconL4, B_LARGE_ICON) == B_OK);
942 CHK(type.SetPreferredApp(testAppSignature2) == B_OK);
943
944 // * has icon, but not type => B_OK,
945 // returns the "application/octet-stream" icon
946 NextSubTest();
947 {
948 TestTrackerIcon(nodeInfo, &testRef1, B_MINI_ICON, &octetMIcon);
949 TestTrackerIcon(nodeInfo, &testRef1, B_LARGE_ICON, &octetLIcon);
950 }
951 // set invalid file type
952 CHK(nodeInfo.SetType(invalidTestType) == B_OK);
953 // * has icon, but invalid type => B_OK, returns file icon
954 NextSubTest();
955 {
956 TestTrackerIcon(nodeInfo, &testRef1, B_MINI_ICON, fIconM1);
957 TestTrackerIcon(nodeInfo, &testRef1, B_LARGE_ICON, fIconL1);
958 }
959 // set file type
960 CHK(nodeInfo.SetType(testType1) == B_OK);
961 // * has icon => B_OK
962 NextSubTest();
963 {
964 TestTrackerIcon(nodeInfo, &testRef1, B_MINI_ICON, fIconM1);
965 TestTrackerIcon(nodeInfo, &testRef1, B_LARGE_ICON, fIconL1);
966 }
967 // unset icons
968 CHK(nodeInfo.SetIcon(NULL, B_MINI_ICON) == B_OK);
969 CHK(nodeInfo.SetIcon(NULL, B_LARGE_ICON) == B_OK);
970 // * has no icon, but preferred app with icon for type => B_OK
971 NextSubTest();
972 {
973 TestTrackerIcon(nodeInfo, &testRef1, B_MINI_ICON, fIconM2);
974 TestTrackerIcon(nodeInfo, &testRef1, B_LARGE_ICON, fIconL2);
975 }
976 // unset icons for type for preferred app
977 CHK(appType.SetIconForType(testType1, NULL, B_MINI_ICON) == B_OK);
978 CHK(appType.SetIconForType(testType1, NULL, B_LARGE_ICON) == B_OK);
979 // * no icon, preferred app without icon for type,
980 // but icon for type in MIME data base => B_OK
981 NextSubTest();
982 {
983 TestTrackerIcon(nodeInfo, &testRef1, B_MINI_ICON, fIconM3);
984 TestTrackerIcon(nodeInfo, &testRef1, B_LARGE_ICON, fIconL3);
985 }
986 // unset preferred app
987 CHK(nodeInfo.SetPreferredApp(NULL) == B_OK);
988 // * no icon, no preferred app,
989 // but icon for type in MIME data base => B_OK
990 NextSubTest();
991 {
992 TestTrackerIcon(nodeInfo, &testRef1, B_MINI_ICON, fIconM3);
993 TestTrackerIcon(nodeInfo, &testRef1, B_LARGE_ICON, fIconL3);
994 }
995 // unset icons for type
996 CHK(type.SetIcon(NULL, B_MINI_ICON) == B_OK);
997 CHK(type.SetIcon(NULL, B_LARGE_ICON) == B_OK);
998 // * no icon, no preferred app, no icon for type in MIME data base, but
999 // preferred app for type in MIME database and app has icon for type
1000 // => B_OK
1001 NextSubTest();
1002 {
1003 TestTrackerIcon(nodeInfo, &testRef1, B_MINI_ICON, fIconM4);
1004 TestTrackerIcon(nodeInfo, &testRef1, B_LARGE_ICON, fIconL4);
1005 }
1006 // unset icons for type for preferred app
1007 CHK(appType2.SetIconForType(testType1, NULL, B_MINI_ICON) == B_OK);
1008 CHK(appType2.SetIconForType(testType1, NULL, B_LARGE_ICON) == B_OK);
1009 // * no icon, no preferred app, no icon for type in MIME data base,
1010 // preferred app for type in MIME database and app has no icon for type
1011 // => B_OK, returns the "application/octet-stream" icon
1012 NextSubTest();
1013 {
1014 TestTrackerIcon(nodeInfo, &testRef1, B_MINI_ICON, &octetMIcon);
1015 TestTrackerIcon(nodeInfo, &testRef1, B_LARGE_ICON, &octetLIcon);
1016 }
1017 // unset preferred application
1018 CHK(type.SetPreferredApp(NULL) == B_OK);
1019 // * no icon, no preferred app, no icon for type in MIME data base,
1020 // no preferred app for type in MIME database => B_OK,
1021 // returns the "application/octet-stream" icon
1022 NextSubTest();
1023 {
1024 TestTrackerIcon(nodeInfo, &testRef1, B_MINI_ICON, &octetMIcon);
1025 TestTrackerIcon(nodeInfo, &testRef1, B_LARGE_ICON, &octetLIcon);
1026 }
1027
1028 // Test GetTrackerIcon() for different types (without type set)
1029 NextSubTest();
1030 {
1031 TestTrackerIcon(testDir, B_DIRECTORY_MIME_TYPE);
1032 TestTrackerIcon("/", B_VOLUME_MIME_TYPE);
1033 TestTrackerIcon("/system", B_SYMLINK_MIME_TYPE);
1034
1035 chmod(testFile4, 0755);
1036 TestTrackerIcon(testFile4, B_APP_MIME_TYPE);
1037 chmod(testFile4, 0644);
1038 }
1039 }
1040
1041