1//------------------------------------------------------------------------------ 2// FindAppTester.cpp 3// 4//------------------------------------------------------------------------------ 5 6// Standard Includes ----------------------------------------------------------- 7#include <stdio.h> 8#include <stdlib.h> 9#include <utime.h> 10 11// System Includes ------------------------------------------------------------- 12#include <Message.h> 13#include <OS.h> 14#include <AppFileInfo.h> 15#include <Application.h> 16#include <File.h> 17#include <FindDirectory.h> 18#include <Handler.h> 19#include <Looper.h> 20#include <Path.h> 21#include <Roster.h> 22#include <String.h> 23 24// Project Includes ------------------------------------------------------------ 25#include <TestShell.h> 26#include <TestUtils.h> 27#include <cppunit/TestAssert.h> 28 29// Local Includes -------------------------------------------------------------- 30#include "AppRunner.h" 31#include "FindAppTester.h" 32 33// Local Defines --------------------------------------------------------------- 34 35// Globals --------------------------------------------------------------------- 36 37//------------------------------------------------------------------------------ 38 39static const char *uninstalledType 40 = "application/x-vnd.obos-roster-findapp-uninstalled"; 41static const char *appType1 = "application/x-vnd.obos-roster-findapp-app1"; 42static const char *appType2 = "application/x-vnd.obos-roster-findapp-app2"; 43static const char *fileType1 = "application/x-vnd.obos-roster-findapp-file1"; 44static const char *fileType2 = "application/x-vnd.obos-roster-findapp-file2"; 45static const char *textTestType = "text/x-vnd.obos-roster-findapp"; 46 47static const char *testDir = "/tmp/testdir"; 48static const char *appFile1 = "/tmp/testdir/app1"; 49static const char *appFile2 = "/tmp/testdir/app2"; 50static const char *testFile1 = "/tmp/testdir/testFile1"; 51static const char *testLink1 = "/tmp/testdir/testLink1"; 52static const char *trashAppName = "roster-findapp-app"; 53 54// get_trash_app_file 55static 56const char* 57get_trash_app_file() 58{ 59 static char trashAppFile[B_PATH_NAME_LENGTH]; 60 static bool initialized = false; 61 if (!initialized) { 62 BPath path; 63 CHK(find_directory(B_TRASH_DIRECTORY, &path) == B_OK); 64 CHK(path.Append(trashAppName) == B_OK); 65 strcpy(trashAppFile, path.Path()); 66 initialized = true; 67 } 68 return trashAppFile; 69} 70 71// install_type 72static 73void 74install_type(const char *type, const char *preferredApp = NULL, 75 const char *snifferRule = NULL) 76{ 77 BMimeType mimeType(type); 78 if (!mimeType.IsInstalled()) 79 CHK(mimeType.Install() == B_OK); 80 if (preferredApp) 81 CHK(mimeType.SetPreferredApp(preferredApp) == B_OK); 82 if (snifferRule) 83 CHK(mimeType.SetSnifferRule(snifferRule) == B_OK); 84} 85 86// ref_for_path 87static 88entry_ref 89ref_for_path(const char *filename, bool traverse = true) 90{ 91 entry_ref ref; 92 BEntry entry; 93 CHK(entry.SetTo(filename, traverse) == B_OK); 94 CHK(entry.GetRef(&ref) == B_OK); 95 return ref; 96} 97 98// create_app 99static 100void 101create_app(const char *filename, const char *signature = NULL, 102 bool install = false, bool makeExecutable = true) 103{ 104 system((string("touch ") + filename).c_str()); 105 if (makeExecutable) 106 system((string("chmod a+x ") + filename).c_str()); 107 if (signature) { 108 BFile file; 109 CHK(file.SetTo(filename, B_READ_WRITE) == B_OK); 110 BAppFileInfo appFileInfo; 111 CHK(appFileInfo.SetTo(&file) == B_OK); 112 CHK(appFileInfo.SetSignature(signature) == B_OK); 113 if (install) 114 CHK(BMimeType(signature).Install() == B_OK); 115 } 116} 117 118// create_file 119static 120entry_ref 121create_file(const char *filename, const char *type, 122 const char *preferredApp = NULL, const char *appHintPath = NULL, 123 const char *contents = NULL) 124{ 125 if (contents) 126 system((string("echo -n \"") + contents + "\" > " + filename).c_str()); 127 else 128 system((string("touch ") + filename).c_str()); 129 if (type || preferredApp || appHintPath) { 130 BFile file; 131 CHK(file.SetTo(filename, B_READ_WRITE) == B_OK); 132 BNodeInfo nodeInfo; 133 CHK(nodeInfo.SetTo(&file) == B_OK); 134 if (type) 135 CHK(nodeInfo.SetType(type) == B_OK); 136 if (preferredApp) 137 CHK(nodeInfo.SetPreferredApp(preferredApp) == B_OK); 138 if (appHintPath) { 139 entry_ref appHint(ref_for_path(appHintPath)); 140 CHK(nodeInfo.SetAppHint(&appHint) == B_OK); 141 } 142 } 143 return ref_for_path(filename); 144} 145 146// check_app_type 147static 148void 149check_app_type(const char *signature, const char *filename) 150{ 151 BMimeType type(signature); 152 CHK(type.IsInstalled() == true); 153 if (filename) { 154 entry_ref appHint; 155 CHK(type.GetAppHint(&appHint) == B_OK); 156 CHK(ref_for_path(filename) == appHint); 157 } 158} 159 160// set_file_time 161static 162void 163set_file_time(const char *filename, time_t time) 164{ 165 utimbuf buffer; 166 buffer.actime = time; 167 buffer.modtime = time; 168 CHK(utime(filename, &buffer) == 0); 169} 170 171// set_version 172static 173void 174set_version(const char *filename, uint32 version) 175{ 176 version_info versionInfo = { 1, 1, 1, 1, version, "short1", "long1" }; 177 BFile file; 178 CHK(file.SetTo(filename, B_READ_WRITE) == B_OK); 179 BAppFileInfo appFileInfo; 180 CHK(appFileInfo.SetTo(&file) == B_OK); 181 CHK(appFileInfo.SetVersionInfo(&versionInfo, B_APP_VERSION_KIND) == B_OK); 182} 183 184// set_type_app_hint 185static 186void 187set_type_app_hint(const char *signature, const char *filename) 188{ 189 BMimeType type(signature); 190 if (!type.IsInstalled()); 191 CHK(type.Install() == B_OK); 192 entry_ref fileRef(ref_for_path(filename)); 193 CHK(type.SetAppHint(&fileRef) == B_OK); 194} 195 196// setUp 197void 198FindAppTester::setUp() 199{ 200 fApplication = new BApplication("application/x-vnd.obos-roster-findapp"); 201 system((string("mkdir ") + testDir).c_str()); 202} 203 204// tearDown 205void 206FindAppTester::tearDown() 207{ 208 BMimeType(uninstalledType).Delete(); 209 BMimeType(appType1).Delete(); 210 BMimeType(appType2).Delete(); 211 BMimeType(fileType1).Delete(); 212 BMimeType(fileType2).Delete(); 213 BMimeType(textTestType).Delete(); 214 delete fApplication; 215 system((string("rm -rf ") + testDir).c_str()); 216 system((string("rm -f ") + get_trash_app_file()).c_str()); 217} 218 219// FindAppCaller 220class FindAppCaller { 221public: 222 virtual status_t operator()(const char *type, entry_ref *ref) = 0; 223}; 224 225/* 226 @case 1 uninstalled type mimeType 227 @results Should return B_LAUNCH_FAILED_APP_NOT_FOUND. 228*/ 229static 230void 231CommonFindAppTest1(FindAppCaller &caller) 232{ 233 BRoster roster; 234 entry_ref ref; 235 CHK(caller(uninstalledType, &ref) == B_LAUNCH_FAILED_APP_NOT_FOUND); 236} 237 238/* 239 @case 2 installed type mimeType, no preferred app 240 @results Should return B_LAUNCH_FAILED_NO_PREFERRED_APP. 241*/ 242static 243void 244CommonFindAppTest2(FindAppCaller &caller) 245{ 246 BRoster roster; 247 install_type(fileType1); 248 entry_ref ref; 249 CHK(caller(fileType1, &ref) == B_LAUNCH_FAILED_NO_PREFERRED_APP); 250} 251 252/* 253 @case 3 installed type mimeType, preferred app, app type not 254 installed, app has no signature 255 @results Should return B_LAUNCH_FAILED_APP_NOT_FOUND. 256*/ 257static 258void 259CommonFindAppTest3(FindAppCaller &caller) 260{ 261 BRoster roster; 262 install_type(fileType1, appType1); 263 entry_ref ref; 264 CHK(caller(fileType1, &ref) == B_LAUNCH_FAILED_APP_NOT_FOUND); 265} 266 267/* 268 @case 4 installed type mimeType, preferred app, app type not 269 installed, app has signature 270 @results Should return B_OK and set the ref to refer to the 271 application's executable. Should install the app type and 272 set the app hint on it. 273*/ 274static 275void 276CommonFindAppTest4(FindAppCaller &caller) 277{ 278 BRoster roster; 279 create_app(appFile1, appType1); 280 install_type(fileType1, appType1); 281 entry_ref ref; 282 CHK(caller(fileType1, &ref) == B_OK); 283 CHK(ref_for_path(appFile1) == ref); 284 check_app_type(appType1, appFile1); 285} 286 287/* 288 @case 5 installed type mimeType, preferred app, app type installed, 289 app has signature 290 @results Should return B_OK and set the ref to refer to the 291 application'sexecutable. Should set the app hint on the 292 app type. 293*/ 294static 295void 296CommonFindAppTest5(FindAppCaller &caller) 297{ 298 BRoster roster; 299 create_app(appFile1, appType1, true); 300 install_type(fileType1, appType1); 301 entry_ref ref; 302 CHK(caller(fileType1, &ref) == B_OK); 303 CHK(ref_for_path(appFile1) == ref); 304 check_app_type(appType1, appFile1); 305} 306 307/* 308 @case 6 installed type mimeType, preferred app, app type installed, 309 app has signature, app has no execute permission 310 @results Should return B_OK and set the ref to refer to the 311 application's executable. Should set the app hint on the 312 app type. 313*/ 314static 315void 316CommonFindAppTest6(FindAppCaller &caller) 317{ 318 BRoster roster; 319 create_app(appFile1, appType1, true, false); 320 install_type(fileType1, appType1); 321 entry_ref ref; 322 CHK(caller(fileType1, &ref) == B_OK); 323 CHK(ref_for_path(appFile1) == ref); 324 check_app_type(appType1, appFile1); 325} 326 327/* 328 @case 7 installed type mimeType, preferred app, app type installed, 329 two apps have the signature 330 @results Should return B_OK and set the ref to refer to the 331 application executable with the most recent modification 332 time. Should set the app hint on the app type. 333*/ 334static 335void 336CommonFindAppTest7(FindAppCaller &caller) 337{ 338 BRoster roster; 339 create_app(appFile1, appType1); 340 create_app(appFile2, appType1, true); 341 set_file_time(appFile2, time(NULL) + 1); 342 install_type(fileType1, appType1); 343 entry_ref ref; 344 CHK(caller(fileType1, &ref) == B_OK); 345 CHK(ref_for_path(appFile2) == ref); 346 check_app_type(appType1, appFile2); 347} 348 349/* 350 @case 8 installed type mimeType, preferred app, app type installed, 351 two apps have the signature, one has a version info, the 352 other one is newer 353 @results Should return B_OK and set the ref to refer to the 354 application executable with version info. Should set the 355 app hint on the app type. 356*/ 357static 358void 359CommonFindAppTest8(FindAppCaller &caller) 360{ 361 BRoster roster; 362 create_app(appFile1, appType1); 363 set_version(appFile1, 1); 364 create_app(appFile2, appType1, true); 365 set_file_time(appFile2, time(NULL) + 1); 366 install_type(fileType1, appType1); 367 entry_ref ref; 368 CHK(caller(fileType1, &ref) == B_OK); 369 CHK(ref_for_path(appFile1) == ref); 370 check_app_type(appType1, appFile1); 371} 372 373/* 374 @case 9 installed type mimeType, preferred app, app type installed, 375 two apps have the signature, both apps have a version info 376 @results Should return B_OK and set the ref to refer to the 377 application executable with the greater version. Should 378 set the app hint on the app type. 379*/ 380static 381void 382CommonFindAppTest9(FindAppCaller &caller) 383{ 384 BRoster roster; 385 create_app(appFile1, appType1); 386 set_version(appFile1, 2); 387 create_app(appFile2, appType1, true); 388 set_version(appFile1, 1); 389 set_file_time(appFile2, time(NULL) + 1); 390 install_type(fileType1, appType1); 391 entry_ref ref; 392 CHK(caller(fileType1, &ref) == B_OK); 393 CHK(ref_for_path(appFile1) == ref); 394 check_app_type(appType1, appFile1); 395} 396 397/* 398 @case 10 installed type mimeType, preferred app, app type installed, 399 preferred app type has an app hint that points to an app 400 with a different signature 401 @results Should return B_OK and set the ref to refer to the 402 application's executable. Should remove the incorrect app 403 hint on the app type. (Haiku: Should set the correct app 404 hint. Don't even return the wrong app?) 405*/ 406static 407void 408CommonFindAppTest10(FindAppCaller &caller) 409{ 410 BRoster roster; 411 create_app(appFile1, appType2); 412 set_type_app_hint(appType1, appFile1); 413 entry_ref appHint; 414 CHK(BMimeType(appType1).GetAppHint(&appHint) == B_OK); 415 install_type(fileType1, appType1); 416 entry_ref ref; 417 CHK(caller(fileType1, &ref) == B_OK); 418 CHK(ref_for_path(appFile1) == ref); 419 CHK(BMimeType(appType1).GetAppHint(&appHint) == B_ENTRY_NOT_FOUND); 420// Haiku: We set the app hint for app type 2. There's no reason not to do it. 421#ifdef TEST_R5 422 CHK(BMimeType(appType2).IsInstalled() == false); 423#else 424 check_app_type(appType2, appFile1); 425#endif 426} 427 428/* 429 @case 11 installed type mimeType, preferred app, app type installed, 430 preferred app type has an app hint pointing to void, 431 a differently named app with this signature exists 432 @results Should return B_OK and set the ref to refer to the 433 application's executable. Should update the app 434 hint on the app type. 435*/ 436static 437void 438CommonFindAppTest11(FindAppCaller &caller) 439{ 440 BRoster roster; 441 create_app(appFile1, appType1); 442 set_type_app_hint(appType1, appFile2); 443 install_type(fileType1, appType1); 444 entry_ref ref; 445 CHK(caller(fileType1, &ref) == B_OK); 446 CHK(ref_for_path(appFile1) == ref); 447 check_app_type(appType1, appFile1); 448} 449 450/* 451 @case 12 mimeType is app signature, not installed 452 @results Should return B_OK and set the ref to refer to the 453 application executable. Should set the app hint on the 454 app type. 455*/ 456static 457void 458CommonFindAppTest12(FindAppCaller &caller) 459{ 460 BRoster roster; 461 create_app(appFile1, appType1); 462 entry_ref ref; 463 CHK(caller(appType1, &ref) == B_OK); 464 CHK(ref_for_path(appFile1) == ref); 465 check_app_type(appType1, appFile1); 466} 467 468/* 469 @case 13 mimeType is installed, but has no preferred application, 470 super type has preferred application 471 @results Should return B_OK and set the ref to refer to the 472 application executable associated with the preferred app 473 of the supertype. Should set the app hint on the app type. 474*/ 475static 476void 477CommonFindAppTest13(FindAppCaller &caller) 478{ 479 BRoster roster; 480 // make sure, the original preferred app for the "text" supertype is 481 // re-installed 482 struct TextTypeSaver { 483 TextTypeSaver() 484 { 485 BMimeType textType("text"); 486 hasPreferredApp 487 = (textType.GetPreferredApp(preferredApp) == B_OK); 488 } 489 490 ~TextTypeSaver() 491 { 492 BMimeType textType("text"); 493 textType.SetPreferredApp(hasPreferredApp ? preferredApp : NULL); 494 } 495 496 bool hasPreferredApp; 497 char preferredApp[B_MIME_TYPE_LENGTH]; 498 } _saver; 499 500 create_app(appFile1, appType1); 501 CHK(BMimeType("text").SetPreferredApp(appType1) == B_OK); 502 install_type(textTestType); 503 entry_ref ref; 504 CHK(caller(textTestType, &ref) == B_OK); 505 CHK(ref_for_path(appFile1) == ref); 506 check_app_type(appType1, appFile1); 507} 508 509/* 510 @case 14 installed type mimeType, preferred app, app type not installed, 511 app has signature, app is trash 512 @results Should return B_LAUNCH_FAILED_APP_IN_TRASH. 513*/ 514static 515void 516CommonFindAppTest14(FindAppCaller &caller) 517{ 518 BRoster roster; 519 create_app(get_trash_app_file(), appType1); 520 install_type(fileType1, appType1); 521 entry_ref ref; 522 CHK(caller(fileType1, &ref) == B_LAUNCH_FAILED_APP_IN_TRASH); 523} 524 525/* 526 @case 15 installed type mimeType, preferred app, app type installed, 527 preferred app type has an app hint pointing to void, 528 no app with this signature exists 529 @results Should return B_LAUNCH_FAILED_APP_NOT_FOUND and unset the 530 app type's app hint. 531*/ 532static 533void 534CommonFindAppTest15(FindAppCaller &caller) 535{ 536 BRoster roster; 537 set_type_app_hint(appType1, appFile1); 538 install_type(fileType1, appType1); 539 entry_ref ref; 540 CHK(caller(fileType1, &ref) == B_LAUNCH_FAILED_APP_NOT_FOUND); 541 entry_ref appHint; 542 CHK(BMimeType(appType1).GetAppHint(&appHint) == B_ENTRY_NOT_FOUND); 543} 544 545/* 546 @case 16 installed type mimeType, preferred app, app type installed, 547 preferred app type has an app hint pointing to a cyclic 548 link, no app with this signature exists 549 @results R5: Should return B_OK and set the ref to refer to the 550 link. 551 Haiku: Should return B_LAUNCH_FAILED_APP_NOT_FOUND and 552 unset the app type's app hint. 553*/ 554static 555void 556CommonFindAppTest16(FindAppCaller &caller) 557{ 558 BRoster roster; 559 set_type_app_hint(appType1, appFile1); 560 install_type(fileType1, appType1); 561 system((string("ln -s ") + appFile1 + " " + appFile1).c_str()); 562 entry_ref ref; 563 entry_ref appHint; 564#ifdef TEST_R5 565 CHK(caller(fileType1, &ref) == B_OK); 566 CHK(ref_for_path(appFile1, false) == ref); 567 CHK(BMimeType(appType1).GetAppHint(&appHint) == B_OK); 568 CHK(appHint == ref); 569#else 570 CHK(caller(fileType1, &ref) == B_LAUNCH_FAILED_APP_NOT_FOUND); 571 CHK(BMimeType(appType1).GetAppHint(&appHint) == B_ENTRY_NOT_FOUND); 572#endif 573} 574 575typedef void commonTestFunction(FindAppCaller &caller); 576static commonTestFunction *commonTestFunctions[] = { 577 CommonFindAppTest1, CommonFindAppTest2, CommonFindAppTest3, 578 CommonFindAppTest4, CommonFindAppTest5, CommonFindAppTest6, 579 CommonFindAppTest7, CommonFindAppTest8, CommonFindAppTest9, 580 CommonFindAppTest10, CommonFindAppTest11, CommonFindAppTest12, 581 CommonFindAppTest13, CommonFindAppTest14, CommonFindAppTest15, 582 CommonFindAppTest16 583}; 584static int32 commonTestFunctionCount 585 = sizeof(commonTestFunctions) / sizeof(commonTestFunction*); 586 587/* 588 status_t FindApp(const char *mimeType, entry_ref *app) const 589 @case 1 mimeType or app are NULL 590 @results Should return B_BAD_VALUE. 591*/ 592void FindAppTester::FindAppTestA1() 593{ 594 BRoster roster; 595 CHK(roster.FindApp((const char*)NULL, NULL) == B_BAD_VALUE); 596// R5: crashes when passing a non-NULL type, but a NULL ref. 597#ifndef TEST_R5 598 CHK(roster.FindApp("image/gif", NULL) == B_BAD_VALUE); 599#endif 600 entry_ref ref; 601 CHK(roster.FindApp((const char*)NULL, &ref) == B_BAD_VALUE); 602} 603 604/* 605 status_t FindApp(const char *mimeType, entry_ref *app) const 606 @case 2 mimeType is invalid 607 @results Should return B_BAD_VALUE. 608*/ 609void FindAppTester::FindAppTestA2() 610{ 611 BRoster roster; 612 entry_ref ref; 613 CHK(roster.FindApp("invalid/mine/type", &ref) == B_BAD_VALUE); 614} 615 616// FindAppTypeCaller 617class FindAppTypeCaller : public FindAppCaller { 618public: 619 virtual status_t operator()(const char *type, entry_ref *ref) 620 { 621 BRoster roster; 622 return roster.FindApp(type, ref); 623 } 624}; 625 626/* 627 status_t FindApp(const char *mimeType, entry_ref *app) const 628 @case 3 FindApp(const char*, entry_ref*) cases 3-16 629 (== common cases 1-14) 630*/ 631void FindAppTester::FindAppTestA3() 632{ 633 FindAppTypeCaller caller; 634 for (int32 i = 0; i < commonTestFunctionCount; i++) { 635 NextSubTest(); 636 (*commonTestFunctions[i])(caller); 637 tearDown(); 638 setUp(); 639 } 640} 641 642/* 643 status_t FindApp(entry_ref *ref, entry_ref *app) const 644 @case 1 ref or app are NULL 645 @results Should return B_BAD_VALUE. 646*/ 647void FindAppTester::FindAppTestB1() 648{ 649 BRoster roster; 650 CHK(roster.FindApp((entry_ref*)NULL, NULL) == B_BAD_VALUE); 651// R5: Crashes when passing a NULL (app) ref. 652#ifndef TEST_R5 653 create_app(appFile1, appType1); 654 entry_ref fileRef(create_file(testFile1, fileType1, appType1)); 655 CHK(roster.FindApp(&fileRef, NULL) == B_BAD_VALUE); 656#endif 657 entry_ref ref; 658 CHK(roster.FindApp((entry_ref*)NULL, &ref) == B_BAD_VALUE); 659} 660 661/* 662 status_t FindApp(entry_ref *ref, entry_ref *app) const 663 @case 2 ref doesn't refer to an existing entry => 664 @results Should return B_ENTRY_NOT_FOUND. 665*/ 666void FindAppTester::FindAppTestB2() 667{ 668 BRoster roster; 669 entry_ref fileRef(ref_for_path(testFile1)); 670 entry_ref ref; 671 CHK(roster.FindApp(&fileRef, &ref) == B_ENTRY_NOT_FOUND); 672} 673 674/* 675 status_t FindApp(entry_ref *ref, entry_ref *app) const 676 @case 3 ref is valid, file has type and preferred app, preferred 677 app is in trash 678 @results Should return B_LAUNCH_FAILED_APP_IN_TRASH. 679*/ 680void FindAppTester::FindAppTestB3() 681{ 682 BRoster roster; 683 create_app(get_trash_app_file(), appType1); 684 entry_ref fileRef(create_file(testFile1, fileType1, appType1)); 685 entry_ref ref; 686 CHK(roster.FindApp(&fileRef, &ref) == B_LAUNCH_FAILED_APP_IN_TRASH); 687} 688 689/* 690 status_t FindApp(entry_ref *ref, entry_ref *app) const 691 @case 4 ref is valid, file has type and preferred app, app type is 692 not installed, app exists and has signature 693 @results Should return B_OK and set the ref to refer to the file's 694 (not the file type's) preferred application's executable. 695 Should install the app type and set the app hint on it. 696*/ 697void FindAppTester::FindAppTestB4() 698{ 699 BRoster roster; 700 create_app(appFile1, appType1); 701 create_app(appFile2, appType2); 702 install_type(fileType1, appType1); 703 entry_ref fileRef(create_file(testFile1, fileType1, appType2)); 704 entry_ref ref; 705 CHK(roster.FindApp(&fileRef, &ref) == B_OK); 706 CHK(ref_for_path(appFile2) == ref); 707 check_app_type(appType2, appFile2); 708} 709 710/* 711 status_t FindApp(entry_ref *ref, entry_ref *app) const 712 @case 5 ref is valid, file has no type, but preferred app, 713 app type is not installed, app exists and has signature 714 @results Should return B_OK and set the ref to refer to the 715 application's executable. Should install the app type and 716 set the app hint on it. 717*/ 718void FindAppTester::FindAppTestB5() 719{ 720 BRoster roster; 721 create_app(appFile1, appType1); 722 entry_ref fileRef(create_file(testFile1, NULL, appType1)); 723 entry_ref ref; 724 CHK(roster.FindApp(&fileRef, &ref) == B_OK); 725 CHK(ref_for_path(appFile1) == ref); 726 check_app_type(appType1, appFile1); 727} 728 729/* 730 status_t FindApp(entry_ref *ref, entry_ref *app) const 731 @case 6 ref is valid, file has type and app hint, the type's 732 preferred app type is not installed, app exists and has 733 signature 734 @results Should return B_OK and set the ref to refer to the file 735 type's preferred application's executable. Should install 736 the app type and set the app hint on it. 737*/ 738void FindAppTester::FindAppTestB6() 739{ 740 BRoster roster; 741 create_app(appFile1, appType1); 742 create_app(appFile2, appType2); 743 install_type(fileType1, appType1); 744 entry_ref fileRef(create_file(testFile1, fileType1, NULL, appFile2)); 745 entry_ref ref; 746 CHK(roster.FindApp(&fileRef, &ref) == B_OK); 747 CHK(ref_for_path(appFile1) == ref); 748 check_app_type(appType1, appFile1); 749} 750 751/* 752 status_t FindApp(entry_ref *ref, entry_ref *app) const 753 @case 7 ref is valid, file has type, the type's preferred app 754 type is not installed, app exists and has signature, 755 file is executable 756 @results Should return B_OK and set the ref to refer to the file. 757 Should not set the app hint on the app or file type (Why?). 758*/ 759void FindAppTester::FindAppTestB7() 760{ 761 BRoster roster; 762 create_app(appFile1, appType1); 763 install_type(fileType1, appType1); 764 entry_ref fileRef(create_file(testFile1, fileType1)); 765 system((string("chmod a+x ") + testFile1).c_str()); 766 entry_ref ref; 767 CHK(roster.FindApp(&fileRef, &ref) == B_OK); 768 CHK(ref_for_path(testFile1) == ref); 769 CHK(BMimeType(appType1).IsInstalled() == false); 770 CHK(BMimeType(fileType1).GetAppHint(&ref) == B_ENTRY_NOT_FOUND); 771} 772 773/* 774 status_t FindApp(entry_ref *ref, entry_ref *app) const 775 @case 8 ref is valid and refers to a link to a file, file has type, 776 the type's preferred app type is not installed, 777 app exists and has signature 778 @results Should return B_OK and set the ref to refer to the file 779 type's preferred application's executable. Should install 780 the app type and set the app hint on it. 781*/ 782void FindAppTester::FindAppTestB8() 783{ 784 BRoster roster; 785 create_app(appFile1, appType1); 786 install_type(fileType1, appType1); 787 create_file(testFile1, fileType1); 788 system((string("ln -s ") + testFile1 + " " + testLink1).c_str()); 789 entry_ref linkRef(ref_for_path(testLink1, false)); 790 entry_ref ref; 791 CHK(roster.FindApp(&linkRef, &ref) == B_OK); 792 CHK(ref_for_path(appFile1) == ref); 793 check_app_type(appType1, appFile1); 794} 795 796// FileWithTypeCaller 797class FileWithTypeCaller : public FindAppCaller { 798public: 799 virtual status_t operator()(const char *type, entry_ref *ref) 800 { 801 BRoster roster; 802 entry_ref fileRef(create_file(testFile1, type)); 803 return roster.FindApp(&fileRef, ref); 804 } 805}; 806 807/* 808 status_t FindApp(entry_ref *ref, entry_ref *app) const 809 @case 9 ref is valid, file has no type, sniffing results in a type, 810 type is set on file, 811 FindApp(const char*, entry_ref*) cases 4-16 812 (== common cases 2-14) 813*/ 814void FindAppTester::FindAppTestB9() 815{ 816 FileWithTypeCaller caller; 817 for (int32 i = 0; i < commonTestFunctionCount; i++) { 818 NextSubTest(); 819 (*commonTestFunctions[i])(caller); 820 tearDown(); 821 setUp(); 822 } 823} 824 825// SniffFileTypeCaller 826class SniffFileTypeCaller : public FindAppCaller { 827public: 828 virtual status_t operator()(const char *type, entry_ref *ref) 829 { 830 BRoster roster; 831 entry_ref fileRef(create_file(testFile1, type, NULL, NULL, 832 "UnIQe pAtTeRn")); 833 install_type(fileType1, NULL, "1.0 [0] ('UnIQe pAtTeRn')"); 834 return roster.FindApp(&fileRef, ref); 835 } 836}; 837 838/* 839 status_t FindApp(entry_ref *ref, entry_ref *app) const 840 @case 10 ref is valid, file has no type, sniffing results in a type, 841 type is set on file, 842 FindApp(const char*, entry_ref*) cases 3-16 843 (== common cases 1-14) 844*/ 845void FindAppTester::FindAppTestB10() 846{ 847 SniffFileTypeCaller caller; 848 for (int32 i = 1; i < commonTestFunctionCount; i++) { 849 NextSubTest(); 850 (*commonTestFunctions[i])(caller); 851 tearDown(); 852 setUp(); 853 } 854} 855 856/* 857 status_t FindApp(entry_ref *ref, entry_ref *app) const 858 @case 11 ref is valid and refers to a cyclic link 859 @results Should return B_LAUNCH_FAILED_NO_RESOLVE_LINK. 860*/ 861void FindAppTester::FindAppTestB11() 862{ 863 BRoster roster; 864 system((string("ln -s ") + testLink1 + " " + testLink1).c_str()); 865 entry_ref linkRef(ref_for_path(testLink1, false)); 866 entry_ref ref; 867 CHK(roster.FindApp(&linkRef, &ref) == B_LAUNCH_FAILED_NO_RESOLVE_LINK); 868} 869 870/* 871 status_t FindApp(entry_ref *ref, entry_ref *app) const 872 @case 12 ref is valid and refers to a link to void 873 @results Should return B_LAUNCH_FAILED_NO_RESOLVE_LINK. 874*/ 875void FindAppTester::FindAppTestB12() 876{ 877 BRoster roster; 878 system((string("ln -s ") + testFile1 + " " + testLink1).c_str()); 879 entry_ref linkRef(ref_for_path(testLink1, false)); 880 entry_ref ref; 881 CHK(roster.FindApp(&linkRef, &ref) == B_LAUNCH_FAILED_NO_RESOLVE_LINK); 882} 883 884 885Test* FindAppTester::Suite() 886{ 887 TestSuite* SuiteOfTests = new TestSuite; 888 889 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestA1); 890 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestA2); 891 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestA3); 892 893 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB1); 894 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB2); 895 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB3); 896 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB4); 897 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB5); 898 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB6); 899 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB7); 900 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB8); 901 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB9); 902 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB10); 903 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB11); 904 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB12); 905 906 return SuiteOfTests; 907} 908 909