mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-07 06:25:30 +00:00
ICU-21997 Fixes currency code retrieval for locale: instead of selecting the
first currency in the list now select the first legal tender currency in the list. Or the first currency if the list has no legal tender currencies (which is the previous behaviour). ICU-21997 Removed an overlooked earlier unit test attempt. ICU-21997 Shields C++ unit test from compilation when configuration flag UCONFIG_NO_FORMATTING is set.
This commit is contained in:
parent
c5872e7f67
commit
5a77fd9d11
5 changed files with 63 additions and 4 deletions
|
@ -566,9 +566,32 @@ ucurr_forLocale(const char* locale,
|
|||
UResourceBundle *rb = ures_openDirect(U_ICUDATA_CURR, CURRENCY_DATA, &localStatus);
|
||||
UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus);
|
||||
UResourceBundle *countryArray = ures_getByKey(rb, id, cm, &localStatus);
|
||||
UResourceBundle *currencyReq = ures_getByIndex(countryArray, 0, NULL, &localStatus);
|
||||
s = ures_getStringByKey(currencyReq, "id", &resLen, &localStatus);
|
||||
ures_close(currencyReq);
|
||||
// https://unicode-org.atlassian.net/browse/ICU-21997
|
||||
// Prefer to use currencies that are legal tender.
|
||||
if (U_SUCCESS(localStatus)) {
|
||||
int32_t arrayLength = ures_getSize(countryArray);
|
||||
for (int32_t i = 0; i < arrayLength; ++i) {
|
||||
LocalUResourceBundlePointer currencyReq(
|
||||
ures_getByIndex(countryArray, i, nullptr, &localStatus));
|
||||
// The currency is legal tender if it is *not* marked with tender{"false"}.
|
||||
UErrorCode tenderStatus = localStatus;
|
||||
const UChar *tender =
|
||||
ures_getStringByKey(currencyReq.getAlias(), "tender", nullptr, &tenderStatus);
|
||||
bool isTender = U_FAILURE(tenderStatus) || u_strcmp(tender, u"false") != 0;
|
||||
if (!isTender && s != nullptr) {
|
||||
// We already have a non-tender currency. Ignore all following non-tender ones.
|
||||
continue;
|
||||
}
|
||||
// Fetch the currency code.
|
||||
s = ures_getStringByKey(currencyReq.getAlias(), "id", &resLen, &localStatus);
|
||||
if (isTender) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (U_SUCCESS(localStatus) && s == nullptr) {
|
||||
localStatus = U_MISSING_RESOURCE_ERROR;
|
||||
}
|
||||
}
|
||||
ures_close(countryArray);
|
||||
}
|
||||
|
||||
|
|
|
@ -288,6 +288,9 @@ void LocaleTest::runIndexedTest( int32_t index, UBool exec, const char* &name, c
|
|||
TESTCASE_AUTO(TestNullDereferenceWrite21597);
|
||||
TESTCASE_AUTO(TestLongLocaleSetKeywordAssign);
|
||||
TESTCASE_AUTO(TestLongLocaleSetKeywordMoveAssign);
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
TESTCASE_AUTO(TestSierraLeoneCurrency21997);
|
||||
#endif
|
||||
TESTCASE_AUTO_END;
|
||||
}
|
||||
|
||||
|
@ -6614,3 +6617,19 @@ void LocaleTest::TestNullDereferenceWrite21597() {
|
|||
l.canonicalize(status);
|
||||
status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR);
|
||||
}
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
void LocaleTest::TestSierraLeoneCurrency21997() {
|
||||
// Check that currency of Sierra Leone is SLL (which is legal tender)
|
||||
// and not the newer currency SLE (which is not legal tender), as of CLDR 41.
|
||||
// Test will fail once SLE is declared legal.
|
||||
UnicodeString sllStr("SLL", ""), resultStr;
|
||||
UChar tmp[4];
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
ucurr_forLocale("en_SL", tmp, 4, &status);
|
||||
resultStr.setTo(tmp);
|
||||
if (sllStr != resultStr) {
|
||||
errcheckln(status, "Fail: en_SL didn't return SLL - %s", u_errorName(status));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -160,6 +160,7 @@ public:
|
|||
void TestNullDereferenceWrite21597();
|
||||
void TestLongLocaleSetKeywordAssign();
|
||||
void TestLongLocaleSetKeywordMoveAssign();
|
||||
void TestSierraLeoneCurrency21997();
|
||||
|
||||
private:
|
||||
void _checklocs(const char* label,
|
||||
|
|
|
@ -278,7 +278,12 @@ public class Currency extends MeasureUnit {
|
|||
private static Currency loadCurrency(String key) {
|
||||
String region = key;
|
||||
CurrencyMetaInfo info = CurrencyMetaInfo.getInstance();
|
||||
List<String> list = info.currencies(CurrencyFilter.onRegion(region));
|
||||
// https://unicode-org.atlassian.net/browse/ICU-21997
|
||||
// Prefer to use currencies that are legal tender.
|
||||
List<String> list = info.currencies(CurrencyFilter.onRegion(region).withTender());
|
||||
if (list.isEmpty()) {
|
||||
list = info.currencies(CurrencyFilter.onRegion(region));
|
||||
}
|
||||
if (!list.isEmpty()) {
|
||||
String code = list.get(0);
|
||||
return getInstance(code);
|
||||
|
|
|
@ -983,4 +983,15 @@ public class CurrencyTest extends TestFmwk {
|
|||
public void TestCurrencyDataCtor() throws Exception {
|
||||
checkDefaultPrivateConstructor(CurrencyData.class);
|
||||
}
|
||||
@Test
|
||||
public void testSierraLeoneCurrency21997() {
|
||||
// Check that currency of Sierra Leone is SLL (which is legal tender)
|
||||
// and not the newer currency SLE (which is not legal tender), as of CLDR 41.
|
||||
// Test will fail once SLE is declared legal.
|
||||
Currency currency = Currency.getInstance(ULocale.forLanguageTag("en-SL"));
|
||||
String result = currency.getCurrencyCode();
|
||||
if (!"SLL".equals(result)) {
|
||||
errln("Currency code of en-SL is not SLL but " + result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue