- Includes fixes to tests.
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);
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)",
TESTCASE_AUTO(TestCases);
TESTCASE_AUTO(TestCurrencyNames);
+ TESTCASE_AUTO(Test20484_NarrowSymbolFallback);
TESTCASE_AUTO(TestCurrencyAmount);
TESTCASE_AUTO(TestCurrencyUnit);
TESTCASE_AUTO(TestCoverage);
// 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";
void TestCurrencyNames(void);
+ void Test20484_NarrowSymbolFallback(void);
+
void TestCurrencyAmount(void);
void TestCurrencyUnit(void);
/**
* 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.
/**
* 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().
}
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<>();
}
////////////////////////
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;
}
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;
}
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);
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)",
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);