/* ***************************************************************************************** * * * COPYRIGHT: * * (C) Copyright Taligent, Inc., 1997 * * (C) Copyright International Business Machines Corporation, 1997-1998 * * Licensed Material - Program-Property of IBM - All Rights Reserved. * * US Government Users Restricted Rights - Use, duplication, or disclosure * * restricted by GSA ADP Schedule Contract with IBM Corp. * * * ***************************************************************************************** */ #include "restest.h" #include "resbund.h" #include "unistr.h" #include #include #include #define RESTEST_HEAP_CHECK 0 #if defined(_WIN32) && !defined(__WINDOWS__) #define _CRTDBG_MAP_ALLOC #include #endif //*************************************************************************************** const UnicodeString kERROR = "ERROR"; const int32_t kERROR_COUNT = -1234567; //*************************************************************************************** enum E_Where { e_Default, e_te, e_te_IN, e_Where_count }; //*************************************************************************************** #define CONFIRM_EQ(actual,expected) if ((expected)==(actual)) { record_pass(); } else { record_fail(); OUT << action << " returned " << (actual) << " instead of " << (expected) << endl; pass=FALSE; } #define CONFIRM_GE(actual,expected) if ((actual)>=(expected)) { record_pass(); } else { record_fail(); OUT << action << " returned " << (actual) << " instead of x >= " << (expected) << endl; pass=FALSE; } #define CONFIRM_NE(actual,expected) if ((expected)!=(actual)) { record_pass(); } else { record_fail(); OUT << action << " returned " << (actual) << " instead of x != " << (expected) << endl; pass=FALSE; } #ifdef _DEBUG #define CONFIRM_UErrorCode(actual,expected) if ((expected)==(actual)) { record_pass(); } else { record_fail(); OUT << action << " returned " << errorName(actual) << " instead of " << errorName(expected) << endl; pass=FALSE; } #else #define CONFIRM_UErrorCode(actual,expected) if ((expected)==(actual)) { record_pass(); } else { record_fail(); OUT << action << " returned " << actual << " instead of " << expected << endl; pass=FALSE; } #endif //*************************************************************************************** /** * Convert an integer, positive or negative, to a character string radix 10. */ char* itoa(int32_t i, char* buf) { char* result = buf; // Handle negative if (i < 0) { *buf++ = '-'; i = -i; } // Output digits in reverse order char* p = buf; do { *p++ = '0' + (i % 10); i /= 10; } while (i); *p-- = 0; // Reverse the string while (buf < p) { char c = *buf; *buf++ = *p; *p-- = c; } return result; } //*************************************************************************************** // Array of our test objects struct { const char* name; Locale *locale; UErrorCode expected_constructor_status; E_Where where; bool_t like[e_Where_count]; bool_t inherits[e_Where_count]; } param[] = { // "te" means test // "IN" means inherits // "NE" or "ne" means "does not exist" { "default", 0, U_ZERO_ERROR, e_Default, { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } }, { "te", 0, U_ZERO_ERROR, e_te, { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE } }, { "te_IN", 0, U_ZERO_ERROR, e_te_IN, { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE } }, { "te_NE", 0, U_USING_FALLBACK_ERROR, e_te, { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE } }, { "te_IN_NE", 0, U_USING_FALLBACK_ERROR, e_te_IN, { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE } }, { "ne", 0, U_USING_DEFAULT_ERROR, e_Default, { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } } }; int32_t bundles_count = sizeof(param) / sizeof(param[0]); //*************************************************************************************** /** * Return a random unsigned long l where 0N <= l <= ULONG_MAX. */ uint32_t randul() { static bool_t initialized = FALSE; if (!initialized) { srand((unsigned)time(NULL)); initialized = TRUE; } // Assume rand has at least 12 bits of precision uint32_t l; for (int32_t i=0; i> 4; return l; } /** * Return a random double x where 0.0 <= x < 1.0. */ double randd() { return ((double)randul()) / ULONG_MAX; } /** * Return a random integer i where 0 <= i < n. */ int32_t randi(int32_t n) { return (int32_t)(randd() * n); } //*************************************************************************************** ResourceBundleTest::ResourceBundleTest() : pass(0), fail(0), OUT(it_out) { param[0].locale = new Locale("default"); param[1].locale = new Locale("te"); param[2].locale = new Locale("te", "IN"); param[3].locale = new Locale("te", "NE"); param[4].locale = new Locale("te", "IN", "NE"); param[5].locale = new Locale("ne"); } ResourceBundleTest::~ResourceBundleTest() { } void ResourceBundleTest::runIndexedTest( int32_t index, bool_t exec, char* &name, char* par ) { if (exec) logln("TestSuite ResourceBundleTest: "); switch (index) { case 0: name = "TestResourceBundles"; if (exec) TestResourceBundles(); break; case 1: name = "TestConstruction"; if (exec) TestConstruction(); break; default: name = ""; break; //needed to end loop } } //*************************************************************************************** void ResourceBundleTest::TestResourceBundles() { #if defined(_WIN32) && !defined(__WINDOWS__) #if defined(_DEBUG) && RESTEST_HEAP_CHECK /* * Set the debug-heap flag to keep freed blocks in the * heap's linked list - This will allow us to catch any * inadvertent use of freed memory */ int tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF; tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF; tmpDbgFlag |= _CRTDBG_CHECK_ALWAYS_DF; _CrtSetDbgFlag(tmpDbgFlag); _CrtMemState memstate; _CrtMemCheckpoint(&memstate); { #endif #endif testTag("only_in_Default", TRUE, FALSE, FALSE); testTag("only_in_te", FALSE, TRUE, FALSE); testTag("only_in_te_IN", FALSE, FALSE, TRUE); testTag("in_Default_te", TRUE, TRUE, FALSE); testTag("in_Default_te_te_IN", TRUE, TRUE, TRUE); testTag("in_Default_te_IN", TRUE, FALSE, TRUE); testTag("in_te_te_IN", FALSE, TRUE, TRUE); testTag("nonexistent", FALSE, FALSE, FALSE); OUT << "Passed: " << pass << "\nFailed: " << fail << endl; #if defined(_WIN32) && !defined(__WINDOWS__) #if defined(_DEBUG) && RESTEST_HEAP_CHECK } _CrtMemDumpAllObjectsSince(&memstate); /* * Set the debug-heap flag to keep freed blocks in the * heap's linked list - This will allow us to catch any * inadvertent use of freed memory */ tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF; tmpDbgFlag &= ~_CRTDBG_LEAK_CHECK_DF; tmpDbgFlag &= ~_CRTDBG_CHECK_ALWAYS_DF; _CrtSetDbgFlag(tmpDbgFlag); #endif #endif } void ResourceBundleTest::TestConstruction() { { UErrorCode err = U_ZERO_ERROR; const char *directory; Locale locale("te", "IN"); directory=IntlTest::getTestDirectory(); ResourceBundle test1(directory, err); ResourceBundle test2(directory, locale, err); UnicodeString result1; UnicodeString result2; test1.getString("string_in_Default_te_te_IN", result1, err); test2.getString("string_in_Default_te_te_IN", result2, err); if (U_FAILURE(err)) { errln("Something threw an error in TestConstruction()"); return; } logln("for string_in_Default_te_te_IN, default.txt had " + result1); logln("for string_in_Default_te_te_IN, te_IN.txt had " + result2); if (result1 != "DEFAULT" || result2 != "TE_IN") errln("Construction test failed; run verbose for more information"); const char* version1; const char* version2; version1 = test1.getVersionNumber(); version2 = test2.getVersionNumber(); char *versionID1 = new char[1 + strlen(ICU_VERSION) + strlen(version1)]; // + 1 for zero byte char *versionID2 = new char[1 + strlen(ICU_VERSION) + strlen(version2)]; // + 1 for zero byte strcpy(versionID1, ICU_VERSION); strcat(versionID1, ".44"); // hardcoded, please change if the default.txt file or ResourceBundle::kVersionSeparater is changed. strcpy(versionID2, ICU_VERSION); strcat(versionID2, ".55"); // hardcoded, please change if the te_IN.txt file or ResourceBundle::kVersionSeparater is changed. logln(UnicodeString("getVersionNumber on default.txt returned ") + version1); logln(UnicodeString("getVersionNumber on te_IN.txt returned ") + version2); if (strcmp(version1, versionID1) != 0 || strcmp(version2, versionID2) != 0) errln("getVersionNumber() failed"); } { UErrorCode err = U_ZERO_ERROR; const char *directory; Locale locale("te", "IN"); directory=IntlTest::getTestDirectory(); wchar_t* wideDirectory = new wchar_t[256]; mbstowcs(wideDirectory, directory, 256); ResourceBundle test2(wideDirectory, locale, err); UnicodeString result2; test2.getString("string_in_Default_te_te_IN", result2, err); if (U_FAILURE(err)) { errln("Something threw an error in TestConstruction()"); return; } logln("for string_in_Default_te_te_IN, te_IN.txt had " + result2); if (result2 != "TE_IN") errln("Construction test failed; run verbose for more information"); } } //*************************************************************************************** bool_t ResourceBundleTest::testTag(const char* frag, bool_t in_Default, bool_t in_te, bool_t in_te_IN) { bool_t pass=TRUE; // Make array from input params bool_t is_in[] = { in_Default, in_te, in_te_IN }; const char* NAME[] = { "DEFAULT", "TE", "TE_IN" }; // Now try to load the desired items UnicodeString tag; UnicodeString action; int32_t i,j,row,col, actual_bundle; int32_t index; const char *directory; directory=IntlTest::getTestDirectory(); for (i=0; i default */ else if(i == 3) actual_bundle = 1; /* te_NE -> te */ else if(i == 4) actual_bundle = 2; /* te_IN_NE -> te_IN */ else actual_bundle = i; UErrorCode expected_resource_status = U_MISSING_RESOURCE_ERROR; for (j=e_te_IN; j>=e_Default; --j) { if (is_in[j] && param[i].inherits[j]) { if(j == actual_bundle) /* it's in the same bundle OR it's a nonexistent=default bundle (5) */ expected_resource_status = U_ZERO_ERROR; else if(j == 0) expected_resource_status = U_USING_DEFAULT_ERROR; else expected_resource_status = U_USING_FALLBACK_ERROR; break; } } UErrorCode expected_status; UnicodeString base; for (j=param[i].where; j>=0; --j) { if (is_in[j]) { base = NAME[j]; break; } } //-------------------------------------------------------------------------- // string action = param[i].name; action += ".getString("; action += tag; action += ")"; tag = "string_"; tag += frag; UnicodeString string(kERROR); status = U_ZERO_ERROR; theBundle.getString(tag, string, status); CONFIRM_UErrorCode(status, expected_resource_status); UnicodeString expected_string; expected_string = U_SUCCESS(status) ? base : kERROR; CONFIRM_EQ(string, expected_string); //-------------------------------------------------------------------------- // array action = param[i].name; action += ".getStringArray("; action += tag; action += ")"; tag = "array_"; tag += frag; int32_t count = kERROR_COUNT; status = U_ZERO_ERROR; const UnicodeString* array = theBundle.getStringArray(tag, count, status); CONFIRM_UErrorCode(status,expected_resource_status); if (U_SUCCESS(status)) { CONFIRM_GE(count,1); CONFIRM_NE((int32_t)array,(int32_t)0); for (j=0; j= 0 && index < count) ? expected_resource_status : U_MISSING_RESOURCE_ERROR; CONFIRM_UErrorCode(status,expected_status); if (U_SUCCESS(status)) { char buf[32]; expected_string = base; expected_string += itoa(index,buf); } else { expected_string = kERROR; } CONFIRM_EQ(string,expected_string); } //-------------------------------------------------------------------------- // 2dArray action = param[i].name; action += ".get2dArray("; action += tag; action += ")"; tag = "array_2d_"; tag += frag; int32_t row_count = kERROR_COUNT, column_count = kERROR_COUNT; status = U_ZERO_ERROR; const UnicodeString** array2d = theBundle.get2dArray(tag, row_count, column_count, status); CONFIRM_UErrorCode(status,expected_resource_status); if (U_SUCCESS(status)) { CONFIRM_GE(row_count,1); CONFIRM_GE(column_count,(int32_t)0); CONFIRM_NE((int32_t)array,(int32_t)0); for (row=0; row= 0 && row < row_count && col >= 0 && col < column_count) ? expected_resource_status: U_MISSING_RESOURCE_ERROR; CONFIRM_UErrorCode(status,expected_status); if (U_SUCCESS(status)) { char buf[32]; expected_string = base; expected_string += itoa(row,buf); expected_string += itoa(col,buf); } else { expected_string = kERROR; } CONFIRM_EQ(string,expected_string); } //-------------------------------------------------------------------------- // taggedArrayItem tag = "tagged_array_"; tag += frag; action = param[i].name; action += ".getTaggedArray("; action += tag; action += ")"; UnicodeString* tags = 0; UnicodeString* items = 0; int32_t expected_count; status = U_ZERO_ERROR; theBundle.getTaggedArray(tag, tags, items, expected_count, status); CONFIRM_UErrorCode(status, expected_resource_status); if (U_SUCCESS(status)) { CONFIRM_GE((int32_t)expected_count, (int32_t)0); CONFIRM_NE((int32_t)tags, (int32_t)0); CONFIRM_NE((int32_t)items, (int32_t)0); for (index = 0; index < expected_count; index++) { logln("tag = " + tags[index] + ", value = " + items[index]); if (tags[index].startsWith("tag") && items[index].startsWith(base)) record_pass(); else record_fail(); } } else expected_count = 0; delete [] tags; delete [] items; //-------------------------------------------------------------------------- // taggedArrayItem action = param[i].name; action += ".getTaggedArrayItem("; action += tag; action += ")"; count = 0; for (index=-20; index<20; ++index) { char buf[32]; UnicodeString item_tag("tag"); item_tag += itoa(index,buf); status = U_ZERO_ERROR; string = kERROR; theBundle.getTaggedArrayItem(tag,item_tag,string,status); if (index < 0) { CONFIRM_UErrorCode(status,U_MISSING_RESOURCE_ERROR); } else { if (status != U_MISSING_RESOURCE_ERROR) { count++; expected_string = base; expected_string += buf; CONFIRM_EQ(string,expected_string); } } } CONFIRM_EQ(count, expected_count); } return pass; } void ResourceBundleTest::record_pass() { ++pass; } void ResourceBundleTest::record_fail() { err(); ++fail; } //eof