+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
/********************************************************************
* COPYRIGHT:
- * Copyright (c) 1997-2004, International Business Machines Corporation and
+ * Copyright (c) 1997-2016, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
#include "loctest.h"
-#include <stdio.h>
#include "unicode/decimfmt.h"
#include "unicode/ucurr.h"
#include "unicode/smpdtfmt.h"
+#include "unicode/strenum.h"
#include "unicode/dtfmtsym.h"
#include "unicode/brkiter.h"
#include "unicode/coll.h"
+#include "unicode/ustring.h"
+#include "charstr.h"
+#include "cmemory.h"
#include "cstring.h"
-#include "uassert.h"
+#include <stdio.h>
+#include <string.h>
+#include "putilimp.h"
+#include "hash.h"
+#include "locmap.h"
-const char* rawData[33][8] = {
+static const char* const rawData[33][8] = {
// language code
{ "en", "fr", "ca", "el", "no", "it", "xx", "zh" },
// display name (English)
// Updated no_NO_NY English display name for new pattern-based algorithm
// (part of Euro support).
- { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway, NY)", "Italian", "xx (YY)", "Chinese (Simplified Han, China)" },
+ { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway, NY)", "Italian", "xx (YY)", "Chinese (Simplified, China)" },
// display langage (French)
{ "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "italien", "xx", "chinois" },
// display script (French)
- { "", "", "", "", "", "", "", "han simplifi\\u00E9" },
+ { "", "", "", "", "", "", "", "sinogrammes simplifi\\u00E9s" },
// display country (French)
{ "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "", "YY", "Chine" },
// display variant (French)
{ "", "", "", "", "NY", "", "", "" },
// display name (French)
//{ "anglais (Etats-Unis)", "francais (France)", "catalan (Espagne)", "grec (Grece)", "norvegien (Norvege,Nynorsk)", "italien", "xx (YY)" },
- { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)", "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "italien", "xx (YY)", "chinois (han simplifi\\u00E9, Chine)" }, // STILL not right
+ { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)", "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "italien", "xx (YY)", "chinois (simplifi\\u00E9, Chine)" },
/* display language (Catalan) */
- { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "itali\\u00E0", "", "xin\\u00E9s" },
+ { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "itali\\u00E0", "", "xin\\u00E8s" },
/* display script (Catalan) */
- { "", "", "", "", "", "", "", "Hans" },
+ { "", "", "", "", "", "", "", "han simplificat" },
/* display country (Catalan) */
{ "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "", "", "Xina" },
/* display variant (Catalan) */
{ "", "", "", "", "NY", "", "" },
/* display name (Catalan) */
- { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)", "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "itali\\u00E0", "", "xin\\u00E9s (Hans, Xina)" },
+ { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)", "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "itali\\u00E0", "", "xin\\u00E8s (simplificat, Xina)" },
// display langage (Greek)[actual values listed below]
{ "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
"\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC"
},
// display script (Greek)
- { "", "", "", "", "", "", "", "Hans" },
+ { "", "", "", "", "", "", "", "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u03a7\\u03b1\\u03bd" },
// display country (Greek)[actual values listed below]
{ "\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2",
"\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
"\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
"\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
"",
- "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (Hans, \\u039A\\u03AF\\u03BD\\u03B1)"
+ "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03b1, \\u039A\\u03AF\\u03BD\\u03B1)"
},
// display langage (<root>)
{ "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,NY)", "Italian", "xx (YY)", "" }
};
-// * test macros
+
/*
Usage:
- test_compare( Function to be performed,
- Test of the function,
- expected result of the test,
- printable result
- )
+ test_assert( Test (should be TRUE) )
Example:
- test_compare(i=3,i,3, someNumberFormatter(i));
- test_compare(0,1+1,2,someNumberFormatter(1+1));
-
- Note that in the second example the expression is 0, because the fcn produces it's own result.
+ test_assert(i==3);
- Macro is ugly but makes the tests pretty.
+ the macro is ugly but makes the tests pretty.
*/
-#define test_compare(expression,test,expected,printableResult) \
+#define test_assert(test) \
{ \
- expression; \
- \
- if((test) != (expected)) \
- errln("FAIL: " + UnicodeString(#expression) + "; -> " + printableResult + "\n" + \
- " (" + UnicodeString(#test) + " != " + UnicodeString(#expected) + ")" ); \
+ if(!(test)) \
+ errln("FAIL: " #test " was not true. In " __FILE__ " on line %d", __LINE__ ); \
else \
- logln(UnicodeString(#expression) + " -> " + printableResult + " (" + UnicodeString(#test) + ")"); \
+ logln("PASS: asserted " #test); \
}
-
-
-
/*
Usage:
test_assert_print( Test (should be TRUE), printable )
#define test_assert_print(test,print) \
{ \
if(!(test)) \
- errln("FAIL: " + UnicodeString(#test) + " was not true." + "-> " + UnicodeString(print) ); \
+ errln("FAIL: " #test " was not true. " + UnicodeString(print) ); \
else \
- logln("PASS: asserted " + UnicodeString(#test) + "-> " + UnicodeString(print)); \
+ logln("PASS: asserted " #test "-> " + UnicodeString(print)); \
}
-#define test_dumpLocale(l) { UnicodeString s(l.getName(),""); logln(#l + UnicodeString(" = ") + s); }
+#define test_dumpLocale(l) { logln(#l " = " + UnicodeString(l.getName(), "")); }
LocaleTest::LocaleTest()
: dataTable(NULL)
void LocaleTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
{
- switch (index) {
- TESTCASE(0, TestBasicGetters);
- TESTCASE(1, TestSimpleResourceInfo);
- TESTCASE(2, TestDisplayNames);
- TESTCASE(3, TestSimpleObjectStuff);
- TESTCASE(4, TestPOSIXParsing);
- TESTCASE(5, TestGetAvailableLocales);
- TESTCASE(6, TestDataDirectory);
- TESTCASE(7, TestISO3Fallback);
- TESTCASE(8, TestGetLangsAndCountries);
- TESTCASE(9, TestSimpleDisplayNames);
- TESTCASE(10, TestUninstalledISO3Names);
- TESTCASE(11, TestAtypicalLocales);
+ TESTCASE_AUTO_BEGIN;
+ TESTCASE_AUTO(TestBug11421); // Must run early in list to trigger failure.
+ TESTCASE_AUTO(TestBasicGetters);
+ TESTCASE_AUTO(TestSimpleResourceInfo);
+ TESTCASE_AUTO(TestDisplayNames);
+ TESTCASE_AUTO(TestSimpleObjectStuff);
+ TESTCASE_AUTO(TestPOSIXParsing);
+ TESTCASE_AUTO(TestGetAvailableLocales);
+ TESTCASE_AUTO(TestDataDirectory);
+ TESTCASE_AUTO(TestISO3Fallback);
+ TESTCASE_AUTO(TestGetLangsAndCountries);
+ TESTCASE_AUTO(TestSimpleDisplayNames);
+ TESTCASE_AUTO(TestUninstalledISO3Names);
+ TESTCASE_AUTO(TestAtypicalLocales);
#if !UCONFIG_NO_FORMATTING
- TESTCASE(12, TestThaiCurrencyFormat);
- TESTCASE(13, TestEuroSupport);
+ TESTCASE_AUTO(TestThaiCurrencyFormat);
+ TESTCASE_AUTO(TestEuroSupport);
#endif
- TESTCASE(14, TestToString);
+ TESTCASE_AUTO(TestToString);
#if !UCONFIG_NO_FORMATTING
- TESTCASE(15, Test4139940);
- TESTCASE(16, Test4143951);
+ TESTCASE_AUTO(Test4139940);
+ TESTCASE_AUTO(Test4143951);
#endif
- TESTCASE(17, Test4147315);
- TESTCASE(18, Test4147317);
- TESTCASE(19, Test4147552);
- TESTCASE(20, TestVariantParsing);
+ TESTCASE_AUTO(Test4147315);
+ TESTCASE_AUTO(Test4147317);
+ TESTCASE_AUTO(Test4147552);
+ TESTCASE_AUTO(TestVariantParsing);
#if !UCONFIG_NO_FORMATTING
- TESTCASE(21, Test4105828);
+ TESTCASE_AUTO(Test4105828);
#endif
- TESTCASE(22, TestSetIsBogus);
- TESTCASE(23, TestParallelAPIValues);
- TESTCASE(24, TestKeywordVariants);
- TESTCASE(25, TestKeywordVariantParsing);
- TESTCASE(26, TestGetBaseName);
- TESTCASE(27, TestGetLocale);
- TESTCASE(28, TestVariantWithOutCountry);
- TESTCASE(29, TestCanonicalization);
-
- // keep the last index in sync with the condition in default:
-
- default:
- if (index <= 28) { // keep this in sync with the last index!
- name = "(test omitted by !UCONFIG_NO_FORMATTING)";
- } else {
- name = "";
- }
- break; //needed to end loop
- }
+ TESTCASE_AUTO(TestSetIsBogus);
+ TESTCASE_AUTO(TestParallelAPIValues);
+ TESTCASE_AUTO(TestKeywordVariants);
+ TESTCASE_AUTO(TestKeywordVariantParsing);
+ TESTCASE_AUTO(TestSetKeywordValue);
+ TESTCASE_AUTO(TestGetBaseName);
+#if !UCONFIG_NO_FILE_IO
+ TESTCASE_AUTO(TestGetLocale);
+#endif
+ TESTCASE_AUTO(TestVariantWithOutCountry);
+ TESTCASE_AUTO(TestCanonicalization);
+ TESTCASE_AUTO(TestCurrencyByDate);
+ TESTCASE_AUTO(TestGetVariantWithKeywords);
+ TESTCASE_AUTO(TestIsRightToLeft);
+ TESTCASE_AUTO(TestBug13277);
+ TESTCASE_AUTO(TestBug13554);
+ TESTCASE_AUTO_END;
}
void LocaleTest::TestBasicGetters() {
logln(" In locale = el_GR...");
doTestDisplayNames(greek, DLANG_EL);
- /* test that the default locale has a display name for its own language */
UnicodeString s;
- Locale().getDisplayLanguage(Locale(), s);
- if(s.length()<=3 && s.charAt(0)<=0x7f) {
- /* check <=3 to reject getting the language code as a display name */
- errln("unable to get a display string for the language of the default locale\n");
- }
+ UErrorCode status = U_ZERO_ERROR;
- /*
- * API coverage improvements: call
- * Locale::getDisplayLanguage(UnicodeString &) and
- * Locale::getDisplayCountry(UnicodeString &)
- */
- s.remove();
- Locale().getDisplayLanguage(s);
- if(s.length()<=3 && s.charAt(0)<=0x7f) {
- errln("unable to get a display string for the language of the default locale [2]\n");
+#if !UCONFIG_NO_FORMATTING
+ DecimalFormatSymbols symb(status);
+ /* Check to see if ICU supports this locale */
+ if (symb.getLocale(ULOC_VALID_LOCALE, status) != Locale("root")) {
+ /* test that the default locale has a display name for its own language */
+ /* Currently, there is no language information in the "tl" data file so this test will fail if default locale is "tl" */
+ if (uprv_strcmp(Locale().getLanguage(), "tl") != 0) {
+ Locale().getDisplayLanguage(Locale(), s);
+ if(s.length()<=3 && s.charAt(0)<=0x7f) {
+ /* check <=3 to reject getting the language code as a display name */
+ dataerrln("unable to get a display string for the language of the default locale: " + s);
+ }
+
+ /*
+ * API coverage improvements: call
+ * Locale::getDisplayLanguage(UnicodeString &) and
+ * Locale::getDisplayCountry(UnicodeString &)
+ */
+ s.remove();
+ Locale().getDisplayLanguage(s);
+ if(s.length()<=3 && s.charAt(0)<=0x7f) {
+ dataerrln("unable to get a display string for the language of the default locale [2]: " + s);
+ }
+ }
+ }
+ else {
+ logln("Default locale %s is unsupported by ICU\n", Locale().getName());
}
s.remove();
+#endif
+
french.getDisplayCountry(s);
if(s.isEmpty()) {
errln("unable to get any default-locale display string for the country of fr_FR\n");
}
-}
-
-/*
- Usage:
- test_assert( Test (should be TRUE) )
-
- Example:
- test_assert(i==3);
-
- the macro is ugly but makes the tests pretty.
-*/
-
-#define test_assert(test) \
- { \
- if(!(test)) \
- errln("FAIL: " + UnicodeString(#test) + " was not true. " + UnicodeString(__FILE__ " line ") + __LINE__ ); \
- else \
- logln("PASS: asserted " + UnicodeString(#test) ); \
+ s.remove();
+ Locale("zh", "Hant").getDisplayScript(s);
+ if(s.isEmpty()) {
+ errln("unable to get any default-locale display string for the country of zh_Hant\n");
}
+}
void LocaleTest::TestSimpleObjectStuff() {
Locale test1("aa", "AA");
const Locale* locList = Locale::getAvailableLocales(locCount);
if (locCount == 0)
- errln("getAvailableLocales() returned an empty list!");
+ dataerrln("getAvailableLocales() returned an empty list!");
else {
logln(UnicodeString("Number of locales returned = ") + locCount);
UnicodeString temp;
expectedName = dataTable[DNAME_EN][i];
if (testLang != expectedLang)
- errln("Display language (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testLang + " expected " + expectedLang);
+ dataerrln("Display language (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testLang + " expected " + expectedLang);
if (testScript != expectedScript)
- errln("Display script (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testScript + " expected " + expectedScript);
+ dataerrln("Display script (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testScript + " expected " + expectedScript);
if (testCtry != expectedCtry)
- errln("Display country (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testCtry + " expected " + expectedCtry);
+ dataerrln("Display country (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testCtry + " expected " + expectedCtry);
if (testVar != expectedVar)
- errln("Display variant (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testVar + " expected " + expectedVar);
+ dataerrln("Display variant (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testVar + " expected " + expectedVar);
if (testName != expectedName)
- errln("Display name (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testName + " expected " + expectedName);
+ dataerrln("Display name (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testName + " expected " + expectedName);
}
}
;
/* TODO: Change this test to be more like the cloctst version? */
- if (testCount != 468)
- errln("Expected getISOLanguages() to return 468 languages; it returned %d", testCount);
+ if (testCount != 595)
+ errln("Expected getISOLanguages() to return 595 languages; it returned %d", testCount);
else {
for (i = 0; i < 15; i++) {
int32_t j;
for(testCount=0;test[testCount];testCount++)
;
- if (testCount != 239)
- errln("Expected getISOLanguages to return 238 languages; it returned" + testCount);
- else {
+ if (testCount != 256){
+ errln("Expected getISOCountries to return 256 countries; it returned %d", testCount);
+ }else {
for (i = 0; i < spot2Len; i++) {
int32_t j;
for (j = 0; j < testCount; j++)
}
}
for (i = 0; i < testCount; i++) {
- UnicodeString testee(test[i],"");
+ UnicodeString testee(test[i],"");
UnicodeString uc(test[i],"");
if (testee != uc.toUpper())
errln(testee + " is not all upper case.");
if (i > 0 && testee.compare(test[i - 1]) <= 0)
errln(testee + " appears in an out-of-order position in the list.");
}
+
+ // This getAvailableLocales and getISO3Language
+ {
+ int32_t numOfLocales;
+ Locale enLoc ("en");
+ const Locale *pLocales = Locale::getAvailableLocales(numOfLocales);
+
+ for (int i = 0; i < numOfLocales; i++) {
+ const Locale &loc(pLocales[i]);
+ UnicodeString name;
+ char szName[200];
+
+ loc.getDisplayName (enLoc, name);
+ name.extract (0, 200, szName, sizeof(szName));
+
+ if (strlen(loc.getISO3Language()) == 0) {
+ errln("getISO3Language() returned an empty string for: " + name);
+ }
+ }
+ }
}
/**
// names, and other stuff like that. This test just checks specific language
// and country codes to make sure we have the correct names for them.
char languageCodes[] [4] = { "he", "id", "iu", "ug", "yi", "za" };
- UnicodeString languageNames [] = { "Hebrew", "Indonesian", "Inuktitut", "Uighur", "Yiddish",
+ UnicodeString languageNames [] = { "Hebrew", "Indonesian", "Inuktitut", "Uyghur", "Yiddish",
"Zhuang" };
for (int32_t i = 0; i < 6; i++) {
Locale l(languageCodes[i], "", "");
l.getDisplayLanguage(Locale::getUS(), test);
if (test != languageNames[i])
- errln("Got wrong display name for " + UnicodeString(languageCodes[i]) + ": Expected \"" +
+ dataerrln("Got wrong display name for " + UnicodeString(languageCodes[i]) + ": Expected \"" +
languageNames[i] + "\", got \"" + test + "\".");
}
}
CharsToUnicodeString("B\\u00E9lgica") };
// De-Anglicizing root required the change from
// English display names to ISO Codes - ram 2003/09/26
- UnicodeString bengaliDisplayNames [] = { "de (CA)",
- "ja (ZA)",
- "ru (MX)",
- "en (FR)",
- "es (DE)",
- "HR",
- "SE",
- "DO",
- "BE" };
+ UnicodeString invDisplayNames [] = { "German (Canada)",
+ "Japanese (South Africa)",
+ "Russian (Mexico)",
+ "English (France)",
+ "Spanish (Germany)",
+ "Croatia",
+ "Sweden",
+ "Dominican Republic",
+ "Belgium" };
int32_t i;
UErrorCode status = U_ZERO_ERROR;
+ Locale saveLocale;
Locale::setDefault(Locale::getUS(), status);
for (i = 0; i < 9; ++i) {
UnicodeString name;
logln(name);
if (name != englishDisplayNames[i])
{
- errln("Lookup in English failed: expected \"" + englishDisplayNames[i]
+ dataerrln("Lookup in English failed: expected \"" + englishDisplayNames[i]
+ "\", got \"" + name + "\"");
logln("Locale name was-> " + (name=localesToTest[i].getName()));
}
localesToTest[i].getDisplayName(Locale("es", "ES"), name);
logln(name);
if (name != spanishDisplayNames[i])
- errln("Lookup in Spanish failed: expected \"" + spanishDisplayNames[i]
+ dataerrln("Lookup in Spanish failed: expected \"" + spanishDisplayNames[i]
+ "\", got \"" + name + "\"");
}
localesToTest[i].getDisplayName(Locale::getFrance(), name);
logln(name);
if (name != frenchDisplayNames[i])
- errln("Lookup in French failed: expected \"" + frenchDisplayNames[i]
+ dataerrln("Lookup in French failed: expected \"" + frenchDisplayNames[i]
+ "\", got \"" + name + "\"");
}
for (i = 0; i < 9; i++) {
UnicodeString name;
- localesToTest[i].getDisplayName(Locale("be", "ES"), name);
+ localesToTest[i].getDisplayName(Locale("inv", "IN"), name);
logln(name + " Locale fallback to be, and data fallback to root");
- if (name != bengaliDisplayNames[i])
- errln("Lookup in Bengali failed: expected \"" + bengaliDisplayNames[i]
- + "\", got \"" + name + "\"");
- localesToTest[i].getDisplayName(Locale("be", "EG"), name);
+ if (name != invDisplayNames[i])
+ dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames[i])
+ + "\", got \"" + prettify(name) + "\"");
+ localesToTest[i].getDisplayName(Locale("inv", "BD"), name);
logln(name + " Data fallback to root");
- if (name != bengaliDisplayNames[i])
- errln("Lookup in Bengali failed: expected \"" + bengaliDisplayNames[i]
- + "\", got \"" + name + "\"");
+ if (name != invDisplayNames[i])
+ dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames[i])
+ + "\", got \"" + prettify(name )+ "\"");
}
+ Locale::setDefault(saveLocale, status);
}
#if !UCONFIG_NO_FORMATTING
UErrorCode status = U_ZERO_ERROR;
DecimalFormat *thaiCurrency = (DecimalFormat*)NumberFormat::createCurrencyInstance(
Locale("th", "TH"), status);
- UChar posPrefix = 0x0e3f;
+ UnicodeString posPrefix("THB", 3, US_INV); // per cldrbug 7618
UnicodeString temp;
if(U_FAILURE(status) || !thaiCurrency)
{
- errln("Couldn't get th_TH currency -> " + UnicodeString(u_errorName(status)));
+ dataerrln("Couldn't get th_TH currency -> " + UnicodeString(u_errorName(status)));
return;
}
- if (thaiCurrency->getPositivePrefix(temp) != UnicodeString(&posPrefix, 1, 1))
- errln("Thai currency prefix wrong: expected 0x0e3f, got \"" +
+ if (thaiCurrency->getPositivePrefix(temp) != posPrefix)
+ errln("Thai currency prefix wrong: expected THB, got \"" +
thaiCurrency->getPositivePrefix(temp) + "\"");
if (thaiCurrency->getPositiveSuffix(temp) != "")
errln("Thai currency suffix wrong: expected \"\", got \"" +
UnicodeString temp;
NumberFormat *nf = NumberFormat::createCurrencyInstance(loc, status);
UnicodeString pos;
+
+ if (U_FAILURE(status)) {
+ dataerrln("Error calling NumberFormat::createCurrencyInstance(%s)", *locales);
+ continue;
+ }
+
nf->format(271828.182845, pos);
UnicodeString neg;
nf->format(-271828.182845, neg);
ucurr_forLocale("en_US", tmp, 4, &status);
resultStr.setTo(tmp);
if (dollarStr != resultStr) {
- errln("Fail: en_US didn't return USD");
+ errcheckln(status, "Fail: en_US didn't return USD - %s", u_errorName(status));
}
ucurr_forLocale("en_US_EURO", tmp, 4, &status);
resultStr.setTo(tmp);
if (euroStr != resultStr) {
- errln("Fail: en_US_EURO didn't return EUR");
+ errcheckln(status, "Fail: en_US_EURO didn't return EUR - %s", u_errorName(status));
}
ucurr_forLocale("en_GB_EURO", tmp, 4, &status);
resultStr.setTo(tmp);
if (euroStr != resultStr) {
- errln("Fail: en_GB_EURO didn't return EUR");
+ errcheckln(status, "Fail: en_GB_EURO didn't return EUR - %s", u_errorName(status));
}
ucurr_forLocale("en_US_PREEURO", tmp, 4, &status);
resultStr.setTo(tmp);
if (dollarStr != resultStr) {
- errln("Fail: en_US_PREEURO didn't fallback to en_US");
+ errcheckln(status, "Fail: en_US_PREEURO didn't fallback to en_US - %s", u_errorName(status));
}
ucurr_forLocale("en_US_Q", tmp, 4, &status);
resultStr.setTo(tmp);
if (dollarStr != resultStr) {
- errln("Fail: en_US_Q didn't fallback to en_US");
+ errcheckln(status, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status));
}
int32_t invalidLen = ucurr_forLocale("en_QQ", tmp, 4, &status);
if (invalidLen || U_SUCCESS(status)) {
errln("Fail: en_QQ didn't return NULL");
}
+
+ // The currency keyword value is as long as the destination buffer.
+ // It should detect the overflow internally, and default to the locale's currency.
+ tmp[0] = u'¤';
+ status = U_ZERO_ERROR;
+ int32_t length = ucurr_forLocale("en_US@currency=euro", tmp, 4, &status);
+ if (U_FAILURE(status) || dollarStr != UnicodeString(tmp, length)) {
+ if (U_SUCCESS(status) && tmp[0] == u'¤') {
+ errln("Fail: ucurr_forLocale(en_US@currency=euro) succeeded without writing output");
+ } else {
+ errln("Fail: ucurr_forLocale(en_US@currency=euro) != USD - %s", u_errorName(status));
+ }
+ }
}
#endif
UDate mydate = date(98,3,13); // A Monday
UErrorCode status = U_ZERO_ERROR;
SimpleDateFormat df_full("EEEE", mylocale, status);
+ if(U_FAILURE(status)){
+ dataerrln(UnicodeString("Could not create SimpleDateFormat object for locale hu. Error: ") + UnicodeString(u_errorName(status)));
+ return;
+ }
UnicodeString str;
FieldPosition pos(FieldPosition::DONT_CARE);
df_full.format(mydate, str, pos);
UChar ocf = 0x00f4;
UChar oda = 0x0151;
if (str.indexOf(oda) < 0 || str.indexOf(ocf) >= 0) {
- errln("Fail: Monday in Hungarian is wrong - oda's index is %d and ocf's is %d",
- str.indexOf(oda), str.indexOf(ocf));
+ /* If the default locale is "th" this test will fail because of the buddhist calendar. */
+ if (strcmp(Locale::getDefault().getLanguage(), "th") != 0) {
+ errln("Fail: Monday in Hungarian is wrong - oda's index is %d and ocf's is %d",
+ str.indexOf(oda), str.indexOf(ocf));
+ } else {
+ logln(UnicodeString("An error is produce in buddhist calendar."));
+ }
logln(UnicodeString("String is: ") + str );
}
}
Calendar *cal = Calendar::createInstance(Locale("ru", "", ""), status);
if(U_SUCCESS(status)) {
if (cal->getFirstDayOfWeek(status) != UCAL_MONDAY) {
- errln("Fail: First day of week in Russia should be Monday");
+ dataerrln("Fail: First day of week in Russia should be Monday");
}
}
delete cal;
UnicodeString temp;
// Try with codes that are the wrong length but happen to match text
// at a valid offset in the mapping table
- Locale locale("aaa", "CCC");
+ Locale locale("xxx", "CCC");
const char *result = locale.getISO3Country();
UnicodeString temp;
// Try with codes that are the wrong length but happen to match text
// at a valid offset in the mapping table
- Locale locale("aaa", "CCC");
+ Locale locale("xxx", "CCC");
const char *result = locale.getISO3Language();
"norsk (Noreg, NY)"
//"Norsk (Noreg, Nynorsk)"
};
+ UErrorCode status = U_ZERO_ERROR;
+ Locale saveLocale;
+ Locale::setDefault(Locale::getEnglish(), status);
for (int32_t i = 0; i < 3; ++i) {
Locale loc = locales[i];
UnicodeString temp;
if (loc.getDisplayName(temp) != englishDisplayNames[i])
- errln("English display-name mismatch: expected " +
+ dataerrln("English display-name mismatch: expected " +
englishDisplayNames[i] + ", got " + loc.getDisplayName(temp));
if (loc.getDisplayName(loc, temp) != norwegianDisplayNames[i])
- errln("Norwegian display-name mismatch: expected " +
+ dataerrln("Norwegian display-name mismatch: expected " +
norwegianDisplayNames[i] + ", got " +
loc.getDisplayName(loc, temp));
}
+ Locale::setDefault(saveLocale, status);
}
void
en_US_custom.getDisplayName(Locale::getUS(), got);
if(got != dispName) {
- errln("FAIL: getDisplayName()");
- errln("Wanted: " + dispName);
- errln("Got : " + got);
+ dataerrln("FAIL: getDisplayName()");
+ dataerrln("Wanted: " + dispName);
+ dataerrln("Got : " + got);
}
Locale shortVariant("fr", "FR", "foo");
for (int32_t i = 0; i < 4; ++i) {
NumberFormat *fmt = NumberFormat::createPercentInstance(LOC[i], status);
if(U_FAILURE(status)) {
- errln("Couldn't create NumberFormat");
+ dataerrln("Couldn't create NumberFormat - %s", u_errorName(status));
return;
}
UnicodeString result;
- FieldPosition pos(0);
+ FieldPosition pos(FieldPosition::DONT_CARE);
fmt->format((int32_t)1, result, pos);
UnicodeString temp;
if(result != "100%") {
void
LocaleTest::TestKeywordVariants(void) {
- struct {
+ static const struct {
const char *localeID;
const char *expectedLocaleID;
//const char *expectedLocaleIDNoKeywords;
const UnicodeString *keywordString;
int32_t keywordLen = 0;
- for(i = 0; i < (int32_t)(sizeof(testCases)/sizeof(testCases[0])); i++) {
+ for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
status = U_ZERO_ERROR;
Locale l(testCases[i].localeID);
keywords = l.createKeywords(status);
}
}
}
+ keywords->reset(status); // Make sure that reset works.
+ for(j = 0;;) {
+ if((keyword = keywords->next(&keywordLen, status)) == NULL) {
+ break;
+ }
+ if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) {
+ err("Expected to get keyword value %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
+ }
+ j++;
+ }
}
delete keywords;
}
void
LocaleTest::TestKeywordVariantParsing(void) {
- struct {
+ static const struct {
const char *localeID;
const char *keyword;
const char *expectedValue;
int32_t resultLen = 0;
char buffer[256];
- for(i = 0; i < (int32_t)(sizeof(testCases)/sizeof(testCases[0])); i++) {
+ for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
*buffer = 0;
Locale l(testCases[i].localeID);
resultLen = l.getKeywordValue(testCases[i].keyword, buffer, 256, status);
+ (void)resultLen; // Suppress unused variable warning.
if(uprv_strcmp(testCases[i].expectedValue, buffer) != 0) {
err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
testCases[i].expectedValue, testCases[i].localeID, testCases[i].keyword, buffer);
}
}
+void
+LocaleTest::TestSetKeywordValue(void) {
+ static const struct {
+ const char *keyword;
+ const char *value;
+ } testCases[] = {
+ { "collation", "phonebook" },
+ { "currency", "euro" },
+ { "calendar", "buddhist" }
+ };
+
+ UErrorCode status = U_ZERO_ERROR;
+
+ int32_t i = 0;
+ int32_t resultLen = 0;
+ char buffer[256];
+
+ Locale l(Locale::getGerman());
+
+ for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
+ l.setKeywordValue(testCases[i].keyword, testCases[i].value, status);
+ if(U_FAILURE(status)) {
+ err("FAIL: Locale::setKeywordValue failed - %s\n", u_errorName(status));
+ }
+
+ *buffer = 0;
+ resultLen = l.getKeywordValue(testCases[i].keyword, buffer, 256, status);
+ (void)resultLen; // Suppress unused variable warning.
+ if(uprv_strcmp(testCases[i].value, buffer) != 0) {
+ err("Expected to extract \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
+ testCases[i].value, testCases[i].keyword, buffer);
+ }
+ }
+}
+
void
LocaleTest::TestGetBaseName(void) {
- struct {
+ static const struct {
const char *localeID;
const char *baseName;
} testCases[] = {
{ "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
{ "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
- { "ja@calendar = buddhist", "ja" }
+ { "ja@calendar = buddhist", "ja" },
+ { "de-u-co-phonebk", "de"}
};
int32_t i = 0;
- for(i = 0; i < (int32_t)(sizeof(testCases)/sizeof(testCases[0])); i++) {
+ for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
Locale loc(testCases[i].localeID);
if(strcmp(testCases[i].baseName, loc.getBaseName())) {
errln("For locale \"%s\" expected baseName \"%s\", but got \"%s\"",
return;
}
}
+
+ // Verify that adding a keyword to an existing Locale doesn't change the base name.
+ UErrorCode status = U_ZERO_ERROR;
+ Locale loc2("en-US");
+ if (strcmp("en_US", loc2.getBaseName())) {
+ errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__, __LINE__, loc2.getBaseName());
+ }
+ loc2.setKeywordValue("key", "value", status);
+ if (strcmp("en_US@key=value", loc2.getName())) {
+ errln("%s:%d Expected \"en_US@key=value\", got \"%s\"", __FILE__, __LINE__, loc2.getName());
+ }
+ if (strcmp("en_US", loc2.getBaseName())) {
+ errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__, __LINE__, loc2.getBaseName());
+ }
}
/**
logln("%s; req=%s, valid=%s, actual=%s",
label, req, valid, actual);
} else {
- errln("FAIL: %s; req=%s, valid=%s, actual=%s. Require (R %s V) and (V %s A)",
+ dataerrln("FAIL: %s; req=%s, valid=%s, actual=%s. Require (R %s V) and (V %s A)",
label, req, valid, actual,
expReqValid, expValidActual);
}
void LocaleTest::TestGetLocale(void) {
#if !UCONFIG_NO_SERVICE
- UErrorCode ec = U_ZERO_ERROR;
const char *req;
Locale valid, actual, reqLoc;
// Calendar
#if !UCONFIG_NO_FORMATTING
- req = "en_US_BROOKLYN";
- Calendar* cal = Calendar::createInstance(Locale::createFromName(req), ec);
- if (U_FAILURE(ec)) {
- errln("FAIL: Calendar::createInstance failed");
- } else {
- valid = cal->getLocale(ULOC_VALID_LOCALE, ec);
- actual = cal->getLocale(ULOC_ACTUAL_LOCALE, ec);
+ {
+ UErrorCode ec = U_ZERO_ERROR; // give each resource type its own error code
+ req = "en_US_BROOKLYN";
+ Calendar* cal = Calendar::createInstance(Locale::createFromName(req), ec);
if (U_FAILURE(ec)) {
- errln("FAIL: Calendar::getLocale() failed");
+ dataerrln("FAIL: Calendar::createInstance failed - %s", u_errorName(ec));
} else {
- _checklocs("Calendar", req, valid, actual);
+ valid = cal->getLocale(ULOC_VALID_LOCALE, ec);
+ actual = cal->getLocale(ULOC_ACTUAL_LOCALE, ec);
+ if (U_FAILURE(ec)) {
+ errln("FAIL: Calendar::getLocale() failed");
+ } else {
+ _checklocs("Calendar", req, valid, actual);
+ }
+ /* Make sure that it fails correctly */
+ ec = U_FILE_ACCESS_ERROR;
+ if (cal->getLocale(ULOC_VALID_LOCALE, ec).getName()[0] != 0) {
+ errln("FAIL: Calendar::getLocale() failed to fail correctly. It should have returned \"\"");
+ }
+ ec = U_ZERO_ERROR;
}
+ delete cal;
}
- delete cal;
#endif
// DecimalFormat, DecimalFormatSymbols
#if !UCONFIG_NO_FORMATTING
- req = "fr_FR_NICE";
- DecimalFormat* dec = (DecimalFormat*)
- NumberFormat::createInstance(Locale::createFromName(req), ec);
- U_ASSERT(dec->getDynamicClassID() == DecimalFormat::getStaticClassID());
- if (U_FAILURE(ec)) {
- errln("FAIL: NumberFormat::createInstance failed");
- } else {
- valid = dec->getLocale(ULOC_VALID_LOCALE, ec);
- actual = dec->getLocale(ULOC_ACTUAL_LOCALE, ec);
+ {
+ UErrorCode ec = U_ZERO_ERROR; // give each resource type its own error code
+ req = "fr_FR_NICE";
+ NumberFormat* nf = NumberFormat::createInstance(Locale::createFromName(req), ec);
if (U_FAILURE(ec)) {
- errln("FAIL: DecimalFormat::getLocale() failed");
+ dataerrln("FAIL: NumberFormat::createInstance failed - %s", u_errorName(ec));
} else {
- _checklocs("DecimalFormat", req, valid, actual);
- }
+ DecimalFormat* dec = dynamic_cast<DecimalFormat*>(nf);
+ if (dec == NULL) {
+ errln("FAIL: NumberFormat::createInstance does not return a DecimalFormat");
+ return;
+ }
+ valid = dec->getLocale(ULOC_VALID_LOCALE, ec);
+ actual = dec->getLocale(ULOC_ACTUAL_LOCALE, ec);
+ if (U_FAILURE(ec)) {
+ errln("FAIL: DecimalFormat::getLocale() failed");
+ } else {
+ _checklocs("DecimalFormat", req, valid, actual);
+ }
- const DecimalFormatSymbols* sym = dec->getDecimalFormatSymbols();
- U_ASSERT(sym != 0);
- valid = sym->getLocale(ULOC_VALID_LOCALE, ec);
- actual = sym->getLocale(ULOC_ACTUAL_LOCALE, ec);
- if (U_FAILURE(ec)) {
- errln("FAIL: DecimalFormatSymbols::getLocale() failed");
- } else {
- _checklocs("DecimalFormatSymbols", req, valid, actual);
- }
+ const DecimalFormatSymbols* sym = dec->getDecimalFormatSymbols();
+ if (sym == NULL) {
+ errln("FAIL: getDecimalFormatSymbols returned NULL");
+ return;
+ }
+ valid = sym->getLocale(ULOC_VALID_LOCALE, ec);
+ actual = sym->getLocale(ULOC_ACTUAL_LOCALE, ec);
+ if (U_FAILURE(ec)) {
+ errln("FAIL: DecimalFormatSymbols::getLocale() failed");
+ } else {
+ _checklocs("DecimalFormatSymbols", req, valid, actual);
+ }
+ }
+ delete nf;
}
- delete dec;
#endif
// DateFormat, DateFormatSymbols
#if !UCONFIG_NO_FORMATTING
- req = "de_CH_LUCERNE";
- SimpleDateFormat* dat = (SimpleDateFormat*)
- DateFormat::createDateInstance(DateFormat::kDefault,
- Locale::createFromName(req));
- U_ASSERT(dat != 0);
- U_ASSERT(dat->getDynamicClassID() == SimpleDateFormat::getStaticClassID());
- valid = dat->getLocale(ULOC_VALID_LOCALE, ec);
- actual = dat->getLocale(ULOC_ACTUAL_LOCALE, ec);
- if (U_FAILURE(ec)) {
- errln("FAIL: SimpleDateFormat::getLocale() failed");
- } else {
- _checklocs("SimpleDateFormat", req, valid, actual);
- }
+ {
+ UErrorCode ec = U_ZERO_ERROR; // give each resource type its own error code
+ req = "de_CH_LUCERNE";
+ DateFormat* df =
+ DateFormat::createDateInstance(DateFormat::kDefault,
+ Locale::createFromName(req));
+ if (df == 0){
+ dataerrln("Error calling DateFormat::createDateInstance()");
+ } else {
+ SimpleDateFormat* dat = dynamic_cast<SimpleDateFormat*>(df);
+ if (dat == NULL) {
+ errln("FAIL: DateFormat::createInstance does not return a SimpleDateFormat");
+ return;
+ }
+ valid = dat->getLocale(ULOC_VALID_LOCALE, ec);
+ actual = dat->getLocale(ULOC_ACTUAL_LOCALE, ec);
+ if (U_FAILURE(ec)) {
+ errln("FAIL: SimpleDateFormat::getLocale() failed");
+ } else {
+ _checklocs("SimpleDateFormat", req, valid, actual);
+ }
- const DateFormatSymbols* sym = dat->getDateFormatSymbols();
- U_ASSERT(sym != 0);
- valid = sym->getLocale(ULOC_VALID_LOCALE, ec);
- actual = sym->getLocale(ULOC_ACTUAL_LOCALE, ec);
- if (U_FAILURE(ec)) {
- errln("FAIL: DateFormatSymbols::getLocale() failed");
- } else {
- _checklocs("DateFormatSymbols", req, valid, actual);
- }
- delete dat;
+ const DateFormatSymbols* sym = dat->getDateFormatSymbols();
+ if (sym == NULL) {
+ errln("FAIL: getDateFormatSymbols returned NULL");
+ return;
+ }
+ valid = sym->getLocale(ULOC_VALID_LOCALE, ec);
+ actual = sym->getLocale(ULOC_ACTUAL_LOCALE, ec);
+ if (U_FAILURE(ec)) {
+ errln("FAIL: DateFormatSymbols::getLocale() failed");
+ } else {
+ _checklocs("DateFormatSymbols", req, valid, actual);
+ }
+ }
+ delete df;
+ }
#endif
// BreakIterator
#if !UCONFIG_NO_BREAK_ITERATION
- req = "es_ES_BARCELONA";
- reqLoc = Locale::createFromName(req);
- BreakIterator* brk = BreakIterator::createWordInstance(reqLoc, ec);
- if (U_FAILURE(ec)) {
- errln("FAIL: BreakIterator::createWordInstance failed");
- } else {
- valid = brk->getLocale(ULOC_VALID_LOCALE, ec);
- actual = brk->getLocale(ULOC_ACTUAL_LOCALE, ec);
+ {
+ UErrorCode ec = U_ZERO_ERROR; // give each resource type its own error code
+ req = "es_ES_BARCELONA";
+ reqLoc = Locale::createFromName(req);
+ BreakIterator* brk = BreakIterator::createWordInstance(reqLoc, ec);
if (U_FAILURE(ec)) {
- errln("FAIL: BreakIterator::getLocale() failed");
+ dataerrln("FAIL: BreakIterator::createWordInstance failed - %s", u_errorName(ec));
} else {
- _checklocs("BreakIterator", req, valid, actual);
- }
+ valid = brk->getLocale(ULOC_VALID_LOCALE, ec);
+ actual = brk->getLocale(ULOC_ACTUAL_LOCALE, ec);
+ if (U_FAILURE(ec)) {
+ errln("FAIL: BreakIterator::getLocale() failed");
+ } else {
+ _checklocs("BreakIterator", req, valid, actual);
+ }
- // After registering something, the behavior should be different
- URegistryKey key = BreakIterator::registerInstance(brk, reqLoc, UBRK_WORD, ec);
- brk = 0; // registerInstance adopts
- if (U_FAILURE(ec)) {
- errln("FAIL: BreakIterator::registerInstance() failed");
- } else {
+ // After registering something, the behavior should be different
+ URegistryKey key = BreakIterator::registerInstance(brk, reqLoc, UBRK_WORD, ec);
+ brk = 0; // registerInstance adopts
+ if (U_FAILURE(ec)) {
+ errln("FAIL: BreakIterator::registerInstance() failed");
+ } else {
+ brk = BreakIterator::createWordInstance(reqLoc, ec);
+ if (U_FAILURE(ec)) {
+ errln("FAIL: BreakIterator::createWordInstance failed");
+ } else {
+ valid = brk->getLocale(ULOC_VALID_LOCALE, ec);
+ actual = brk->getLocale(ULOC_ACTUAL_LOCALE, ec);
+ if (U_FAILURE(ec)) {
+ errln("FAIL: BreakIterator::getLocale() failed");
+ } else {
+ // N.B.: now expect valid==actual==req
+ _checklocs("BreakIterator(registered)",
+ req, valid, actual, "eq", "eq");
+ }
+ }
+ // No matter what, unregister
+ BreakIterator::unregister(key, ec);
+ if (U_FAILURE(ec)) {
+ errln("FAIL: BreakIterator::unregister() failed");
+ }
+ delete brk;
+ brk = 0;
+ }
+
+ // After unregistering, should behave normally again
brk = BreakIterator::createWordInstance(reqLoc, ec);
if (U_FAILURE(ec)) {
errln("FAIL: BreakIterator::createWordInstance failed");
if (U_FAILURE(ec)) {
errln("FAIL: BreakIterator::getLocale() failed");
} else {
- // N.B.: now expect valid==actual==req
- _checklocs("BreakIterator(registered)",
- req, valid, actual, "eq", "eq");
+ _checklocs("BreakIterator(unregistered)", req, valid, actual);
}
}
- // No matter what, unregister
- BreakIterator::unregister(key, ec);
- if (U_FAILURE(ec)) {
- errln("FAIL: BreakIterator::unregister() failed");
- }
- delete brk;
- brk = 0;
- }
-
- // After unregistering, should behave normally again
- brk = BreakIterator::createWordInstance(reqLoc, ec);
- if (U_FAILURE(ec)) {
- errln("FAIL: BreakIterator::createWordInstance failed");
- } else {
- valid = brk->getLocale(ULOC_VALID_LOCALE, ec);
- actual = brk->getLocale(ULOC_ACTUAL_LOCALE, ec);
- if (U_FAILURE(ec)) {
- errln("FAIL: BreakIterator::getLocale() failed");
- } else {
- _checklocs("BreakIterator(unregistered)", req, valid, actual);
- }
}
+ delete brk;
}
- delete brk;
#endif
// Collator
#if !UCONFIG_NO_COLLATION
- req = "hi_IN_BHOPAL";
- reqLoc = Locale::createFromName(req);
- Collator* coll = Collator::createInstance(reqLoc, ec);
- if (U_FAILURE(ec)) {
- errln("FAIL: Collator::createInstance failed");
- } else {
- valid = coll->getLocale(ULOC_VALID_LOCALE, ec);
- actual = coll->getLocale(ULOC_ACTUAL_LOCALE, ec);
- if (U_FAILURE(ec)) {
- errln("FAIL: Collator::getLocale() failed");
- } else {
- _checklocs("Collator", req, valid, actual);
- }
+ {
+ UErrorCode ec = U_ZERO_ERROR; // give each resource type its own error code
+
+ checkRegisteredCollators(NULL); // Don't expect any extras
- // After registering something, the behavior should be different
- URegistryKey key = Collator::registerInstance(coll, reqLoc, ec);
- coll = 0; // registerInstance adopts
+ req = "hi_IN_BHOPAL";
+ reqLoc = Locale::createFromName(req);
+ Collator* coll = Collator::createInstance(reqLoc, ec);
if (U_FAILURE(ec)) {
- errln("FAIL: Collator::registerInstance() failed");
+ dataerrln("FAIL: Collator::createInstance failed - %s", u_errorName(ec));
} else {
+ valid = coll->getLocale(ULOC_VALID_LOCALE, ec);
+ actual = coll->getLocale(ULOC_ACTUAL_LOCALE, ec);
+ if (U_FAILURE(ec)) {
+ errln("FAIL: Collator::getLocale() failed");
+ } else {
+ _checklocs("Collator", req, valid, actual);
+ }
+
+ // After registering something, the behavior should be different
+ URegistryKey key = Collator::registerInstance(coll, reqLoc, ec);
+ coll = 0; // registerInstance adopts
+ if (U_FAILURE(ec)) {
+ errln("FAIL: Collator::registerInstance() failed");
+ } else {
+ coll = Collator::createInstance(reqLoc, ec);
+ if (U_FAILURE(ec)) {
+ errln("FAIL: Collator::createWordInstance failed");
+ } else {
+ valid = coll->getLocale(ULOC_VALID_LOCALE, ec);
+ actual = coll->getLocale(ULOC_ACTUAL_LOCALE, ec);
+ if (U_FAILURE(ec)) {
+ errln("FAIL: Collator::getLocale() failed");
+ } else {
+ // N.B.: now expect valid==actual==req
+ _checklocs("Collator(registered)",
+ req, valid, actual, "eq", "eq");
+ }
+ }
+ checkRegisteredCollators(req); // include hi_IN_BHOPAL
+
+ // No matter what, unregister
+ Collator::unregister(key, ec);
+ if (U_FAILURE(ec)) {
+ errln("FAIL: Collator::unregister() failed");
+ }
+ delete coll;
+ coll = 0;
+ }
+
+ // After unregistering, should behave normally again
coll = Collator::createInstance(reqLoc, ec);
if (U_FAILURE(ec)) {
- errln("FAIL: Collator::createWordInstance failed");
+ errln("FAIL: Collator::createInstance failed");
} else {
valid = coll->getLocale(ULOC_VALID_LOCALE, ec);
actual = coll->getLocale(ULOC_ACTUAL_LOCALE, ec);
if (U_FAILURE(ec)) {
errln("FAIL: Collator::getLocale() failed");
} else {
- // N.B.: now expect valid==actual==req
- _checklocs("Collator(registered)",
- req, valid, actual, "eq", "eq");
+ _checklocs("Collator(unregistered)", req, valid, actual);
}
}
- // No matter what, unregister
- Collator::unregister(key, ec);
- if (U_FAILURE(ec)) {
- errln("FAIL: Collator::unregister() failed");
- }
- delete coll;
- coll = 0;
}
+ delete coll;
- // After unregistering, should behave normally again
- coll = Collator::createInstance(reqLoc, ec);
- if (U_FAILURE(ec)) {
- errln("FAIL: Collator::createInstance failed");
- } else {
- valid = coll->getLocale(ULOC_VALID_LOCALE, ec);
- actual = coll->getLocale(ULOC_ACTUAL_LOCALE, ec);
- if (U_FAILURE(ec)) {
- errln("FAIL: Collator::getLocale() failed");
+ checkRegisteredCollators(NULL); // extra should be gone again
+ }
+#endif
+#endif
+}
+
+#if !UCONFIG_NO_COLLATION
+/**
+ * Compare Collator::getAvailableLocales(int) [ "old", returning an array ]
+ * with Collator::getAvailableLocales() [ "new", returning a StringEnumeration ]
+ * These should be identical (check their API docs) EXCEPT that
+ * if expectExtra is non-NULL, it will be in the "new" array but not "old".
+ * Does not return any status but calls errln on error.
+ * @param expectExtra an extra locale, will be in "new" but not "old". Or NULL.
+ */
+void LocaleTest::checkRegisteredCollators(const char *expectExtra) {
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t count1=0,count2=0;
+ Hashtable oldHash(status);
+ Hashtable newHash(status);
+ TEST_ASSERT_STATUS(status);
+
+ UnicodeString expectStr(expectExtra?expectExtra:"n/a", "");
+
+ // the 'old' list (non enumeration)
+ const Locale* oldList = Collator::getAvailableLocales(count1);
+ if(oldList == NULL) {
+ dataerrln("Error: Collator::getAvailableLocales(count) returned NULL");
+ return;
+ }
+
+ // the 'new' list (enumeration)
+ LocalPointer<StringEnumeration> newEnum(Collator::getAvailableLocales());
+ if(newEnum.isNull()) {
+ errln("Error: collator::getAvailableLocales() returned NULL");
+ return;
+ }
+
+ // OK. Let's add all of the OLD
+ // then check for any in the NEW not in OLD
+ // then check for any in OLD not in NEW.
+
+ // 1. add all of OLD
+ for(int32_t i=0;i<count1;i++) {
+ const UnicodeString key(oldList[i].getName(), "");
+ int32_t oldI = oldHash.puti(key, 1, status);
+ if( oldI == 1 ){
+ errln("Error: duplicate key %s in Collator::getAvailableLocales(count) list.\n",
+ oldList[i].getName());
+ return;
+ }
+ if(expectExtra != NULL && !strcmp(expectExtra, oldList[i].getName())) {
+ errln("Inexplicably, Collator::getAvailableCollators(count) had registered collator %s. This shouldn't happen, so I am going to consider it an error.\n", expectExtra);
+ }
+ }
+
+ // 2. add all of NEW
+ const UnicodeString *locStr;
+ UBool foundExpected = FALSE;
+ while((locStr = newEnum->snext(status)) && U_SUCCESS(status)) {
+ count2++;
+
+ if(expectExtra != NULL && expectStr == *locStr) {
+ foundExpected = TRUE;
+ logln(UnicodeString("Found expected registered collator: ","") + expectStr);
+ }
+ (void)foundExpected; // Hush unused variable compiler warning.
+
+ if( oldHash.geti(*locStr) == 0 ) {
+ if(expectExtra != NULL && expectStr==*locStr) {
+ logln(UnicodeString("As expected, Collator::getAvailableLocales(count) is missing registered collator ") + expectStr);
} else {
- _checklocs("Collator(unregistered)", req, valid, actual);
+ errln(UnicodeString("Error: Collator::getAvailableLocales(count) is missing: ","")
+ + *locStr);
}
}
+ newHash.puti(*locStr, 1, status);
}
- delete coll;
-#endif
-#endif
+
+ // 3. check all of OLD again
+ for(int32_t i=0;i<count1;i++) {
+ const UnicodeString key(oldList[i].getName(), "");
+ int32_t newI = newHash.geti(key);
+ if(newI == 0) {
+ errln(UnicodeString("Error: Collator::getAvailableLocales() is missing: ","")
+ + key);
+ }
+ }
+
+ int32_t expectCount2 = count1;
+ if(expectExtra != NULL) {
+ expectCount2 ++; // if an extra item registered, bump the expect count
+ }
+
+ assertEquals("Collator::getAvail() count", expectCount2, count2);
}
+#endif
+
+
void LocaleTest::TestVariantWithOutCountry(void) {
Locale loc("en","","POSIX");
if (0 != strcmp(loc.getVariant(), "POSIX")) {
- errln("FAIL: en__POSIX didn't get parsed correctly");
+ errln("FAIL: en__POSIX didn't get parsed correctly - name is %s - expected %s got %s", loc.getName(), "POSIX", loc.getVariant());
}
Locale loc2("en","","FOUR");
if (0 != strcmp(loc2.getVariant(), "FOUR")) {
- errln("FAIL: en__FOUR didn't get parsed correctly");
+ errln("FAIL: en__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc2.getName(), "FOUR", loc2.getVariant());
}
Locale loc3("en","Latn","","FOUR");
if (0 != strcmp(loc3.getVariant(), "FOUR")) {
- errln("FAIL: en_Latn__FOUR didn't get parsed correctly");
+ errln("FAIL: en_Latn__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc3.getName(), "FOUR", loc3.getVariant());
}
Locale loc4("","Latn","","FOUR");
if (0 != strcmp(loc4.getVariant(), "FOUR")) {
- errln("FAIL: _Latn__FOUR didn't get parsed correctly");
+ errln("FAIL: _Latn__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc4.getName(), "FOUR", loc4.getVariant());
}
Locale loc5("","Latn","US","FOUR");
if (0 != strcmp(loc5.getVariant(), "FOUR")) {
- errln("FAIL: _Latn_US_FOUR didn't get parsed correctly");
+ errln("FAIL: _Latn_US_FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc5.getName(), "FOUR", loc5.getVariant());
+ }
+ Locale loc6("de-1901");
+ if (0 != strcmp(loc6.getVariant(), "1901")) {
+ errln("FAIL: de-1901 didn't get parsed correctly - name is %s - expected %s got %s", loc6.getName(), "1901", loc6.getVariant());
}
}
void LocaleTest::TestCanonicalization(void)
{
- static struct {
+ static const struct {
const char *localeID; /* input */
const char *getNameID; /* expected getName() result */
const char *canonicalID; /* expected canonicalize() result */
} testCases[] = {
+ { "", "", "en_US_POSIX" },
+ { "C", "c", "en_US_POSIX" },
+ { "POSIX", "posix", "en_US_POSIX" },
{ "ca_ES_PREEURO-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
"ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
"ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
{ "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ@currency=EUR" }, /* qz-qz uses private use iso codes */
// NOTE: uloc_getName() works on en-BOONT, but Locale() parser considers it BOGUS
// TODO: unify this behavior
- { "en-BOONT", "BOGUS", "en__BOONT" }, /* registered name */
- { "de-1901", "de_1901", "de__1901" }, /* registered name */
- { "de-1906", "de_1906", "de__1906" }, /* registered name */
- { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_SP" }, /* .NET name */
- { "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_SP" }, /* .NET name */
+ { "en-BOONT", "en__BOONT", "en__BOONT" }, /* registered name */
+ { "de-1901", "de__1901", "de__1901" }, /* registered name */
+ { "de-1906", "de__1906", "de__1906" }, /* registered name */
+ { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_RS" }, /* .NET name */
+ { "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_RS" }, /* .NET name */
+ { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_Cyrl_RS" }, /* Linux name */
{ "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_Cyrl_UZ" }, /* .NET name */
{ "uz-UZ-Latn", "uz_UZ_LATN", "uz_Latn_UZ" }, /* .NET name */
{ "zh-CHS", "zh_CHS", "zh_Hans" }, /* .NET name */
- { "zh-CHT", "zh_CHT", "zh_TW" }, /* .NET name This may change back to zh_Hant */
+ { "zh-CHT", "zh_CHT", "zh_Hant" }, /* .NET name This may change back to zh_Hant */
/* posix behavior that used to be performed by getName */
{ "mr.utf8", "mr.utf8", "mr" },
int32_t i, j;
- for (i=0; i < (int)(sizeof(testCases)/sizeof(testCases[0])); i++) {
+ for (i=0; i < UPRV_LENGTHOF(testCases); i++) {
for (j=0; j<3; ++j) {
const char* expected = (j==1) ? testCases[i].canonicalID : testCases[i].getNameID;
Locale loc = _canonicalize(j, testCases[i].localeID);
}
}
}
+
+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);
+ }
+}
+
+