ICU-20484 Narrow currency symbol should fall back to short symbol, C and J.

- Includes fixes to tests.
This commit is contained in:
Shane Carr 2019-03-08 00:11:11 -08:00 committed by Shane F. Carr
parent f7b36d39bc
commit ffd8baf16d
8 changed files with 88 additions and 12 deletions

View File

@ -690,7 +690,13 @@ ucurr_getName(const UChar* currency,
key.append("/", ec2);
key.append(buf, ec2);
s = ures_getStringByKeyWithFallback(rb.getAlias(), key.data(), len, &ec2);
} else {
if (ec2 == U_MISSING_RESOURCE_ERROR) {
*ec = U_USING_FALLBACK_WARNING;
ec2 = U_ZERO_ERROR;
choice = UCURR_SYMBOL_NAME;
}
}
if (s == NULL) {
ures_getByKey(rb.getAlias(), CURRENCIES, rb.getAlias(), &ec2);
ures_getByKeyWithFallback(rb.getAlias(), buf, rb.getAlias(), &ec2);
s = ures_getStringByIndex(rb.getAlias(), choice, len, &ec2);

View File

@ -779,7 +779,7 @@ void NumberFormatterApiTest::unitCurrency() {
NumberFormatter::with().unit(PTE).unitWidth(UNUM_UNIT_WIDTH_NARROW),
Locale("pt-PT"),
444444.55,
u"444,444$55 PTE");
u"444,444$55 \u200B");
assertFormatSingle(
u"Currency-dependent symbols (Test ISO Code)",

View File

@ -123,6 +123,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
TESTCASE_AUTO(TestCases);
TESTCASE_AUTO(TestCurrencyNames);
TESTCASE_AUTO(Test20484_NarrowSymbolFallback);
TESTCASE_AUTO(TestCurrencyAmount);
TESTCASE_AUTO(TestCurrencyUnit);
TESTCASE_AUTO(TestCoverage);
@ -2097,6 +2098,50 @@ void NumberFormatTest::TestCurrencyNames(void) {
// TODO add more tests later
}
void NumberFormatTest::Test20484_NarrowSymbolFallback(){
IcuTestErrorCode status(*this, "Test20484_NarrowSymbolFallback");
struct TestCase {
const char* locale;
const char16_t* isoCode;
const char16_t* expectedShort;
const char16_t* expectedNarrow;
UErrorCode expectedNarrowError;
} cases[] = {
{"en-US", u"CAD", u"CA$", u"$", U_USING_DEFAULT_WARNING}, // narrow: fallback to root
{"en-US", u"CDF", u"CDF", u"CDF", U_USING_FALLBACK_WARNING}, // narrow: fallback to short
{"sw-CD", u"CDF", u"FC", u"FC", U_USING_FALLBACK_WARNING}, // narrow: fallback to short
{"en-US", u"GEL", u"GEL", u"", U_USING_DEFAULT_WARNING}, // narrow: fallback to root
{"ka-GE", u"GEL", u"", u"", U_USING_FALLBACK_WARNING}, // narrow: fallback to ka
{"ka", u"GEL", u"", u"", U_ZERO_ERROR}, // no fallback on narrow
};
for (const auto& cas : cases) {
status.setScope(cas.isoCode);
UBool choiceFormatIgnored;
int32_t lengthIgnored;
const UChar* actualShort = ucurr_getName(
cas.isoCode,
cas.locale,
UCURR_SYMBOL_NAME,
&choiceFormatIgnored,
&lengthIgnored,
status);
status.errIfFailureAndReset();
const UChar* actualNarrow = ucurr_getName(
cas.isoCode,
cas.locale,
UCURR_NARROW_SYMBOL_NAME,
&choiceFormatIgnored,
&lengthIgnored,
status);
status.expectErrorAndReset(cas.expectedNarrowError);
assertEquals(UnicodeString("Short symbol: ") + cas.locale + u": " + cas.isoCode,
cas.expectedShort, actualShort);
assertEquals(UnicodeString("Narrow symbol: ") + cas.locale + ": " + cas.isoCode,
cas.expectedNarrow, actualNarrow);
}
}
void NumberFormatTest::TestCurrencyUnit(void){
UErrorCode ec = U_ZERO_ERROR;
static const UChar USD[] = u"USD";

View File

@ -153,6 +153,8 @@ class NumberFormatTest: public CalendarTimeZoneTest {
void TestCurrencyNames(void);
void Test20484_NarrowSymbolFallback(void);
void TestCurrencyAmount(void);
void TestCurrencyUnit(void);

View File

@ -122,8 +122,8 @@ public abstract class CurrencyDisplayNames {
/**
* Returns the narrow symbol for the currency with the provided ISO code.
* If there is no data for narrow symbol, substitutes isoCode, or returns
* null if noSubstitute was set in the factory method.
* If there is no data for narrow symbol, substitutes the default symbol,
* or returns null if noSubstitute was set in the factory method.
*
* @param isoCode the three-letter ISO code.
* @return the narrow symbol.

View File

@ -95,7 +95,7 @@ public class ICUCurrencyDisplayInfoProvider implements CurrencyDisplayInfoProvid
/**
* Cache for symbolMap() and nameMap().
*/
private volatile SoftReference<ParsingData> parsingDataCache = new SoftReference<ParsingData>(null);
private volatile SoftReference<ParsingData> parsingDataCache = new SoftReference<>(null);
/**
* Cache for getUnitPatterns().
@ -124,8 +124,8 @@ public class ICUCurrencyDisplayInfoProvider implements CurrencyDisplayInfoProvid
}
static class ParsingData {
Map<String, String> symbolToIsoCode = new HashMap<String, String>();
Map<String, String> nameToIsoCode = new HashMap<String, String>();
Map<String, String> symbolToIsoCode = new HashMap<>();
Map<String, String> nameToIsoCode = new HashMap<>();
}
////////////////////////
@ -170,9 +170,8 @@ public class ICUCurrencyDisplayInfoProvider implements CurrencyDisplayInfoProvid
NarrowSymbol narrowSymbol = fetchNarrowSymbol(isoCode);
// Fall back to ISO Code
// TODO: Should this fall back to the regular symbol instead of the ISO code?
if (narrowSymbol.narrowSymbol == null && fallback) {
return isoCode;
return getSymbol(isoCode);
}
return narrowSymbol.narrowSymbol;
}
@ -289,7 +288,7 @@ public class ICUCurrencyDisplayInfoProvider implements CurrencyDisplayInfoProvid
CurrencySink sink = new CurrencySink(!fallback, CurrencySink.EntrypointTable.TOP);
sink.parsingData = result;
rb.getAllItemsWithFallback("", sink);
parsingDataCache = new SoftReference<ParsingData>(result);
parsingDataCache = new SoftReference<>(result);
}
return result;
}
@ -297,7 +296,7 @@ public class ICUCurrencyDisplayInfoProvider implements CurrencyDisplayInfoProvid
Map<String, String> fetchUnitPatterns() {
Map<String, String> result = unitPatternsCache;
if (result == null) {
result = new HashMap<String, String>();
result = new HashMap<>();
CurrencySink sink = new CurrencySink(!fallback, CurrencySink.EntrypointTable.CURRENCY_UNIT_PATTERNS);
sink.unitPatterns = result;
rb.getAllItemsWithFallback("CurrencyUnitPatterns", sink);

View File

@ -741,7 +741,7 @@ public class NumberFormatterApiTest {
NumberFormatter.with().unit(PTE).unitWidth(UnitWidth.NARROW),
ULocale.forLanguageTag("pt-PT"),
444444.55,
"444,444$55 PTE");
"444,444$55 \u200B");
assertFormatSingle(
"Currency-dependent symbols (Test)",

View File

@ -238,6 +238,30 @@ public class CurrencyTest extends TestFmwk {
USX.getName(en_US, Currency.LONG_NAME, isChoiceFormat));
}
@Test
public void test20484_NarrowSymbolFallback() {
Object[][] cases = new Object[][] {
{"en-US", "CAD", "CA$", "$"},
{"en-US", "CDF", "CDF", "CDF"},
{"sw-CD", "CDF", "FC", "FC"},
{"en-US", "GEL", "GEL", ""},
{"ka-GE", "GEL", "", ""},
{"ka", "GEL", "", ""},
};
for (Object[] cas : cases) {
ULocale locale = new ULocale((String) cas[0]);
String isoCode = (String) cas[1];
String expectedShort = (String) cas[2];
String expectedNarrow = (String) cas[3];
CurrencyDisplayNames cdn = CurrencyDisplayNames.getInstance(locale);
assertEquals("Short symbol: " + locale + ": " + isoCode,
expectedShort, cdn.getSymbol(isoCode));
assertEquals("Narrow symbol: " + locale + ": " + isoCode,
expectedNarrow, cdn.getNarrowSymbol(isoCode));
}
}
@Test
public void testGetName_Locale_Int_String_BooleanArray() {
Currency currency = Currency.getInstance(ULocale.CHINA);