ICU-11626 Fixes ICU4C CurrencyPluralInfo unit tests. Also fixes a memory leak in CurrencyPluralInfo implementation.

X-SVN-Rev: 41431
This commit is contained in:
Shane Carr 2018-05-22 20:47:19 +00:00
parent 768f3f42a9
commit c2412adb1e
8 changed files with 53 additions and 38 deletions

View file

@ -203,6 +203,9 @@ CurrencyPluralInfo::setCurrencyPluralPattern(const UnicodeString& pluralCount,
const UnicodeString& pattern,
UErrorCode& status) {
if (U_SUCCESS(status)) {
UnicodeString* oldValue = static_cast<UnicodeString*>(
fPluralCountToCurrencyUnitPattern->get(pluralCount));
delete oldValue;
fPluralCountToCurrencyUnitPattern->put(pluralCount, new UnicodeString(pattern), status);
}
}

View file

@ -159,7 +159,7 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe,
if (isCurrency) {
currency = CurrencyUnit(macros.unit, status); // Restore CurrencyUnit from MeasureUnit
}
CurrencySymbols* currencySymbols;
const CurrencySymbols* currencySymbols;
if (macros.currencySymbols != nullptr) {
// Used by the DecimalFormat code path
currencySymbols = macros.currencySymbols;

View file

@ -55,7 +55,9 @@ MacroProps NumberPropertyMapper::oldToNew(const DecimalFormatProperties& propert
// PLURAL RULES //
//////////////////
// TODO
if (!properties.currencyPluralInfo.fPtr.isNull()) {
macros.rules = properties.currencyPluralInfo.fPtr->getPluralRules();
}
/////////////
// AFFIXES //

View file

@ -1386,13 +1386,13 @@ struct U_I18N_API MacroProps : public UMemory {
Scale scale; // = Scale(); (benign value)
/** @internal */
AffixPatternProvider* affixProvider = nullptr; // no ownership
const AffixPatternProvider* affixProvider = nullptr; // no ownership
/** @internal */
PluralRules *rules = nullptr; // no ownership
const PluralRules* rules = nullptr; // no ownership
/** @internal */
CurrencySymbols *currencySymbols = nullptr; // no ownership
const CurrencySymbols* currencySymbols = nullptr; // no ownership
/** @internal */
int32_t threshold = DEFAULT_THRESHOLD;

View file

@ -201,7 +201,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
TESTCASE_AUTO(Test10354);
TESTCASE_AUTO(Test11645_ApplyPatternEquality);
TESTCASE_AUTO(Test12567);
TESTCASE_AUTO(TestCurrencyPluralInfoAndCustomPluralRules);
TESTCASE_AUTO(Test11626_CustomizeCurrencyPluralInfo);
TESTCASE_AUTO(Test13056_GroupingSize);
TESTCASE_AUTO(Test11025_CurrencyPadding);
TESTCASE_AUTO(Test11648_ExpDecFormatMalPattern);
@ -8872,38 +8872,44 @@ void NumberFormatTest::Test12567() {
IcuTestErrorCode errorCode(*this, "Test12567");
// Ticket #12567: DecimalFormat.equals() may not be symmetric
LocalPointer<DecimalFormat> df1((DecimalFormat *)
NumberFormat::createInstance(Locale::getUS(), UNUM_CURRENCY_PLURAL, errorCode));
NumberFormat::createInstance(Locale::getUS(), UNUM_CURRENCY, errorCode));
LocalPointer<DecimalFormat> df2((DecimalFormat *)
NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, errorCode));
df2->setCurrency(df1->getCurrency());
df2->setCurrencyPluralInfo(*df1->getCurrencyPluralInfo());
// NOTE: CurrencyPluralInfo equality not tested in C++ because its operator== is not defined.
df1->applyPattern(u"0.00", errorCode);
df2->applyPattern(u"0.00", errorCode);
// TODO(shane): assertTrue("df1 == df2", *df1 == *df2);
// TODO(shane): assertTrue("df2 == df1", *df2 == *df1);
assertTrue("df1 == df2", *df1 == *df2);
assertTrue("df2 == df1", *df2 == *df1);
df2->setPositivePrefix(u"abc");
assertTrue("df1 != df2", *df1 != *df2);
assertTrue("df2 != df1", *df2 != *df1);
}
void NumberFormatTest::TestCurrencyPluralInfoAndCustomPluralRules() {
IcuTestErrorCode errorCode(*this, "TestCurrencyPluralInfoAndCustomPluralRules");
void NumberFormatTest::Test11626_CustomizeCurrencyPluralInfo() {
IcuTestErrorCode errorCode(*this, "Test11626_CustomizeCurrencyPluralInfo");
// Ticket #11626: No unit test demonstrating how to use CurrencyPluralInfo to
// change formatting spelled out currencies
LocalPointer<DecimalFormatSymbols> symbols(
new DecimalFormatSymbols(Locale::getEnglish(), errorCode));
CurrencyPluralInfo info(Locale::getEnglish(), errorCode);
// Use locale sr because it has interesting plural rules.
Locale locale("sr");
LocalPointer<DecimalFormatSymbols> symbols(new DecimalFormatSymbols(locale, errorCode));
CurrencyPluralInfo info(locale, errorCode);
info.setCurrencyPluralPattern(u"one", u"0 qwerty", errorCode);
info.setCurrencyPluralPattern(u"few", u"0 dvorak", errorCode);
info.setPluralRules(u"one: n is 1; few: n in 2..4", errorCode);
DecimalFormat df(u"#", symbols.orphan(), UNUM_CURRENCY_PLURAL, errorCode);
df.setCurrencyPluralInfo(info);
df.setCurrency(u"USD");
df.setMaximumFractionDigits(0);
UnicodeString result;
// TODO(shane): assertEquals("Plural one", u"1.00 qwerty", df.format(1, result, errorCode));
// TODO(shane): assertEquals("Plural few", u"3.00 dvorak", df.format(3, result.remove(), errorCode));
assertEquals("Plural other", u"5.80 US dollars", df.format(5.8, result.remove(), errorCode));
assertEquals("Plural one", u"1 qwerty", df.format(1, result, errorCode));
assertEquals("Plural few", u"3 dvorak", df.format(3, result.remove(), errorCode));
assertEquals("Plural other", u"99 америчких долара", df.format(99, result.remove(), errorCode));
info.setPluralRules(u"few: n is 1; one: n in 2..4", errorCode);
df.setCurrencyPluralInfo(info);
assertEquals("Plural one", u"1 dvorak", df.format(1, result.remove(), errorCode));
assertEquals("Plural few", u"3 qwerty", df.format(3, result.remove(), errorCode));
assertEquals("Plural other", u"99 америчких долара", df.format(99, result.remove(), errorCode));
}
void NumberFormatTest::Test13056_GroupingSize() {

View file

@ -265,7 +265,7 @@ class NumberFormatTest: public CalendarTimeZoneTest {
void Test10354();
void Test11645_ApplyPatternEquality();
void Test12567();
void TestCurrencyPluralInfoAndCustomPluralRules();
void Test11626_CustomizeCurrencyPluralInfo();
void Test13056_GroupingSize();
void Test11025_CurrencyPadding();
void Test11648_ExpDecFormatMalPattern();

View file

@ -22,6 +22,7 @@ import com.ibm.icu.number.Precision.IncrementRounderImpl;
import com.ibm.icu.number.Precision.SignificantRounderImpl;
import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
import com.ibm.icu.text.DecimalFormatSymbols;
import com.ibm.icu.text.PluralRules;
import com.ibm.icu.util.Currency;
import com.ibm.icu.util.Currency.CurrencyUsage;
import com.ibm.icu.util.ULocale;
@ -92,7 +93,11 @@ final class NumberPropertyMapper {
// PLURAL RULES //
//////////////////
macros.rules = properties.getPluralRules();
PluralRules rules = properties.getPluralRules();
if (rules == null && properties.getCurrencyPluralInfo() != null) {
rules = properties.getCurrencyPluralInfo().getPluralRules();
}
macros.rules = rules;
/////////////
// AFFIXES //

View file

@ -48,13 +48,11 @@ import com.ibm.icu.impl.ICUConfig;
import com.ibm.icu.impl.LocaleUtility;
import com.ibm.icu.impl.data.ResourceReader;
import com.ibm.icu.impl.data.TokenIterator;
import com.ibm.icu.impl.number.DecimalFormatProperties;
import com.ibm.icu.math.BigDecimal;
import com.ibm.icu.math.MathContext;
import com.ibm.icu.text.CompactDecimalFormat;
import com.ibm.icu.text.CurrencyPluralInfo;
import com.ibm.icu.text.DecimalFormat;
import com.ibm.icu.text.DecimalFormat.PropertySetter;
import com.ibm.icu.text.DecimalFormatSymbols;
import com.ibm.icu.text.DisplayContext;
import com.ibm.icu.text.MeasureFormat;
@ -62,7 +60,6 @@ import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.NumberFormat.NumberFormatFactory;
import com.ibm.icu.text.NumberFormat.SimpleNumberFormatFactory;
import com.ibm.icu.text.NumberingSystem;
import com.ibm.icu.text.PluralRules;
import com.ibm.icu.text.RuleBasedNumberFormat;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.util.Currency;
@ -5918,24 +5915,26 @@ public class NumberFormatTest extends TestFmwk {
}
@Test
public void TestCurrencyPluralInfoAndCustomPluralRules() throws ParseException {
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(ULocale.ENGLISH);
final PluralRules rules = PluralRules.parseDescription("one: n is 1; few: n in 2..4");
CurrencyPluralInfo info = CurrencyPluralInfo.getInstance(ULocale.ENGLISH);
public void Test11626_CustomizeCurrencyPluralInfo() throws ParseException {
// Use locale sr because it has interesting plural rules.
ULocale locale = ULocale.forLanguageTag("sr");
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(locale);
CurrencyPluralInfo info = CurrencyPluralInfo.getInstance(locale);
info.setCurrencyPluralPattern("one", "0 qwerty");
info.setCurrencyPluralPattern("few", "0 dvorak");
DecimalFormat df = new DecimalFormat("#", symbols, info, NumberFormat.CURRENCYSTYLE);
df.setCurrency(Currency.getInstance("USD"));
df.setProperties(new PropertySetter(){
@Override
public void set(DecimalFormatProperties props) {
props.setPluralRules(rules);
}
});
df.setMaximumFractionDigits(0);
assertEquals("Plural one", "1.00 qwerty", df.format(1));
assertEquals("Plural few", "3.00 dvorak", df.format(3));
assertEquals("Plural other", "5.80 US dollars", df.format(5.8));
assertEquals("Plural one", "1 qwerty", df.format(1));
assertEquals("Plural few", "3 dvorak", df.format(3));
assertEquals("Plural other", "99 америчких долара", df.format(99));
info.setPluralRules("few: n is 1; one: n in 2..4");
df.setCurrencyPluralInfo(info);
assertEquals("Plural one", "1 dvorak", df.format(1));
assertEquals("Plural few", "3 qwerty", df.format(3));
assertEquals("Plural other", "99 америчких долара", df.format(99));
}
@Test