]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/intltest/restsnew.cpp
ICU-66108.tar.gz
[apple/icu.git] / icuSources / test / intltest / restsnew.cpp
index 1c19fc8e91deeae7b9a574a7b1a8dfc700efb81d..b2d72d98a8201036bb18df0bdf740c749f4d6514 100644 (file)
@@ -7,16 +7,49 @@
 
 #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;
+}
 
 //***************************************************************************************
 
@@ -36,11 +69,39 @@ enum E_Where
 
 //***************************************************************************************
 
-#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
 
 //***************************************************************************************
 
@@ -180,27 +241,6 @@ NewResourceBundleTest::~NewResourceBundleTest()
     }
 }
 
-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
@@ -1202,17 +1242,17 @@ NewResourceBundleTest::TestGetByFallback() {
 }
 
 
-#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.
@@ -1261,13 +1301,11 @@ void NewResourceBundleTest::TestFilter() {
     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);
     }
@@ -1341,7 +1379,162 @@ void NewResourceBundleTest::TestFilter() {
             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