+
+void LocaleTest::TestCurrencyByDate(void)
+{
+#if !UCONFIG_NO_FORMATTING
+ UErrorCode status = U_ZERO_ERROR;
+ UDate date = uprv_getUTCtime();
+ UChar TMP[4];
+ int32_t index = 0;
+ int32_t resLen = 0;
+ UnicodeString tempStr, resultStr;
+
+ // Cycle through historical currencies
+ date = (UDate)-630720000000.0; // pre 1961 - no currency defined
+ index = ucurr_countCurrencies("eo_AM", date, &status);
+ if (index != 0)
+ {
+ errcheckln(status, "FAIL: didn't return 0 for eo_AM - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AM", date, index, TMP, 4, &status);
+ if (resLen != 0) {
+ errcheckln(status, "FAIL: eo_AM didn't return NULL - %s", u_errorName(status));
+ }
+ status = U_ZERO_ERROR;
+
+ date = (UDate)0.0; // 1970 - one currency defined
+ index = ucurr_countCurrencies("eo_AM", date, &status);
+ if (index != 1)
+ {
+ errcheckln(status, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AM", date, index, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("SUR");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return SUR for eo_AM - %s", u_errorName(status));
+ }
+
+ date = (UDate)693792000000.0; // 1992 - one currency defined
+ index = ucurr_countCurrencies("eo_AM", date, &status);
+ if (index != 1)
+ {
+ errcheckln(status, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AM", date, index, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("RUR");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return RUR for eo_AM - %s", u_errorName(status));
+ }
+
+ date = (UDate)977616000000.0; // post 1993 - one currency defined
+ index = ucurr_countCurrencies("eo_AM", date, &status);
+ if (index != 1)
+ {
+ errcheckln(status, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AM", date, index, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("AMD");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return AMD for eo_AM - %s", u_errorName(status));
+ }
+
+ // Locale AD has multiple currencies at once
+ date = (UDate)977616000000.0; // year 2001
+ index = ucurr_countCurrencies("eo_AD", date, &status);
+ if (index != 4)
+ {
+ errcheckln(status, "FAIL: didn't return 4 for eo_AD - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AD", date, 1, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("EUR");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return EUR for eo_AD - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AD", date, 2, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("ESP");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AD", date, 3, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("FRF");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AD", date, 4, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("ADP");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status));
+ }
+
+ date = (UDate)0.0; // year 1970
+ index = ucurr_countCurrencies("eo_AD", date, &status);
+ if (index != 3)
+ {
+ errcheckln(status, "FAIL: didn't return 3 for eo_AD - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AD", date, 1, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("ESP");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AD", date, 2, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("FRF");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AD", date, 3, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("ADP");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status));
+ }
+
+ date = (UDate)-630720000000.0; // year 1950
+ index = ucurr_countCurrencies("eo_AD", date, &status);
+ if (index != 2)
+ {
+ errcheckln(status, "FAIL: didn't return 2 for eo_AD - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AD", date, 1, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("ESP");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AD", date, 2, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("ADP");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status));
+ }
+
+ date = (UDate)-2207520000000.0; // year 1900
+ index = ucurr_countCurrencies("eo_AD", date, &status);
+ if (index != 1)
+ {
+ errcheckln(status, "FAIL: didn't return 1 for eo_AD - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AD", date, 1, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("ESP");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status));
+ }
+
+ // Locale UA has gap between years 1994 - 1996
+ date = (UDate)788400000000.0;
+ index = ucurr_countCurrencies("eo_UA", date, &status);
+ if (index != 0)
+ {
+ errcheckln(status, "FAIL: didn't return 0 for eo_UA - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_UA", date, index, TMP, 4, &status);
+ if (resLen != 0) {
+ errcheckln(status, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status));
+ }
+ status = U_ZERO_ERROR;
+
+ // Test index bounds
+ resLen = ucurr_forLocaleAndDate("eo_UA", date, 100, TMP, 4, &status);
+ if (resLen != 0) {
+ errcheckln(status, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status));
+ }
+ status = U_ZERO_ERROR;
+
+ resLen = ucurr_forLocaleAndDate("eo_UA", date, 0, TMP, 4, &status);
+ if (resLen != 0) {
+ errcheckln(status, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status));
+ }
+ status = U_ZERO_ERROR;
+
+ // Test for bogus locale
+ index = ucurr_countCurrencies("eo_QQ", date, &status);
+ if (index != 0)
+ {
+ errcheckln(status, "FAIL: didn't return 0 for eo_QQ - %s", u_errorName(status));
+ }
+ status = U_ZERO_ERROR;
+ resLen = ucurr_forLocaleAndDate("eo_QQ", date, 1, TMP, 4, &status);
+ if (resLen != 0) {
+ errcheckln(status, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status));
+ }
+ status = U_ZERO_ERROR;
+ resLen = ucurr_forLocaleAndDate("eo_QQ", date, 0, TMP, 4, &status);
+ if (resLen != 0) {
+ errcheckln(status, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status));
+ }
+ status = U_ZERO_ERROR;
+
+ // Cycle through histrocial currencies
+ date = (UDate)977616000000.0; // 2001 - one currency
+ index = ucurr_countCurrencies("eo_AO", date, &status);
+ if (index != 1)
+ {
+ errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("AOA");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return AOA for eo_AO - %s", u_errorName(status));
+ }
+
+ date = (UDate)819936000000.0; // 1996 - 2 currencies
+ index = ucurr_countCurrencies("eo_AO", date, &status);
+ if (index != 2)
+ {
+ errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("AOR");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return AOR for eo_AO - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AO", date, 2, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("AON");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status));
+ }
+
+ date = (UDate)662256000000.0; // 1991 - 2 currencies
+ index = ucurr_countCurrencies("eo_AO", date, &status);
+ if (index != 2)
+ {
+ errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("AON");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AO", date, 2, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("AOK");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status));
+ }
+
+ date = (UDate)315360000000.0; // 1980 - one currency
+ index = ucurr_countCurrencies("eo_AO", date, &status);
+ if (index != 1)
+ {
+ errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("AOK");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status));
+ }
+
+ date = (UDate)0.0; // 1970 - no currencies
+ index = ucurr_countCurrencies("eo_AO", date, &status);
+ if (index != 0)
+ {
+ errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status);
+ if (resLen != 0) {
+ errcheckln(status, "FAIL: eo_AO didn't return NULL - %s", u_errorName(status));
+ }
+ status = U_ZERO_ERROR;
+
+ // Test with currency keyword override
+ date = (UDate)977616000000.0; // 2001 - two currencies
+ index = ucurr_countCurrencies("eo_DE@currency=DEM", date, &status);
+ if (index != 2)
+ {
+ errcheckln(status, "FAIL: didn't return 2 for eo_DE@currency=DEM - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_DE@currency=DEM", date, 1, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("EUR");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return EUR for eo_DE@currency=DEM - %s", u_errorName(status));
+ }
+ resLen = ucurr_forLocaleAndDate("eo_DE@currency=DEM", date, 2, TMP, 4, &status);
+ tempStr.setTo(TMP);
+ resultStr.setTo("DEM");
+ if (resultStr != tempStr) {
+ errcheckln(status, "FAIL: didn't return DEM for eo_DE@currency=DEM - %s", u_errorName(status));
+ }
+
+ // Test Euro Support
+ status = U_ZERO_ERROR; // reset
+ date = uprv_getUTCtime();
+
+ UChar USD[4];
+ ucurr_forLocaleAndDate("en_US", date, 1, USD, 4, &status);
+
+ UChar YEN[4];
+ ucurr_forLocaleAndDate("ja_JP", date, 1, YEN, 4, &status);
+
+ ucurr_forLocaleAndDate("en_US", date, 1, TMP, 4, &status);
+ if (u_strcmp(USD, TMP) != 0) {
+ errcheckln(status, "Fail: en_US didn't return USD - %s", u_errorName(status));
+ }
+ ucurr_forLocaleAndDate("en_US_PREEURO", date, 1, TMP, 4, &status);
+ if (u_strcmp(USD, TMP) != 0) {
+ errcheckln(status, "Fail: en_US_PREEURO didn't fallback to en_US - %s", u_errorName(status));
+ }
+ ucurr_forLocaleAndDate("en_US_Q", date, 1, TMP, 4, &status);
+ if (u_strcmp(USD, TMP) != 0) {
+ errcheckln(status, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status));
+ }
+ status = U_ZERO_ERROR; // reset
+#endif
+}
+
+void LocaleTest::TestGetVariantWithKeywords(void)
+{
+ Locale l("en_US_VALLEY@foo=value");
+ const char *variant = l.getVariant();
+ logln(variant);
+ test_assert(strcmp("VALLEY", variant) == 0);
+
+ UErrorCode status = U_ZERO_ERROR;
+ char buffer[50];
+ int32_t len = l.getKeywordValue("foo", buffer, 50, status);
+ buffer[len] = '\0';
+ test_assert(strcmp("value", buffer) == 0);
+}
+
+void LocaleTest::TestIsRightToLeft() {
+ assertFalse("root LTR", Locale::getRoot().isRightToLeft());
+ assertFalse("zh LTR", Locale::getChinese().isRightToLeft());
+ assertTrue("ar RTL", Locale("ar").isRightToLeft());
+ assertTrue("und-EG RTL", Locale("und-EG").isRightToLeft(), FALSE, TRUE);
+ assertFalse("fa-Cyrl LTR", Locale("fa-Cyrl").isRightToLeft());
+ assertTrue("en-Hebr RTL", Locale("en-Hebr").isRightToLeft());
+ assertTrue("ckb RTL", Locale("ckb").isRightToLeft(), FALSE, TRUE); // Sorani Kurdish
+ assertFalse("fil LTR", Locale("fil").isRightToLeft());
+ assertFalse("he-Zyxw LTR", Locale("he-Zyxw").isRightToLeft());
+}
+
+void LocaleTest::TestBug11421() {
+ Locale::getDefault().getBaseName();
+ int32_t numLocales;
+ const Locale *localeList = Locale::getAvailableLocales(numLocales);
+ for (int localeIndex = 0; localeIndex < numLocales; localeIndex++) {
+ const Locale &loc = localeList[localeIndex];
+ if (strncmp(loc.getName(), loc.getBaseName(), strlen(loc.getBaseName()))) {
+ errln("%s:%d loc.getName=\"%s\"; loc.getBaseName=\"%s\"",
+ __FILE__, __LINE__, loc.getName(), loc.getBaseName());
+ break;
+ }
+ }
+}
+
+// TestBug13277. The failure manifests as valgrind errors.
+// See the trac ticket for details.
+//
+
+void LocaleTest::TestBug13277() {
+ UErrorCode status = U_ZERO_ERROR;
+ CharString name("en-us-x-foo", -1, status);
+ while (name.length() < 152) {
+ name.append("-x-foo", -1, status);
+ }
+
+ while (name.length() < 160) {
+ name.append('z', status);
+ Locale loc(name.data(), nullptr, nullptr, nullptr);
+ }
+}
+
+// TestBug13554 Check for read past end of array in getPosixID().
+// The bug shows as an Address Sanitizer failure.
+
+void LocaleTest::TestBug13554() {
+ UErrorCode status = U_ZERO_ERROR;
+ const int BUFFER_SIZE = 100;
+ char posixID[BUFFER_SIZE];
+
+ for (uint32_t hostid = 0; hostid < 0x500; ++hostid) {
+ status = U_ZERO_ERROR;
+ uprv_convertToPosix(hostid, posixID, BUFFER_SIZE, &status);
+ }
+}
+
+