#include "unicode/utypes.h"
+#include "charstr.h"
#include "cmemory.h"
#include "cstring.h"
#include "unicode/unistr.h"
#include "unicode/resbund.h"
+#include "unicode/brkiter.h"
+#include "unicode/utrace.h"
+#include "unicode/ucurr.h"
+#include "uresimp.h"
#include "restsnew.h"
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <limits.h>
+#include <vector>
+#include <string>
+
+//***************************************************************************************
+
+void NewResourceBundleTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
+{
+ if (exec) logln("TestSuite ResourceBundleTest: ");
+ TESTCASE_AUTO_BEGIN;
+
+#if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
+ TESTCASE_AUTO(TestResourceBundles);
+ TESTCASE_AUTO(TestConstruction);
+ TESTCASE_AUTO(TestIteration);
+ TESTCASE_AUTO(TestOtherAPI);
+ TESTCASE_AUTO(TestNewTypes);
+#endif
+
+ TESTCASE_AUTO(TestGetByFallback);
+ TESTCASE_AUTO(TestFilter);
+ TESTCASE_AUTO(TestIntervalAliasFallbacks);
+
+#if U_ENABLE_TRACING
+ TESTCASE_AUTO(TestTrace);
+#endif
+
+ TESTCASE_AUTO_END;
+}
//***************************************************************************************
//***************************************************************************************
-#define CONFIRM_EQ(actual,expected) if ((expected)==(actual)) { record_pass(); } else { record_fail(); errln(action + (UnicodeString)" returned " + (actual) + (UnicodeString)" instead of " + (expected)); }
-#define CONFIRM_GE(actual,expected) if ((actual)>=(expected)) { record_pass(); } else { record_fail(); errln(action + (UnicodeString)" returned " + (actual) + (UnicodeString)" instead of x >= " + (expected)); }
-#define CONFIRM_NE(actual,expected) if ((expected)!=(actual)) { record_pass(); } else { record_fail(); errln(action + (UnicodeString)" returned " + (actual) + (UnicodeString)" instead of x != " + (expected)); }
-
-#define CONFIRM_UErrorCode(actual,expected) if ((expected)==(actual)) { record_pass(); } else { record_fail(); errln(action + (UnicodeString)" returned " + (UnicodeString)u_errorName(actual) + (UnicodeString)" instead of " + (UnicodeString)u_errorName(expected)); }
+#define CONFIRM_EQ(actual,expected) UPRV_BLOCK_MACRO_BEGIN { \
+ if ((expected)==(actual)) { \
+ record_pass(); \
+ } else { \
+ record_fail(); \
+ errln(action + (UnicodeString)" returned " + (actual) + (UnicodeString)" instead of " + (expected)); \
+ } \
+} UPRV_BLOCK_MACRO_END
+#define CONFIRM_GE(actual,expected) UPRV_BLOCK_MACRO_BEGIN { \
+ if ((actual)>=(expected)) { \
+ record_pass(); \
+ } else { \
+ record_fail(); \
+ errln(action + (UnicodeString)" returned " + (actual) + (UnicodeString)" instead of x >= " + (expected)); \
+ } \
+} UPRV_BLOCK_MACRO_END
+#define CONFIRM_NE(actual,expected) UPRV_BLOCK_MACRO_BEGIN { \
+ if ((expected)!=(actual)) { \
+ record_pass(); \
+ } else { \
+ record_fail(); \
+ errln(action + (UnicodeString)" returned " + (actual) + (UnicodeString)" instead of x != " + (expected)); \
+ } \
+} UPRV_BLOCK_MACRO_END
+
+#define CONFIRM_UErrorCode(actual,expected) UPRV_BLOCK_MACRO_BEGIN { \
+ if ((expected)==(actual)) { \
+ record_pass(); \
+ } else { \
+ record_fail(); \
+ errln(action + (UnicodeString)" returned " + (UnicodeString)u_errorName(actual) + (UnicodeString)" instead of " + (UnicodeString)u_errorName(expected)); \
+ } \
+} UPRV_BLOCK_MACRO_END
//***************************************************************************************
}
}
-void NewResourceBundleTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
-{
- if (exec) logln("TestSuite ResourceBundleTest: ");
- switch (index) {
-#if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
- case 0: name = "TestResourceBundles"; if (exec) TestResourceBundles(); break;
- case 1: name = "TestConstruction"; if (exec) TestConstruction(); break;
- case 2: name = "TestIteration"; if (exec) TestIteration(); break;
- case 3: name = "TestOtherAPI"; if(exec) TestOtherAPI(); break;
- case 4: name = "TestNewTypes"; if(exec) TestNewTypes(); break;
-#else
- case 0: case 1: case 2: case 3: case 4: name = "skip"; break;
-#endif
-
- case 5: name = "TestGetByFallback"; if(exec) TestGetByFallback(); break;
- case 6: name = "TestFilter"; if(exec) TestFilter(); break;
-
- default: name = ""; break; //needed to end loop
- }
-}
-
//***************************************************************************************
void
}
-#define REQUIRE_SUCCESS(status) { \
+#define REQUIRE_SUCCESS(status) UPRV_BLOCK_MACRO_BEGIN { \
if (status.errIfFailureAndReset("line %d", __LINE__)) { \
return; \
} \
-}
+} UPRV_BLOCK_MACRO_END
-#define REQUIRE_ERROR(expected, status) { \
+#define REQUIRE_ERROR(expected, status) UPRV_BLOCK_MACRO_BEGIN { \
if (!status.expectErrorAndReset(expected, "line %d", __LINE__)) { \
return; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Tests the --filterDir option in genrb.
assertEquals("fornia", fornia.getType(), URES_TABLE);
{
+ // Filter: hawaii should not be included based on parent inheritance
ResourceBundle hawaii = fornia.get("hawaii", status);
- REQUIRE_SUCCESS(status);
- assertEquals("hawaii", hawaii.getType(), URES_STRING);
- assertEquals("hawaii", u"idaho", hawaii.getString(status));
- REQUIRE_SUCCESS(status);
+ REQUIRE_ERROR(U_MISSING_RESOURCE_ERROR, status);
- // Filter: illinois should not be included
+ // Filter: illinois should not be included based on direct rule
ResourceBundle illinois = fornia.get("illinois", status);
REQUIRE_ERROR(U_MISSING_RESOURCE_ERROR, status);
}
REQUIRE_ERROR(U_MISSING_RESOURCE_ERROR, status);
}
}
+
+ // Filter: northCarolina should be included based on direct rule,
+ // and so should its child, northDakota
+ ResourceBundle northCarolina = rb.get("northCarolina", status);
+ REQUIRE_SUCCESS(status);
+ assertEquals("northCarolina", northCarolina.getType(), URES_TABLE);
+
+ {
+ ResourceBundle northDakota = northCarolina.get("northDakota", status);
+ REQUIRE_SUCCESS(status);
+ assertEquals("northDakota", northDakota.getType(), URES_STRING);
+ assertEquals("northDakota", u"west-virginia", northDakota.getString(status));
+ REQUIRE_SUCCESS(status);
+ }
+}
+
+void NewResourceBundleTest::TestIntervalAliasFallbacks() {
+ const char* locales[] = {
+ // Thee will not cause infinity loop
+ "en",
+ "ja",
+
+ // These will cause infinity loop
+ "fr_CA",
+ "en_150",
+ "es_419",
+ "id",
+ "in",
+ "pl",
+ "pt_PT",
+ "sr_ME",
+ "zh_Hant",
+ "zh_Hant_TW",
+ "zh_TW",
+ };
+ const char* calendars[] = {
+ // These won't cause infinity loop
+ "gregorian",
+ "chinese",
+
+ // These will cause infinity loop
+ "islamic",
+ "islamic-civil",
+ "islamic-tbla",
+ "islamic-umalqura",
+ "ethiopic-amete-alem",
+ "islamic-rgsa",
+ "japanese",
+ "roc",
+ };
+
+ for (int lidx = 0; lidx < UPRV_LENGTHOF(locales); lidx++) {
+ UErrorCode status = U_ZERO_ERROR;
+ UResourceBundle *rb = ures_open(NULL, locales[lidx], &status);
+ if (U_FAILURE(status)) {
+ errln("Cannot open bundle for locale %s", locales[lidx]);
+ break;
+ }
+ for (int cidx = 0; cidx < UPRV_LENGTHOF(calendars); cidx++) {
+ CharString key;
+ key.append("calendar/", status);
+ key.append(calendars[cidx], status);
+ key.append("/intervalFormats/fallback", status);
+ if (! logKnownIssue("20400")) {
+ int32_t resStrLen = 0;
+ ures_getStringByKeyWithFallback(rb, key.data(), &resStrLen, &status);
+ }
+ if (U_FAILURE(status)) {
+ errln("Cannot ures_getStringByKeyWithFallback('%s') on locale %s",
+ key.data(), locales[lidx]);
+ break;
+ }
+ }
+ ures_close(rb);
+ }
}
+#if U_ENABLE_TRACING
+
+static std::vector<std::string> gResourcePathsTraced;
+static std::vector<std::string> gDataFilesTraced;
+static std::vector<std::string> gBundlesTraced;
+
+static void U_CALLCONV traceData(
+ const void*,
+ int32_t fnNumber,
+ int32_t,
+ const char *,
+ va_list args) {
+
+ // NOTE: Whether this test is run in isolation affects whether or not
+ // *.res files are opened. For stability, ignore *.res file opens.
+
+ if (fnNumber == UTRACE_UDATA_RESOURCE) {
+ va_arg(args, const char*); // type
+ va_arg(args, const char*); // file
+ const char* resourcePath = va_arg(args, const char*);
+ gResourcePathsTraced.push_back(resourcePath);
+ } else if (fnNumber == UTRACE_UDATA_BUNDLE) {
+ const char* filePath = va_arg(args, const char*);
+ gBundlesTraced.push_back(filePath);
+ } else if (fnNumber == UTRACE_UDATA_DATA_FILE) {
+ const char* filePath = va_arg(args, const char*);
+ gDataFilesTraced.push_back(filePath);
+ } else if (fnNumber == UTRACE_UDATA_RES_FILE) {
+ // ignore
+ }
+}
+
+void NewResourceBundleTest::TestTrace() {
+ IcuTestErrorCode status(*this, "TestTrace");
+
+ assertEquals("Start position stability coverage", 0x3000, UTRACE_UDATA_START);
+
+ const void* context;
+ utrace_setFunctions(context, nullptr, nullptr, traceData);
+ utrace_setLevel(UTRACE_VERBOSE);
+
+ {
+ LocalPointer<BreakIterator> brkitr(BreakIterator::createWordInstance("zh-CN", status));
+
+ assertEquals("Should touch expected resource paths",
+ { "/boundaries", "/boundaries/word", "/boundaries/word" },
+ gResourcePathsTraced);
+ assertEquals("Should touch expected resource bundles",
+ { U_ICUDATA_NAME "-brkitr/zh.res" },
+ gBundlesTraced);
+ assertEquals("Should touch expected data files",
+ { U_ICUDATA_NAME "-brkitr/word.brk" },
+ gDataFilesTraced);
+ gResourcePathsTraced.clear();
+ gDataFilesTraced.clear();
+ gBundlesTraced.clear();
+ }
+
+ {
+ ucurr_getDefaultFractionDigits(u"USD", status);
+
+ assertEquals("Should touch expected resource paths",
+ { "/CurrencyMeta", "/CurrencyMeta/DEFAULT", "/CurrencyMeta/DEFAULT" },
+ gResourcePathsTraced);
+ assertEquals("Should touch expected resource bundles",
+ { U_ICUDATA_NAME "-curr/supplementalData.res" },
+ gBundlesTraced);
+ assertEquals("Should touch expected data files",
+ { },
+ gDataFilesTraced);
+ gResourcePathsTraced.clear();
+ gDataFilesTraced.clear();
+ gBundlesTraced.clear();
+ }
+
+ utrace_setFunctions(context, nullptr, nullptr, nullptr);
+}
+
+#endif
+
//eof