152a38012Sejakowatz// MimeTypeTest.cpp
252a38012Sejakowatz
352a38012Sejakowatz#include <ctype.h>			// For tolower()
452a38012Sejakowatz#include <fcntl.h>			// open()
552a38012Sejakowatz#include <map>
652a38012Sejakowatz#include <queue>
752a38012Sejakowatz#include <stdio.h>
852a38012Sejakowatz#include <string.h>			// For memcmp()
952a38012Sejakowatz#include <string>
1052a38012Sejakowatz#include <unistd.h>
1152a38012Sejakowatz#include <vector>
1252a38012Sejakowatz
1352a38012Sejakowatz
14762a48a0STyler Dauwalder#include <fs_attr.h>		// For struct attr_info
1552a38012Sejakowatz#include <fs_info.h>
1652a38012Sejakowatz#include <Application.h>
1752a38012Sejakowatz#include <Bitmap.h>
1852a38012Sejakowatz#include <DataIO.h>
1952a38012Sejakowatz#include <Drivers.h>		// B_GET_ICON, device_icon
2052a38012Sejakowatz#include <Message.h>
2152a38012Sejakowatz#include <Mime.h>
223155eae2STyler Dauwalder#if !TEST_R5
23fde08bf3STyler Dauwalder	#include <mime/database_support.h>
243155eae2STyler Dauwalder#endif
2552a38012Sejakowatz#include <Path.h>			// Only needed for entry_ref dumps
2652a38012Sejakowatz#include <StorageKit.h>
2752a38012Sejakowatz#include <String.h>
28762a48a0STyler Dauwalder#include <storage_support.h>	// for split_path()
2952a38012Sejakowatz
30762a48a0STyler Dauwalder#include "TestShell.h"
31762a48a0STyler Dauwalder#include "TestApp.h"
32762a48a0STyler Dauwalder#include "TestUtils.h"
3352a38012Sejakowatz
34155b583aSIngo Weinhold#include "MimeTypeTest.h"
35155b583aSIngo Weinhold
3652a38012Sejakowatz// MIME database directories
3752a38012Sejakowatzstatic const char *testDir				= "/tmp/mimeTestDir";
38dda17c00STyler Dauwalderstatic const char *R5DatabaseDir		= "/boot/home/config/settings/beos_mime";
39dda17c00STyler Dauwalder#if TEST_R5
40dda17c00STyler Dauwalderstatic std::string mimeDatabaseDir		= R5DatabaseDir;
41dda17c00STyler Dauwalder#else
42fde08bf3STyler Dauwalderstatic std::string mimeDatabaseDir		= BPrivate::Storage::Mime::kDatabaseDir;
43dda17c00STyler Dauwalder#endif
4452a38012Sejakowatz
4552a38012Sejakowatz// MIME Test Types
4652a38012Sejakowatz// testType and testTypeApp are Delete()d after each test.
4752a38012Sejakowatzstatic const char *testType				= "text/x-vnd.obos-Storage-Kit-Test";
4852a38012Sejakowatzstatic const char *testType1			= "text/x-vnd.obos-Storage-Kit-Test1";
4952a38012Sejakowatzstatic const char *testType2			= "text/x-vnd.obos-Storage-Kit-Test2";
5052a38012Sejakowatzstatic const char *testType3			= "text/x-vnd.obos-Storage-Kit-Test3";
5152a38012Sejakowatzstatic const char *testType4			= "text/x-vnd.obos-Storage-Kit-Test4";
5252a38012Sejakowatzstatic const char *testType5			= "text/x-vnd.obos-Storage-Kit-Test5";
5352a38012Sejakowatzstatic const char *testTypeApp			= "application/StorageKit-Test";
5452a38012Sejakowatzstatic const char *testTypeApp1			=  "application/"
5552a38012Sejakowatz										   "x-vnd.obos.mime.test.test1";
5652a38012Sejakowatzstatic const char *testTypeApp2			=  "application/"
5752a38012Sejakowatz										   "x-vnd.obos.mime.test.test2";
5852a38012Sejakowatzstatic const char *testTypeApp3			=  "application/"
5952a38012Sejakowatz										   "x-vnd.obos.mime.test.test3";
6052a38012Sejakowatzstatic const char *testTypeInvalid		= "text/Are spaces valid?";
6152a38012Sejakowatzstatic const char *testTypeSuperValid	= "valid-but-fake-supertype";
6252a38012Sejakowatzstatic const char *testTypeSuperInvalid	= "?????";
6352a38012Sejakowatz
6452a38012Sejakowatz// Real MIME types
6552a38012Sejakowatzstatic const char *wildcardType			= "application/octet-stream";
66762a48a0STyler Dauwalderstatic const char *applicationSupertype	= "application";
6752a38012Sejakowatz
6852a38012Sejakowatz// Application Paths
6952a38012Sejakowatzstatic const char *testApp				= "/boot/beos/apps/SoundRecorder";
7052a38012Sejakowatzstatic const char *testApp2				= "/boot/beos/apps/CDPlayer";
7152a38012Sejakowatzstatic const char *fakeTestApp			= "/__this_isn't_likely_to_exist__";
7252a38012Sejakowatz
7352a38012Sejakowatz// BMessage field names
74e3a2f206STyler Dauwalderstatic const char *applicationsField		= "applications";
7552a38012Sejakowatzstatic const char *typeField				= "type";
76e3a2f206STyler Dauwalderstatic const char *typesField				= "types";
7752a38012Sejakowatzstatic const char *fileExtField				= "extensions";
7852a38012Sejakowatzstatic const char *attrInfoField_Name		= "attr:name";
7952a38012Sejakowatzstatic const char *attrInfoField_PublicName	= "attr:public_name";
8052a38012Sejakowatzstatic const char *attrInfoField_Type		= "attr:type";
8152a38012Sejakowatzstatic const char *attrInfoField_Viewable	= "attr:viewable";
8252a38012Sejakowatzstatic const char *attrInfoField_Editable	= "attr:editable";
8352a38012Sejakowatz
8452a38012Sejakowatz// Descriptions
8552a38012Sejakowatzstatic const char *testDescr			= "Just a test, nothing more :-)";
8652a38012Sejakowatzstatic const char *testDescr2			= "Another amazing test string";
87a30a4a41SJohn Scipionestatic const char *longDescr			=
8852a38012Sejakowatz"This description is longer than B_MIME_TYPE_LENGTH, which is quite useful for certain things... "
8952a38012Sejakowatz"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
9052a38012Sejakowatz"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
9152a38012Sejakowatz"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
9252a38012Sejakowatz"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";
9352a38012Sejakowatz// Signatures
9452a38012Sejakowatzstatic const char *testSig				= "application/x-vnd.obos.mime-type-test";
9552a38012Sejakowatzstatic const char *testSig2				= "application/x-vnd.obos.mime-type-test-2";
9652a38012Sejakowatzstatic const char *longSig				= "application/x-vnd.obos.mime-type-test-long."
9752a38012Sejakowatz"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
9852a38012Sejakowatz"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
9952a38012Sejakowatz"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
10052a38012Sejakowatz"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";
10152a38012Sejakowatz
10252a38012Sejakowatz// Declarations for handy dandy private functions
10352a38012Sejakowatzstatic bool operator==(BBitmap &bmp1, BBitmap &bmp2);
10452a38012Sejakowatzstatic bool operator!=(BBitmap &bmp1, BBitmap &bmp2);
10552a38012Sejakowatzstatic bool operator==(BMessage &msg1, BMessage &msg2);
10652a38012Sejakowatzstatic bool operator!=(BMessage &msg1, BMessage &msg2);
10752a38012Sejakowatzstatic void fill_bitmap(BBitmap &bmp, char value);
108f7046d77STyler Dauwalder//static void dump_bitmap(BBitmap &bmp, char *name = "bmp");
109f7046d77STyler Dauwalder#if !TEST_R5
110f7046d77STyler Dauwalder	static status_t reduce_color_depth(BBitmap &src32, BBitmap &dest8);
111f7046d77STyler Dauwalder#endif
11252a38012Sejakowatz//static void dump_ref(entry_ref *ref, char* name = "ref");
11352a38012Sejakowatzstatic void to_lower(const char *str, std::string &result);
11464b563e0STyler Dauwalderstatic std::string to_lower(const char *str);
115dda17c00STyler Dauwalderstatic void remove_type(const char *type, const char *databaseDir = mimeDatabaseDir.c_str());
116dda17c00STyler Dauwalderstatic bool type_exists(const char *type, const char *databaseDir = mimeDatabaseDir.c_str());
11752a38012Sejakowatzclass ContainerAdapter;
11852a38012Sejakowatzclass SetAdapter;
11952a38012Sejakowatzclass QueueAdapter;
12052a38012Sejakowatzvoid FillWithMimeTypes(ContainerAdapter &container, BMessage &typeMessage, const char* fieldName);
12152a38012Sejakowatz	// Used to add all the types in a BMessage from GetInstalled*Types() to some
12252a38012Sejakowatz	// sort of container object (via an adapter to support differing interfaces).
12352a38012Sejakowatz
124dda17c00STyler Dauwalder// Custom TestSuite class to allow us to make a copy of the MIME database directory
125dda17c00STyler Dauwalder// before running all the BMimeType tests
126dda17c00STyler Dauwalderclass MimeTypeTestSuite : public CppUnit::TestSuite {
127dda17c00STyler Dauwalderpublic:
12875120765STyler Dauwalder	MimeTypeTestSuite() : CppUnit::TestSuite(), fMimeDirExisted(false) {}
129dda17c00STyler Dauwalder	virtual void setUp()
130dda17c00STyler Dauwalder	{
131dda17c00STyler Dauwalder		// If we're using a directory other than the R5 MIME database directory, make
132dda17c00STyler Dauwalder		// sure that directory exists. If not, make a complete copy of the R5 database
133dda17c00STyler Dauwalder		// directory.
134dda17c00STyler Dauwalder		if (mimeDatabaseDir != R5DatabaseDir) {
135dda17c00STyler Dauwalder			BEntry dir(mimeDatabaseDir.c_str());
136dda17c00STyler Dauwalder			if (dir.InitCheck() != B_OK || !dir.Exists()) {
137dda17c00STyler Dauwalder				if (BTestShell::GlobalBeVerbose())
138dda17c00STyler Dauwalder					cout << "(Making a copy of your MIME database at '" + mimeDatabaseDir + "')" << endl;
139dda17c00STyler Dauwalder				std::string cmd = std::string("copyattr -d -r -- ") + R5DatabaseDir
140dda17c00STyler Dauwalder					+ " " + mimeDatabaseDir;
141a30a4a41SJohn Scipione				ExecCommand(cmd.c_str());
142dda17c00STyler Dauwalder			} else {
14375120765STyler Dauwalder				fMimeDirExisted = true;
144dda17c00STyler Dauwalder				if (BTestShell::GlobalBeVerbose())
145dda17c00STyler Dauwalder					cout << "(Using existing copy of MIME database in '" + mimeDatabaseDir + "')" << endl;
146dda17c00STyler Dauwalder			}
147a30a4a41SJohn Scipione		}
148dda17c00STyler Dauwalder	}
149dda17c00STyler Dauwalder
150dda17c00STyler Dauwalder	virtual void tearDown()
151dda17c00STyler Dauwalder	{
15275120765STyler Dauwalder		if (mimeDatabaseDir != R5DatabaseDir && !fMimeDirExisted) {
153dda17c00STyler Dauwalder			if (BTestShell::GlobalBeVerbose())
154dda17c00STyler Dauwalder				cout << "(Removing copy of MIME database in '" + mimeDatabaseDir + "')" << endl;
155dda17c00STyler Dauwalder			std::string cmd = std::string("rm -rf ") + mimeDatabaseDir;
156a30a4a41SJohn Scipione			ExecCommand(cmd.c_str());
157dda17c00STyler Dauwalder		}
158dda17c00STyler Dauwalder	}
159dda17c00STyler Dauwalder
160dda17c00STyler Dauwalder	virtual void run( CppUnit::TestResult *result )
161dda17c00STyler Dauwalder	{
162dda17c00STyler Dauwalder		setUp();
163dda17c00STyler Dauwalder		CppUnit::TestSuite::run(result);
164a30a4a41SJohn Scipione		tearDown();
16575120765STyler Dauwalder	}
16675120765STyler Dauwalderprivate:
16775120765STyler Dauwalder	bool fMimeDirExisted;
168dda17c00STyler Dauwalder};
169dda17c00STyler Dauwalder
17052a38012Sejakowatz// Suite
17152a38012SejakowatzCppUnit::Test*
17252a38012SejakowatzMimeTypeTest::Suite() {
173dda17c00STyler Dauwalder	MimeTypeTestSuite *suite = new MimeTypeTestSuite();
17452a38012Sejakowatz	typedef CppUnit::TestCaller<MimeTypeTest> TC;
175a30a4a41SJohn Scipione
17652a38012Sejakowatz	// Tyler
17752a38012Sejakowatz	suite->addTest( new TC("BMimeType::Install/Delete Test",
17852a38012Sejakowatz						   &MimeTypeTest::InstallDeleteTest) );
17952a38012Sejakowatz	suite->addTest( new TC("BMimeType::App Hint Test",
18052a38012Sejakowatz						   &MimeTypeTest::AppHintTest) );
18152a38012Sejakowatz	suite->addTest( new TC("BMimeType::Attribute Info Test",
18252a38012Sejakowatz						   &MimeTypeTest::AttrInfoTest) );
18352a38012Sejakowatz	suite->addTest( new TC("BMimeType::Long Description Test",
18452a38012Sejakowatz						   &MimeTypeTest::LongDescriptionTest) );
18552a38012Sejakowatz	suite->addTest( new TC("BMimeType::Short Description Test",
18652a38012Sejakowatz						   &MimeTypeTest::ShortDescriptionTest) );
18752a38012Sejakowatz	suite->addTest( new TC("BMimeType::File Extensions Test",
18852a38012Sejakowatz						   &MimeTypeTest::FileExtensionsTest) );
18952a38012Sejakowatz	suite->addTest( new TC("BMimeType::Icon Test (Large)",
19052a38012Sejakowatz						   &MimeTypeTest::LargeIconTest) );
19152a38012Sejakowatz	suite->addTest( new TC("BMimeType::Icon Test (Mini)",
19252a38012Sejakowatz						   &MimeTypeTest::MiniIconTest) );
19352a38012Sejakowatz	suite->addTest( new TC("BMimeType::Icon For Type Test (Large)",
19452a38012Sejakowatz						   &MimeTypeTest::LargeIconForTypeTest) );
19552a38012Sejakowatz	suite->addTest( new TC("BMimeType::Icon For Type Test (Mini)",
19652a38012Sejakowatz						   &MimeTypeTest::MiniIconForTypeTest) );
19752a38012Sejakowatz	suite->addTest( new TC("BMimeType::Installed Types Test",
19852a38012Sejakowatz						   &MimeTypeTest::InstalledTypesTest) );
19952a38012Sejakowatz	suite->addTest( new TC("BMimeType::Preferred App Test",
20052a38012Sejakowatz						   &MimeTypeTest::PreferredAppTest) );
201e3a2f206STyler Dauwalder	suite->addTest( new TC("BMimeType::Supporting Apps Test",
202e3a2f206STyler Dauwalder						   &MimeTypeTest::SupportingAppsTest) );
203e3a2f206STyler Dauwalder	suite->addTest( new TC("BMimeType::Supported Types Test",
204e3a2f206STyler Dauwalder						   &MimeTypeTest::SupportedTypesTest) );
20552a38012Sejakowatz	suite->addTest( new TC("BMimeType::Wildcard Apps Test",
20652a38012Sejakowatz						   &MimeTypeTest::WildcardAppsTest) );
20752a38012Sejakowatz
208a30a4a41SJohn Scipione	// Ingo
20952a38012Sejakowatz	suite->addTest( new TC("BMimeType::Initialization Test",
21052a38012Sejakowatz						   &MimeTypeTest::InitTest) );
21152a38012Sejakowatz	suite->addTest( new TC("BMimeType::MIME String Test",
21252a38012Sejakowatz						   &MimeTypeTest::StringTest) );
21352a38012Sejakowatz	suite->addTest( new TC("BMimeType::MIME Monitoring Test",
21452a38012Sejakowatz						   &MimeTypeTest::MonitoringTest) );
21552a38012Sejakowatz	suite->addTest( new TC("BMimeType::update_mime_info() Test",
21652a38012Sejakowatz						   &MimeTypeTest::UpdateMimeInfoTest) );
21752a38012Sejakowatz	suite->addTest( new TC("BMimeType::create_app_meta_mime() Test",
21852a38012Sejakowatz						   &MimeTypeTest::CreateAppMetaMimeTest) );
21952a38012Sejakowatz	suite->addTest( new TC("BMimeType::get_device_icon() Test",
22052a38012Sejakowatz						   &MimeTypeTest::GetDeviceIconTest) );
22152a38012Sejakowatz	suite->addTest( new TC("BMimeType::Sniffer Rule Test",
22252a38012Sejakowatz						   &MimeTypeTest::SnifferRuleTest) );
22352a38012Sejakowatz	suite->addTest( new TC("BMimeType::Sniffing Test",
22452a38012Sejakowatz						   &MimeTypeTest::SniffingTest) );
225a30a4a41SJohn Scipione
226a30a4a41SJohn Scipione
22752a38012Sejakowatz	return suite;
228a30a4a41SJohn Scipione}
22952a38012Sejakowatz
23052a38012Sejakowatz// Handy comparison operators for BBitmaps. The size and color depth
23152a38012Sejakowatz// are compared first, followed by the bitmap data.
23252a38012Sejakowatzbool
23352a38012Sejakowatzoperator==(BBitmap &bmp1, BBitmap &bmp2) {
23452a38012Sejakowatz	if (bmp1.Bounds() == bmp2.Bounds()) {
23552a38012Sejakowatz//		printf("bmp== 1\n");
23652a38012Sejakowatz		if (bmp1.ColorSpace() == bmp2.ColorSpace()) {
23752a38012Sejakowatz//			printf("bmp== 2\n");
23852a38012Sejakowatz			char *data1 = (char*)bmp1.Bits();
23952a38012Sejakowatz			char *data2 = (char*)bmp2.Bits();
24052a38012Sejakowatz			// NOTE! It's possible that padding bits might not get copied verbatim,
24152a38012Sejakowatz			// which could lead to unexpected failures. If things are acting weird,
24252a38012Sejakowatz			// you might try the commented out code below (keeping in mind that it
24352a38012Sejakowatz			// currently only works for 8-bit color depths).
24452a38012Sejakowatz			for (int i = 0; i < bmp1.BitsLength(); data1++, data2++, i++) {
24552a38012Sejakowatz				if (*data1 != *data2) {
24652a38012Sejakowatz//					printf("i == %d\n", i);
24752a38012Sejakowatz					return false;
24852a38012Sejakowatz				}
249a30a4a41SJohn Scipione			}
25052a38012Sejakowatz/*			for (int i = 0; i < bmp1.Bounds().IntegerHeight(); i++) {
25152a38012Sejakowatz				for (int j = 0; j < bmp1.Bounds().IntegerWidth(); j++) {
25252a38012Sejakowatz//					printf("(%d, %d)", data1[(i * bmp1.BytesPerRow()) + j], data2[(i * bmp2.BytesPerRow()) + j]);
25352a38012Sejakowatz					if (data1[(i * bmp1.BytesPerRow()) + j] != data2[(i * bmp2.BytesPerRow()) + j]) {
25452a38012Sejakowatz						printf("fail at (%d, %d)\n", j, i);
25552a38012Sejakowatz						return false;
25652a38012Sejakowatz					}
25752a38012Sejakowatz				}
25852a38012Sejakowatz			}*/
25952a38012Sejakowatz			return true;
26052a38012Sejakowatz		} else
26152a38012Sejakowatz			return false;
26252a38012Sejakowatz	} else
26352a38012Sejakowatz		return false;
26452a38012Sejakowatz}
26552a38012Sejakowatz
26652a38012Sejakowatzbool
26752a38012Sejakowatzoperator!=(BBitmap &bmp1, BBitmap &bmp2) {
26852a38012Sejakowatz	return !(bmp1 == bmp2);
26952a38012Sejakowatz}
27052a38012Sejakowatz
27152a38012Sejakowatz// Handy comparison operators for BMessages. The BMessages are checked field
27252a38012Sejakowatz// by field, each of which is verified to be identical with respect to: type,
27352a38012Sejakowatz// count, and data (all items).
27452a38012Sejakowatzbool
27552a38012Sejakowatzoperator==(BMessage &msg1, BMessage &msg2) {
27652a38012Sejakowatz	status_t err = B_OK;
277a30a4a41SJohn Scipione
27852a38012Sejakowatz	// For now I'm ignoring the what fields...I shall deal with that later :-)
27952a38012Sejakowatz	if (msg1.what != msg2.what)
28052a38012Sejakowatz		return false;
28152a38012Sejakowatz
28252a38012Sejakowatz/*
28352a38012Sejakowatz	printf("----------------------------------------------------------------------\n");
28452a38012Sejakowatz	msg1.PrintToStream();
28552a38012Sejakowatz	msg2.PrintToStream();
28652a38012Sejakowatz	printf("----------------------------------------------------------------------\n");
28752a38012Sejakowatz*/
288a30a4a41SJohn Scipione
28952a38012Sejakowatz	// Check the counts of field names
290a30a4a41SJohn Scipione	int count1, count2;
29152a38012Sejakowatz	count1 = msg1.CountNames(B_ANY_TYPE);
29252a38012Sejakowatz	count2 = msg2.CountNames(B_ANY_TYPE);
29352a38012Sejakowatz	if (count1 != count2 && (count1 == 0 || count2 == 0))
29452a38012Sejakowatz		return false;
295a30a4a41SJohn Scipione
29652a38012Sejakowatz	// Iterate over all the names in msg1 and check that the field
29752a38012Sejakowatz	// with the same name exists in msg2, is of the same type, and
29852a38012Sejakowatz	// contains identical data.
29952a38012Sejakowatz	for (int i = 0; i < count1 && !err; i++) {
30052a38012Sejakowatz		char *name;
30152a38012Sejakowatz		type_code typeFound1, typeFound2;
30252a38012Sejakowatz		int32 countFound1, countFound2;
303a30a4a41SJohn Scipione
30452a38012Sejakowatz		// Check type and count info
305a30a4a41SJohn Scipione		err = msg1.GetInfo(B_ANY_TYPE, i, &name, &typeFound1, &countFound1);
306a30a4a41SJohn Scipione		if (!err)
30752a38012Sejakowatz			err = msg2.GetInfo(name, &typeFound2, &countFound2);
308a30a4a41SJohn Scipione		if (!err)
30952a38012Sejakowatz			err = (typeFound1 == typeFound2 && countFound1 == countFound2 ? B_OK : B_ERROR);
31052a38012Sejakowatz		if (!err) {
31152a38012Sejakowatz			// Check all the data items
31252a38012Sejakowatz			for (int j = 0; j < countFound1; j++) {
31352a38012Sejakowatz				void *data1, *data2;
31452a38012Sejakowatz				ssize_t bytes1, bytes2;
315a30a4a41SJohn Scipione
31652a38012Sejakowatz				err = msg1.FindData(name, typeFound1, j, (const void**)&data1, &bytes1);
317a30a4a41SJohn Scipione				if (!err)
31852a38012Sejakowatz					err = msg2.FindData(name, typeFound2, j, (const void**)&data2, &bytes2);
319a30a4a41SJohn Scipione				if (!err)
320a30a4a41SJohn Scipione					err = (bytes1 == bytes2 && memcmp(data1, data2, bytes1) == 0 ? B_OK : B_ERROR);
32152a38012Sejakowatz			}
32252a38012Sejakowatz		}
32352a38012Sejakowatz	}
324a30a4a41SJohn Scipione
32552a38012Sejakowatz	return !err;
32652a38012Sejakowatz}
32752a38012Sejakowatz
32852a38012Sejakowatzbool
32952a38012Sejakowatzoperator!=(BMessage &msg1, BMessage &msg2) {
33052a38012Sejakowatz	return !(msg1 == msg2);
33152a38012Sejakowatz}
33252a38012Sejakowatz
33352a38012Sejakowatz// Fills the bitmap data with the given character
33452a38012Sejakowatzvoid
33552a38012Sejakowatzfill_bitmap(BBitmap &bmp, char value) {
33652a38012Sejakowatz	char *data = (char*)bmp.Bits();
33752a38012Sejakowatz	for (int i = 0; i < bmp.BitsLength(); data++, i++) {
33852a38012Sejakowatz//		printf("(%d -> ", *data);
33952a38012Sejakowatz		*data = value;
34052a38012Sejakowatz//		printf("%d)", *data);
34152a38012Sejakowatz	}
34252a38012Sejakowatz//	printf("\n");
34352a38012Sejakowatz}
344a30a4a41SJohn Scipione
3459c561e65STyler Dauwalder// Fills the bitmap data with the given character
3469c561e65STyler Dauwaldervoid
3479c561e65STyler Dauwalderfill_bitmap32(BBitmap &bmp, char r, char g, char b, char a) {
3489c561e65STyler Dauwalder	if (bmp.ColorSpace() == B_RGB32 || bmp.ColorSpace() == B_RGBA32) {
3499c561e65STyler Dauwalder		char *data = (char*)bmp.Bits();
3509c561e65STyler Dauwalder		for (int i = 0; i+3 < bmp.BitsLength(); data += 4, i+= 4) {
3519c561e65STyler Dauwalder			data[0] = b;
3529c561e65STyler Dauwalder			data[1] = g;
3539c561e65STyler Dauwalder			data[2] = r;
3549c561e65STyler Dauwalder			data[3] = a;
3559c561e65STyler Dauwalder//			printf("(%d,%d,%d,%d)", data[2], data[1], data[0], data[3]);
3569c561e65STyler Dauwalder		}
3579c561e65STyler Dauwalder//		printf("\n");
3589c561e65STyler Dauwalder	}
3599c561e65STyler Dauwalder}
360a30a4a41SJohn Scipione
36152a38012Sejakowatz// Dumps the size, colorspace, and first data byte
36252a38012Sejakowatz// of the bitmap to stdout
363f7046d77STyler Dauwalder/*void
36452a38012Sejakowatzdump_bitmap(BBitmap &bmp, char *name = "bmp") {
36552a38012Sejakowatz	printf("%s == (%ldx%ld, ", name, bmp.Bounds().IntegerWidth()+1,
36652a38012Sejakowatz		bmp.Bounds().IntegerHeight()+1);
36752a38012Sejakowatz	switch (bmp.ColorSpace()) {
36852a38012Sejakowatz		case B_CMAP8:
36952a38012Sejakowatz			printf("B_CMAP8");
37052a38012Sejakowatz			break;
371a30a4a41SJohn Scipione
3729c561e65STyler Dauwalder		case B_RGB32:
3739c561e65STyler Dauwalder			printf("B_RGB32");
3749c561e65STyler Dauwalder			break;
375a30a4a41SJohn Scipione
37652a38012Sejakowatz		case B_RGBA32:
37752a38012Sejakowatz			printf("B_RGBA32");
37852a38012Sejakowatz			break;
379a30a4a41SJohn Scipione
38052a38012Sejakowatz		default:
38152a38012Sejakowatz			printf("%x", bmp.ColorSpace());
382a30a4a41SJohn Scipione			break;
38352a38012Sejakowatz	}
3849c561e65STyler Dauwalder	printf(", %d, [", *(char*)bmp.Bits());
3859c561e65STyler Dauwalder	char *data = (char*)bmp.Bits();
3869c561e65STyler Dauwalder	for (int i = 0; i < bmp.BitsLength() && i < 20; data++, i++)
3879c561e65STyler Dauwalder		printf("%d,", *data);
3889c561e65STyler Dauwalder	printf("]\n");
389f7046d77STyler Dauwalder}*/
3909c561e65STyler Dauwalder
3919c561e65STyler Dauwalder// Uses BBitmap::SetBits() to convert the B_RGB32 bitmap in src32
3929c561e65STyler Dauwalder// to a B_CMAP8 bitmap in dest8
393f7046d77STyler Dauwalder#if !TEST_R5
3949c561e65STyler Dauwalderstatus_t
3959c561e65STyler Dauwalderreduce_color_depth(BBitmap &src32, BBitmap &dest8)
3969c561e65STyler Dauwalder{
3979c561e65STyler Dauwalder	status_t err = (src32.ColorSpace() == B_RGB32
3989c561e65STyler Dauwalder				      && dest8.ColorSpace() == B_CMAP8
3999c561e65STyler Dauwalder				        && src32.InitCheck() == B_OK
4009c561e65STyler Dauwalder				          && dest8.InitCheck() == B_OK
4019c561e65STyler Dauwalder					        && src32.Bounds() == dest8.Bounds())
4029c561e65STyler Dauwalder					          ? B_OK
4039c561e65STyler Dauwalder					            : B_BAD_VALUE;
4049c561e65STyler Dauwalder	if (!err) {
4059c561e65STyler Dauwalder		// Set each pixel individually, since SetBits() for B_RGB32 takes
4069c561e65STyler Dauwalder		// 24-bit rgb pixel data...
4079c561e65STyler Dauwalder		char *data = (char*)src32.Bits();
408f7046d77STyler Dauwalder		for (int32 i = 0; i*4+3 < src32.BitsLength(); data += 4, i++) {
4099c561e65STyler Dauwalder			char rgb[3];
4109c561e65STyler Dauwalder			rgb[0] = data[2];	// red
4119c561e65STyler Dauwalder			rgb[1] = data[1];	// green
4129c561e65STyler Dauwalder			rgb[2] = data[0];	// blue
4139c561e65STyler Dauwalder			dest8.SetBits(rgb, 3, i, B_RGB32);
4149c561e65STyler Dauwalder		}
4159c561e65STyler Dauwalder	}
4169c561e65STyler Dauwalder	return err;
4179c561e65STyler Dauwalder}
418f7046d77STyler Dauwalder#endif
419a30a4a41SJohn Scipione
42052a38012Sejakowatz// IconHelper and IconForTypeHelper:
42152a38012Sejakowatz// Adapter(?) classes needed to reuse icon tests among {Get,Set}Icon() and {Get,Set}IconForType()
42252a38012Sejakowatz// What originally were meant to encapsulate the variations among calls to the various BMimeType
42352a38012Sejakowatz// icon functions have now exploded into beefy helper classes with a bunch of BBitmap related
42452a38012Sejakowatz// functionality as well. A lot of this stuff doesn't necessarily belong
42552a38012Sejakowatz
42652a38012Sejakowatzclass IconHelper {
42752a38012Sejakowatzpublic:
42852a38012Sejakowatz	IconHelper(icon_size which)
42952a38012Sejakowatz		: bmp1(BitmapBounds(which), B_CMAP8),
43052a38012Sejakowatz		  bmp2(BitmapBounds(which), B_CMAP8),
43152a38012Sejakowatz		  bmpTemp(BitmapBounds(which), B_CMAP8),
43252a38012Sejakowatz		  size(which)
43352a38012Sejakowatz	{
43452a38012Sejakowatz		// Initialize our three bitmaps to different "colors"
43552a38012Sejakowatz		fill_bitmap(bmp1, 1);
43652a38012Sejakowatz		fill_bitmap(bmp2, 2);
43752a38012Sejakowatz		fill_bitmap(bmpTemp, 3);
43852a38012Sejakowatz	}
43952a38012Sejakowatz
44052a38012Sejakowatz	virtual ~IconHelper() {}
44152a38012Sejakowatz
44252a38012Sejakowatz	// Returns the proper bitmap bounds for the given icon size
44352a38012Sejakowatz	BRect BitmapBounds(icon_size isize) {
44452a38012Sejakowatz		return isize == B_LARGE_ICON ? BRect(0,0,31,31) : BRect(0,0,15,15);
44552a38012Sejakowatz	}
446a30a4a41SJohn Scipione
44752a38012Sejakowatz	// Returns the proper bitmap bounds for this helper's icon size
44852a38012Sejakowatz	BRect BitmapBounds() {
44952a38012Sejakowatz		return BitmapBounds(size);
450a30a4a41SJohn Scipione	}
451a30a4a41SJohn Scipione
45252a38012Sejakowatz	// Used to call the appropriate GetIcon[ForType] function
45352a38012Sejakowatz	virtual status_t GetIcon(BMimeType &mime, BBitmap *icon) {
45452a38012Sejakowatz		return mime.GetIcon(icon, size);
45552a38012Sejakowatz	}
45652a38012Sejakowatz
45752a38012Sejakowatz	// Used to call the appropriate SetIcon[ForType] function
45852a38012Sejakowatz	virtual status_t SetIcon(BMimeType &mime, BBitmap *icon) {
45952a38012Sejakowatz		return mime.SetIcon(icon, size);
46052a38012Sejakowatz	}
461a30a4a41SJohn Scipione
462dd0ba994STyler Dauwalder	// Used to call the appropriate DeleteIcon[ForType] function
463dd0ba994STyler Dauwalder	virtual status_t DeleteIcon(BMimeType &mime) {
464dd0ba994STyler Dauwalder#if TEST_R5
465dd0ba994STyler Dauwalder		return B_BAD_VALUE;
466dd0ba994STyler Dauwalder#else
467dd0ba994STyler Dauwalder		return mime.DeleteIcon(size);
468dd0ba994STyler Dauwalder#endif
469dd0ba994STyler Dauwalder	}
470a30a4a41SJohn Scipione
47152a38012Sejakowatz	BBitmap* TempBitmap() {
47252a38012Sejakowatz		return &bmpTemp;
47352a38012Sejakowatz	}
474a30a4a41SJohn Scipione
47552a38012Sejakowatz	BBitmap* Bitmap1() {
47652a38012Sejakowatz		return &bmp1;
47752a38012Sejakowatz	}
478a30a4a41SJohn Scipione
47952a38012Sejakowatz	BBitmap* Bitmap2() {
48052a38012Sejakowatz		return &bmp2;
48152a38012Sejakowatz	}
482a30a4a41SJohn Scipione
48352a38012Sejakowatz	icon_size Size() {
48452a38012Sejakowatz		return size;
48552a38012Sejakowatz	}
486a30a4a41SJohn Scipione
487a30a4a41SJohn Scipioneprotected:
48852a38012Sejakowatz	BBitmap bmp1;
48952a38012Sejakowatz	BBitmap bmp2;
49052a38012Sejakowatz	BBitmap bmpTemp;
491a30a4a41SJohn Scipione	icon_size size;
49252a38012Sejakowatz};
49352a38012Sejakowatz
49452a38012Sejakowatzclass IconForTypeHelper : public IconHelper {
49552a38012Sejakowatzpublic:
49652a38012Sejakowatz	IconForTypeHelper(const char *fileType, icon_size which)
49752a38012Sejakowatz		: IconHelper(which), fileType(fileType) {}
49852a38012Sejakowatz	virtual ~IconForTypeHelper() {}
49952a38012Sejakowatz	virtual status_t GetIcon(BMimeType &mime, BBitmap *icon) {
50052a38012Sejakowatz		return mime.GetIconForType(fileType.c_str(), icon, size);
50152a38012Sejakowatz	}
50252a38012Sejakowatz	virtual status_t SetIcon(BMimeType &mime, BBitmap *icon) {
50352a38012Sejakowatz		return mime.SetIconForType(fileType.c_str(), icon, size);
50452a38012Sejakowatz	}
505dd0ba994STyler Dauwalder	virtual status_t DeleteIcon(BMimeType &mime) {
506dd0ba994STyler Dauwalder#if TEST_R5
507dd0ba994STyler Dauwalder		return B_BAD_VALUE;
508dd0ba994STyler Dauwalder#else
509dd0ba994STyler Dauwalder		return mime.DeleteIconForType(fileType.c_str(), size);
510dd0ba994STyler Dauwalder#endif
511dd0ba994STyler Dauwalder	}
51252a38012Sejakowatzprotected:
51352a38012Sejakowatz	std::string fileType;
51452a38012Sejakowatz};
51552a38012Sejakowatz
516762a48a0STyler Dauwalder// Adapter classes used by FillWithMimeTypes() to facilitate
517762a48a0STyler Dauwalder// addition of strings to containers with varying interfaces
518762a48a0STyler Dauwalderclass ContainerAdapter {
519762a48a0STyler Dauwalderpublic:
520762a48a0STyler Dauwalder	virtual void Add(std::string value) = 0;
521762a48a0STyler Dauwalder};
522762a48a0STyler Dauwalder
523762a48a0STyler Dauwalderclass SetAdapter : public ContainerAdapter {
524762a48a0STyler Dauwalderpublic:
525762a48a0STyler Dauwalder	SetAdapter(std::set<std::string> &set)
526762a48a0STyler Dauwalder		: fSet(set) { }
527762a48a0STyler Dauwalder	virtual void Add(std::string value) {
528a30a4a41SJohn Scipione		fSet.insert(value);
529762a48a0STyler Dauwalder	}
530762a48a0STyler Dauwalderprotected:
531762a48a0STyler Dauwalder	std::set<std::string> &fSet;
532762a48a0STyler Dauwalder};
533a30a4a41SJohn Scipione
534762a48a0STyler Dauwalderclass QueueAdapter : public ContainerAdapter {
535762a48a0STyler Dauwalderpublic:
536762a48a0STyler Dauwalder	QueueAdapter(std::queue<std::string> &queue)
537762a48a0STyler Dauwalder		: fQueue(queue) { }
538762a48a0STyler Dauwalder	virtual void Add(std::string value) {
539a30a4a41SJohn Scipione		fQueue.push(value);
540762a48a0STyler Dauwalder	}
541762a48a0STyler Dauwalderprotected:
542762a48a0STyler Dauwalder	std::queue<std::string> &fQueue;
543762a48a0STyler Dauwalder};
544762a48a0STyler Dauwalder
545762a48a0STyler Dauwalder
54652a38012Sejakowatz// setUp
54752a38012Sejakowatzvoid
54852a38012SejakowatzMimeTypeTest::setUp()
54952a38012Sejakowatz{
55052a38012Sejakowatz	BasicTest::setUp();
55152a38012Sejakowatz	execCommand(string("mkdir ") + testDir);
55252a38012Sejakowatz/*	// Better not to play with fire, so we'll make a copy of the
55352a38012Sejakowatz	// local mime database which we'll use for certain OpenBeOS tests
55452a38012Sejakowatz	execCommand(string("mkdir ") + testDir
55552a38012Sejakowatz				+ " ; copyattr -d -r -- " + mimeDatabaseDir + "/\* " + testDir
556a30a4a41SJohn Scipione				); */
55752a38012Sejakowatz	// Setup our application
558762a48a0STyler Dauwalder	fApplication = new BTestApp(testSig);
55952a38012Sejakowatz	if (fApplication->Init() != B_OK) {
56052a38012Sejakowatz		fprintf(stderr, "Failed to initialize application.\n");
56152a38012Sejakowatz		delete fApplication;
56252a38012Sejakowatz		fApplication = NULL;
56352a38012Sejakowatz	}
564a30a4a41SJohn Scipione
56552a38012Sejakowatz}
566a30a4a41SJohn Scipione
56752a38012Sejakowatz// tearDown
56852a38012Sejakowatzvoid
56952a38012SejakowatzMimeTypeTest::tearDown()
57052a38012Sejakowatz{
57152a38012Sejakowatz	execCommand(string("rm -rf ") + testDir);
57252a38012Sejakowatz
57352a38012Sejakowatz	// Uninistall our test type
57452a38012Sejakowatz	//! /todo Uncomment the following uninstall code when all is said and done.
57552a38012Sejakowatz/*	BMimeType mime(testType);
57652a38012Sejakowatz	status_t err = mime.InitCheck();
57752a38012Sejakowatz	if (!err && mime.IsInstalled())
57852a38012Sejakowatz		err = mime.Delete();
57952a38012Sejakowatz	if (err)
58052a38012Sejakowatz		fprintf(stderr, "Failed to unistall test type \"%s\"\n", testType); */
58152a38012Sejakowatz	// Terminate the Application
58252a38012Sejakowatz	if (fApplication) {
58352a38012Sejakowatz		fApplication->Terminate();
58452a38012Sejakowatz		delete fApplication;
58552a38012Sejakowatz		fApplication = NULL;
58652a38012Sejakowatz	}
58752a38012Sejakowatz	// remove the types we've added
58852a38012Sejakowatz	const char * const testTypes[] = {
58952a38012Sejakowatz		testType, testType1, testType2, testType3, testType4, testType5,
59052a38012Sejakowatz		testTypeApp, testTypeApp1, testTypeApp2, testTypeApp3,
59152a38012Sejakowatz	};
59252a38012Sejakowatz	for (uint32 i = 0; i < sizeof(testTypes) / sizeof(const char*); i++) {
59352a38012Sejakowatz		BMimeType type(testTypes[i]);
59452a38012Sejakowatz		type.Delete();
59552a38012Sejakowatz	}
59652a38012Sejakowatz	BasicTest::tearDown();
59752a38012Sejakowatz}
59852a38012Sejakowatz
59952a38012Sejakowatz// entry_ref dumping function ; this may be removed at any time
60052a38012Sejakowatz
60152a38012Sejakowatz/*void
60252a38012Sejakowatzdump_ref(entry_ref *ref, char* name = "ref") {
60352a38012Sejakowatz	if (ref) {
60452a38012Sejakowatz		BPath path(ref);
60552a38012Sejakowatz		status_t err = path.InitCheck();
60652a38012Sejakowatz		if (!err) {
60752a38012Sejakowatz			printf("%s == '%s'", name, path.Path());
60852a38012Sejakowatz		} else
60952a38012Sejakowatz			printf("%s == ERROR", name);
61052a38012Sejakowatz		printf(" == (%ld, %Ld, '%s')\n", ref->device, ref->directory, ref->name);
611a30a4a41SJohn Scipione
61252a38012Sejakowatz	} else
61352a38012Sejakowatz		printf("%s == (NULL)\n", name);
61452a38012Sejakowatz}*/
615a30a4a41SJohn Scipione
61652a38012Sejakowatz// App Hint
61752a38012Sejakowatz
61852a38012Sejakowatzvoid
61952a38012SejakowatzMimeTypeTest::AppHintTest() {
62052a38012Sejakowatz	// init a couple of entry_refs to applications
62152a38012Sejakowatz	BEntry entry(testApp);
62252a38012Sejakowatz	entry_ref appRef;
62352a38012Sejakowatz	CHK(entry.InitCheck() == B_OK);
624a30a4a41SJohn Scipione	CHK(entry.GetRef(&appRef) == B_OK);
62552a38012Sejakowatz	BEntry entry2(testApp2);
62652a38012Sejakowatz	entry_ref appRef2;
62752a38012Sejakowatz	CHK(entry2.InitCheck() == B_OK);
628a30a4a41SJohn Scipione	CHK(entry2.GetRef(&appRef2) == B_OK);
62952a38012Sejakowatz	// Uninitialized
630aad997bdSTyler Dauwalder	NextSubTest();
63152a38012Sejakowatz	{
63252a38012Sejakowatz		BMimeType mime;
63352a38012Sejakowatz		entry_ref ref;
63452a38012Sejakowatz		CHK(mime.InitCheck() == B_NO_INIT);
63552a38012Sejakowatz		CHK(mime.GetAppHint(&ref) != B_OK);		// R5 == B_BAD_VALUE
63652a38012Sejakowatz		CHK(mime.SetAppHint(&ref) != B_OK);		// R5 == B_BAD_VALUE
63752a38012Sejakowatz	}
63852a38012Sejakowatz	// NULL params
639aad997bdSTyler Dauwalder	NextSubTest();
64052a38012Sejakowatz	{
64152a38012Sejakowatz		entry_ref ref;
64252a38012Sejakowatz		BMimeType mime(testType);
64352a38012Sejakowatz		CHK(mime.InitCheck() == B_OK);
64452a38012Sejakowatz		// Make sure the type isn't installed
64552a38012Sejakowatz		if (mime.IsInstalled())
64652a38012Sejakowatz			CHK(mime.Delete() == B_OK);
647dd0ba994STyler Dauwalder#if TEST_R5
64852a38012Sejakowatz		CHK(!mime.IsInstalled());
64952a38012Sejakowatz		CHK(mime.GetAppHint(NULL) != B_OK);		// R5 == B_BAD_VALUE
65052a38012Sejakowatz		CHK(!mime.IsInstalled());
65152a38012Sejakowatz		CHK(mime.SetAppHint(NULL) != B_OK);		// Installs, R5 == B_ENTRY_NOT_FOUND
65252a38012Sejakowatz		CHK(mime.IsInstalled());
653dd0ba994STyler Dauwalder		CHK(mime.GetAppHint(NULL) != B_OK);		// R5 == B_BAD_VALUE
654dd0ba994STyler Dauwalder		CHK(mime.SetAppHint(NULL) != B_OK);		// R5 == B_ENTRY_NOT_FOUND
6559c561e65STyler Dauwalder#else
6569c561e65STyler Dauwalder		CHK(!mime.IsInstalled());
657dd0ba994STyler Dauwalder		CHK(mime.GetAppHint(NULL) != B_OK);		// B_BAD_VALUE
658dd0ba994STyler Dauwalder		CHK(!mime.IsInstalled());
659dd0ba994STyler Dauwalder		CHK(mime.SetAppHint(NULL) != B_OK);		// B_ENTRY_NOT_FOUND
660dd0ba994STyler Dauwalder		CHK(!mime.IsInstalled());
661dd0ba994STyler Dauwalder		CHK(mime.SetAppHint(&appRef) == B_OK);
662dd0ba994STyler Dauwalder		CHK(mime.IsInstalled());
663a30a4a41SJohn Scipione		CHK(mime.GetAppHint(&ref) == B_OK);
664dd0ba994STyler Dauwalder		CHK(ref == appRef);
665a30a4a41SJohn Scipione		CHK(mime.SetAppHint(NULL) == B_OK);
666dd0ba994STyler Dauwalder		CHK(mime.IsInstalled());
667dd0ba994STyler Dauwalder		CHK(mime.GetAppHint(&ref) != B_OK);		// B_ENTRY_NOT_FOUND
668dd0ba994STyler Dauwalder#endif
669dd0ba994STyler Dauwalder	}
670dd0ba994STyler Dauwalder	// Delete test
671dd0ba994STyler Dauwalder	NextSubTest();
672dd0ba994STyler Dauwalder	{
673dd0ba994STyler Dauwalder#if !TEST_R5
674dd0ba994STyler Dauwalder		entry_ref ref;
675dd0ba994STyler Dauwalder		BMimeType mime(testType);
676dd0ba994STyler Dauwalder		CHK(mime.InitCheck() == B_OK);
677dd0ba994STyler Dauwalder		// Make sure the type isn't installed
678dd0ba994STyler Dauwalder		if (mime.IsInstalled())
679dd0ba994STyler Dauwalder			CHK(mime.Delete() == B_OK);
680dd0ba994STyler Dauwalder		CHK(!mime.IsInstalled());
681a30a4a41SJohn Scipione		CHK(mime.DeleteAppHint() != B_OK);
682dd0ba994STyler Dauwalder		CHK(!mime.IsInstalled());
683dd0ba994STyler Dauwalder		CHK(mime.SetAppHint(&appRef) == B_OK);
684dd0ba994STyler Dauwalder		CHK(mime.IsInstalled());
685a30a4a41SJohn Scipione		CHK(mime.GetAppHint(&ref) == B_OK);
686dd0ba994STyler Dauwalder		CHK(ref == appRef);
687a30a4a41SJohn Scipione		CHK(mime.DeleteAppHint() == B_OK);
688dd0ba994STyler Dauwalder		CHK(mime.IsInstalled());
689a30a4a41SJohn Scipione		CHK(mime.GetAppHint(&ref) != B_OK);
6909c561e65STyler Dauwalder#endif
69152a38012Sejakowatz	}
69252a38012Sejakowatz	// Non-installed type
693aad997bdSTyler Dauwalder	NextSubTest();
69452a38012Sejakowatz	{
69552a38012Sejakowatz		entry_ref ref;
69652a38012Sejakowatz		BMimeType mime(testType);
69752a38012Sejakowatz		CHK(mime.InitCheck() == B_OK);
69852a38012Sejakowatz		// Make sure the type isn't installed
69952a38012Sejakowatz		if (mime.IsInstalled())
70052a38012Sejakowatz			CHK(mime.Delete() == B_OK);
70152a38012Sejakowatz		CHK(!mime.IsInstalled());
70252a38012Sejakowatz		CHK(mime.GetAppHint(&ref) != B_OK);		// R5 == B_ENTRY_NOT_FOUND
70352a38012Sejakowatz		CHK(!mime.IsInstalled());
70452a38012Sejakowatz		CHK(mime.SetAppHint(&appRef) == B_OK);
70552a38012Sejakowatz		CHK(mime.IsInstalled());
70652a38012Sejakowatz		CHK(mime.GetAppHint(&ref) == B_OK);
70752a38012Sejakowatz		CHK(ref == appRef);
70852a38012Sejakowatz	}
70952a38012Sejakowatz	// Installed Type
710aad997bdSTyler Dauwalder	NextSubTest();
71152a38012Sejakowatz	{
71252a38012Sejakowatz		entry_ref ref;
71352a38012Sejakowatz		BMimeType mime(testType);
71452a38012Sejakowatz		CHK(mime.InitCheck() == B_OK);
71552a38012Sejakowatz		// Uninstall then reinstall to clear attributes
71652a38012Sejakowatz		if (mime.IsInstalled())
71752a38012Sejakowatz			CHK(mime.Delete() == B_OK);
71852a38012Sejakowatz		if (!mime.IsInstalled())
71952a38012Sejakowatz			CHK(mime.Install() == B_OK);
72052a38012Sejakowatz		CHK(mime.IsInstalled());
72152a38012Sejakowatz		// Get() with no apphint installed
72252a38012Sejakowatz		CHK(mime.GetAppHint(&ref) == B_ENTRY_NOT_FOUND);
72352a38012Sejakowatz		// Initial Set()/Get()
72452a38012Sejakowatz		CHK(mime.SetAppHint(&appRef) == B_OK);
72552a38012Sejakowatz		CHK(mime.GetAppHint(&ref) == B_OK);
72652a38012Sejakowatz		CHK(ref == appRef);
72752a38012Sejakowatz		// Followup Set()/Get()
72852a38012Sejakowatz		CHK(mime.SetAppHint(&appRef2) == B_OK);
72952a38012Sejakowatz		CHK(mime.GetAppHint(&ref) == B_OK);
73052a38012Sejakowatz		CHK(ref == appRef2);
73152a38012Sejakowatz		CHK(ref != appRef);
73252a38012Sejakowatz	}
73352a38012Sejakowatz	// Installed Type, invalid entry_ref
734aad997bdSTyler Dauwalder	NextSubTest();
73552a38012Sejakowatz	{
73652a38012Sejakowatz		entry_ref ref(-1, -1, NULL);
73752a38012Sejakowatz		BMimeType mime(testType);
738a30a4a41SJohn Scipione		CHK(mime.InitCheck() == B_OK);
73952a38012Sejakowatz		// Uninstall then reinstall to clear attributes
74052a38012Sejakowatz		if (mime.IsInstalled())
74152a38012Sejakowatz			CHK(mime.Delete() == B_OK);
74252a38012Sejakowatz		if (!mime.IsInstalled())
74352a38012Sejakowatz			CHK(mime.Install() == B_OK);
744a30a4a41SJohn Scipione		CHK(mime.IsInstalled());
74552a38012Sejakowatz		CHK(mime.SetAppHint(&appRef) == B_OK);
74652a38012Sejakowatz		CHK(mime.SetAppHint(&ref) != B_OK);	// R5 == B_BAD_VALUE
74752a38012Sejakowatz	}
74852a38012Sejakowatz	// Installed Type, fake/invalid entry_ref
749aad997bdSTyler Dauwalder	NextSubTest();
75052a38012Sejakowatz	{
75152a38012Sejakowatz		entry_ref ref(0, 0, "__this_ought_not_exist__");
75252a38012Sejakowatz		BMimeType mime(testType);
753a30a4a41SJohn Scipione		CHK(mime.InitCheck() == B_OK);
75452a38012Sejakowatz		// Uninstall then reinstall to clear attributes
75552a38012Sejakowatz		if (mime.IsInstalled())
75652a38012Sejakowatz			CHK(mime.Delete() == B_OK);
75752a38012Sejakowatz		if (!mime.IsInstalled())
758a30a4a41SJohn Scipione			CHK(mime.Install() == B_OK);
759a30a4a41SJohn Scipione		CHK(mime.IsInstalled());
76052a38012Sejakowatz		CHK(mime.SetAppHint(&appRef) == B_OK);
76152a38012Sejakowatz		CHK(mime.SetAppHint(&ref) != B_OK);	// R5 == B_ENTRY_NOT_FOUND
762a30a4a41SJohn Scipione	}
76352a38012Sejakowatz	// Installed Type, abstract entry_ref
764aad997bdSTyler Dauwalder	NextSubTest();
76552a38012Sejakowatz	{
76652a38012Sejakowatz		entry_ref fakeRef;
76752a38012Sejakowatz		entry_ref ref;
76852a38012Sejakowatz		BEntry entry(fakeTestApp);
76952a38012Sejakowatz		CHK(entry.InitCheck() == B_OK);
77052a38012Sejakowatz		CHK(!entry.Exists());
77152a38012Sejakowatz		CHK(entry.GetRef(&fakeRef) == B_OK);
77252a38012Sejakowatz		BMimeType mime(testType);
773a30a4a41SJohn Scipione		CHK(mime.InitCheck() == B_OK);
77452a38012Sejakowatz		// Uninstall then reinstall to clear attributes
77552a38012Sejakowatz		if (mime.IsInstalled())
77652a38012Sejakowatz			CHK(mime.Delete() == B_OK);
77752a38012Sejakowatz		if (!mime.IsInstalled())
778a30a4a41SJohn Scipione			CHK(mime.Install() == B_OK);
779a30a4a41SJohn Scipione		CHK(mime.IsInstalled());
78052a38012Sejakowatz		CHK(mime.SetAppHint(&appRef) == B_OK);
78152a38012Sejakowatz		CHK(mime.SetAppHint(&fakeRef) == B_OK);
78252a38012Sejakowatz		CHK(mime.GetAppHint(&ref) == B_OK);
78352a38012Sejakowatz		CHK(ref == fakeRef);
78452a38012Sejakowatz		CHK(ref != appRef);
785a30a4a41SJohn Scipione	}
78652a38012Sejakowatz}
78752a38012Sejakowatz
78852a38012Sejakowatz// Attr Info
78952a38012Sejakowatz
79052a38012Sejakowatzvoid
79152a38012SejakowatzMimeTypeTest::AttrInfoTest() {
79252a38012Sejakowatz	// Create some messages to sling around
79352a38012Sejakowatz	const int32 WHAT = 233;	// This is the what value that GAI() returns...not sure if it has a name yet
79452a38012Sejakowatz	BMessage msg1(WHAT), msg2(WHAT), msg3(WHAT), msgIncomplete1(WHAT), msgIncomplete2(WHAT);
79552a38012Sejakowatz
79652a38012Sejakowatz	CHK(msg1.AddString(attrInfoField_Name, "Color") == B_OK);
79752a38012Sejakowatz	CHK(msg1.AddString(attrInfoField_PublicName, "The Color") == B_OK);
79852a38012Sejakowatz	CHK(msg1.AddInt32(attrInfoField_Type, B_STRING_TYPE) == B_OK);
79952a38012Sejakowatz	CHK(msg1.AddBool(attrInfoField_Viewable, true) == B_OK);
80052a38012Sejakowatz	CHK(msg1.AddBool(attrInfoField_Editable, true) == B_OK);
80152a38012Sejakowatz
80252a38012Sejakowatz	CHK(msg1.AddString(attrInfoField_Name, "High Score") == B_OK);
80352a38012Sejakowatz	CHK(msg1.AddString(attrInfoField_PublicName, "The Highest Score Ever") == B_OK);
80452a38012Sejakowatz	CHK(msg1.AddInt32(attrInfoField_Type, B_INT32_TYPE) == B_OK);
80552a38012Sejakowatz	CHK(msg1.AddBool(attrInfoField_Viewable, false) == B_OK);
80652a38012Sejakowatz	CHK(msg1.AddBool(attrInfoField_Editable, false) == B_OK);
80752a38012Sejakowatz
80852a38012Sejakowatz	CHK(msg2.AddString(attrInfoField_Name, "Volume") == B_OK);
80952a38012Sejakowatz	CHK(msg2.AddString(attrInfoField_PublicName, "Loudness") == B_OK);
81052a38012Sejakowatz	CHK(msg2.AddInt32(attrInfoField_Type, B_DOUBLE_TYPE) == B_OK);
81152a38012Sejakowatz	CHK(msg2.AddBool(attrInfoField_Viewable, true) == B_OK);
81252a38012Sejakowatz	CHK(msg2.AddBool(attrInfoField_Editable, true) == B_OK);
813a30a4a41SJohn Scipione
81452a38012Sejakowatz	CHK(msg3.AddString(attrInfoField_Name, "Volume") == B_OK);
81552a38012Sejakowatz	CHK(msg3.AddString(attrInfoField_PublicName, "Loudness") == B_OK);
81652a38012Sejakowatz	CHK(msg3.AddInt32(attrInfoField_Type, B_DOUBLE_TYPE) == B_OK);
81752a38012Sejakowatz	CHK(msg3.AddBool(attrInfoField_Viewable, true) == B_OK);
81852a38012Sejakowatz	CHK(msg3.AddBool(attrInfoField_Editable, true) == B_OK);
819a30a4a41SJohn Scipione
82052a38012Sejakowatz	CHK(msgIncomplete1.AddString(attrInfoField_Name, "Color") == B_OK);
82152a38012Sejakowatz	CHK(msgIncomplete1.AddString(attrInfoField_PublicName, "The Color") == B_OK);
82252a38012Sejakowatz	CHK(msgIncomplete1.AddInt32(attrInfoField_Type, B_STRING_TYPE) == B_OK);
82352a38012Sejakowatz	CHK(msgIncomplete1.AddBool(attrInfoField_Viewable, true) == B_OK);
82452a38012Sejakowatz	CHK(msgIncomplete1.AddBool(attrInfoField_Editable, true) == B_OK);
82552a38012Sejakowatz
82652a38012Sejakowatz	CHK(msgIncomplete1.AddString(attrInfoField_Name, "High Score") == B_OK);
82752a38012Sejakowatz//	CHK(msgIncomplete1.AddString(attrInfoField_PublicName, "The Highest Score Ever") == B_OK);
82852a38012Sejakowatz	CHK(msgIncomplete1.AddInt32(attrInfoField_Type, B_INT32_TYPE) == B_OK);
82952a38012Sejakowatz//	CHK(msgIncomplete1.AddBool(attrInfoField_Viewable, false) == B_OK);
83052a38012Sejakowatz	CHK(msgIncomplete1.AddBool(attrInfoField_Editable, false) == B_OK);
831a30a4a41SJohn Scipione
83252a38012Sejakowatz	CHK(msgIncomplete2.AddString(attrInfoField_Name, "Color") == B_OK);
83352a38012Sejakowatz//	CHK(msgIncomplete2.AddString(attrInfoField_PublicName, "The Color") == B_OK);
83452a38012Sejakowatz//	CHK(msgIncomplete2.AddInt32(attrInfoField_Type, B_STRING_TYPE) == B_OK);
83552a38012Sejakowatz//	CHK(msgIncomplete2.AddBool(attrInfoField_Viewable, true) == B_OK);
83652a38012Sejakowatz	CHK(msgIncomplete2.AddBool(attrInfoField_Editable, true) == B_OK);
83752a38012Sejakowatz
83852a38012Sejakowatz	CHK(msg1 == msg1);
83952a38012Sejakowatz	CHK(msg2 == msg2);
84052a38012Sejakowatz	CHK(msg3 == msg3);
84152a38012Sejakowatz	CHK(msg1 != msg2);
84252a38012Sejakowatz	CHK(msg1 != msg3);
84352a38012Sejakowatz	CHK(msg2 == msg3);
84452a38012Sejakowatz
84552a38012Sejakowatz	// Uninitialized
846aad997bdSTyler Dauwalder	NextSubTest();
84752a38012Sejakowatz	{
84852a38012Sejakowatz		BMimeType mime;
84952a38012Sejakowatz		BMessage msg;
850a30a4a41SJohn Scipione
85152a38012Sejakowatz		CHK(mime.InitCheck() == B_NO_INIT);
85252a38012Sejakowatz		CHK(mime.GetAttrInfo(&msg) != B_OK);		// R5 == B_BAD_VALUE
85352a38012Sejakowatz		CHK(mime.SetAttrInfo(&msg) != B_OK);		// R5 == B_BAD_VALUE
85452a38012Sejakowatz	}
855a30a4a41SJohn Scipione
85652a38012Sejakowatz	// NULL params
857aad997bdSTyler Dauwalder	NextSubTest();
85852a38012Sejakowatz	{
8593155eae2STyler Dauwalder#if !TEST_R5
86052a38012Sejakowatz		BMessage msg;
8613155eae2STyler Dauwalder		BMimeType mime(testType);
86252a38012Sejakowatz		CHK(mime.InitCheck() == B_OK);
86352a38012Sejakowatz		// Make sure the type isn't installed
86452a38012Sejakowatz		if (mime.IsInstalled())
86552a38012Sejakowatz			CHK(mime.Delete() == B_OK);
86652a38012Sejakowatz		CHK(!mime.IsInstalled());
867a30a4a41SJohn Scipione		CHK(mime.DeleteAttrInfo() != B_OK);
86852a38012Sejakowatz		CHK(!mime.IsInstalled());
8693155eae2STyler Dauwalder		msg1.RemoveName(typeField);						// Clear "type" field, since SAI() just adds another
8703155eae2STyler Dauwalder		CHK(mime.SetAttrInfo(&msg1) == B_OK);
87152a38012Sejakowatz		CHK(mime.IsInstalled());
8723155eae2STyler Dauwalder		CHK(msg != msg1);
873a30a4a41SJohn Scipione		CHK(mime.GetAttrInfo(&msg) == B_OK);
8743155eae2STyler Dauwalder		CHK(msg1.AddString(typeField, testType) == B_OK);	// Add in "type" field as GAI() does
8753155eae2STyler Dauwalder		CHK(msg == msg1);
876a30a4a41SJohn Scipione		CHK(mime.SetAttrInfo(NULL) == B_OK);
8773155eae2STyler Dauwalder		CHK(mime.IsInstalled());
878a30a4a41SJohn Scipione		CHK(mime.GetAttrInfo(&msg) != B_OK);
8793155eae2STyler Dauwalder#endif
8803155eae2STyler Dauwalder	}
8813155eae2STyler Dauwalder	// Delete test
8823155eae2STyler Dauwalder	NextSubTest();
8833155eae2STyler Dauwalder	{
884aad997bdSTyler Dauwalder#if !TEST_R5
8853155eae2STyler Dauwalder		BMessage msg;
8863155eae2STyler Dauwalder		BMimeType mime(testType);
8873155eae2STyler Dauwalder		CHK(mime.InitCheck() == B_OK);
8883155eae2STyler Dauwalder		// Make sure the type isn't installed
8893155eae2STyler Dauwalder		if (mime.IsInstalled())
8903155eae2STyler Dauwalder			CHK(mime.Delete() == B_OK);
8913155eae2STyler Dauwalder		CHK(!mime.IsInstalled());
892a30a4a41SJohn Scipione		CHK(mime.DeleteAttrInfo() != B_OK);
8933155eae2STyler Dauwalder		CHK(!mime.IsInstalled());
8943155eae2STyler Dauwalder		msg1.RemoveName(typeField);						// Clear "type" field, since SAI() just adds another
8953155eae2STyler Dauwalder		CHK(mime.SetAttrInfo(&msg1) == B_OK);
8963155eae2STyler Dauwalder		CHK(mime.IsInstalled());
8973155eae2STyler Dauwalder		CHK(msg != msg1);
898a30a4a41SJohn Scipione		CHK(mime.GetAttrInfo(&msg) == B_OK);
8993155eae2STyler Dauwalder		CHK(msg1.AddString(typeField, testType) == B_OK);	// Add in "type" field as GAI() does
9003155eae2STyler Dauwalder		CHK(msg == msg1);
901a30a4a41SJohn Scipione		CHK(mime.DeleteAttrInfo() == B_OK);
9023155eae2STyler Dauwalder		CHK(mime.IsInstalled());
903a30a4a41SJohn Scipione		CHK(mime.GetAttrInfo(&msg) != B_OK);
90452a38012Sejakowatz#endif
90552a38012Sejakowatz	}
906a30a4a41SJohn Scipione
90752a38012Sejakowatz	// Improperly formatted BMessages
908aad997bdSTyler Dauwalder	NextSubTest();
90952a38012Sejakowatz	{
91052a38012Sejakowatz		BMessage msg(WHAT);
91152a38012Sejakowatz		BMimeType mime(testType);
91252a38012Sejakowatz		CHK(mime.InitCheck() == B_OK);
913a30a4a41SJohn Scipione
91452a38012Sejakowatz		// Uninstall then reinstall to clear attributes
91552a38012Sejakowatz		if (mime.IsInstalled())
91652a38012Sejakowatz			CHK(mime.Delete() == B_OK);
91752a38012Sejakowatz		if (!mime.IsInstalled())
918a30a4a41SJohn Scipione			CHK(mime.Install() == B_OK);
91952a38012Sejakowatz		CHK(mime.IsInstalled());
92052a38012Sejakowatz
92152a38012Sejakowatz		// Initial Set()/Get()
92252a38012Sejakowatz		msgIncomplete1.RemoveName(typeField);		// Clear "type" fields, since SAI() just adds another
923