mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-09 15:27:38 +00:00
ICU-11986 MeasureFormat unit display patterns need to fall back to the parent locales per plural form, not as a set; add MeasureFormatTest::TestIndividualPluralFallback(); fix RelativeDateTimeFormatterTest::TestSerbianFallback() test data
X-SVN-Rev: 38103
This commit is contained in:
parent
8b03bbc037
commit
5a7ff3049b
8 changed files with 85 additions and 45 deletions
|
@ -241,10 +241,8 @@ struct UnitDataSink : public ResourceTableSink {
|
|||
// The key must be one of the plural form strings. For example:
|
||||
// one{"{0} hr"}
|
||||
// other{"{0} hrs"}
|
||||
if (!outer.hasPatterns) {
|
||||
outer.cacheData.formatters[outer.unitIndex][outer.width].add(
|
||||
key, value.getUnicodeString(errorCode), errorCode);
|
||||
}
|
||||
outer.cacheData.formatters[outer.unitIndex][outer.width].
|
||||
addIfAbsent(key, value, errorCode);
|
||||
}
|
||||
}
|
||||
UnitDataSink &outer;
|
||||
|
@ -262,8 +260,6 @@ struct UnitDataSink : public ResourceTableSink {
|
|||
if (U_FAILURE(errorCode)) { return NULL; }
|
||||
outer.unitIndex = MeasureUnit::internalGetIndexForTypeAndSubtype(outer.type, key);
|
||||
if (outer.unitIndex >= 0) {
|
||||
outer.hasPatterns =
|
||||
outer.cacheData.formatters[outer.unitIndex][outer.width].isValid();
|
||||
return &outer.patternSink;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -316,7 +312,7 @@ struct UnitDataSink : public ResourceTableSink {
|
|||
UnitDataSink(MeasureFormatCacheData &outputData)
|
||||
: patternSink(*this), subtypeSink(*this), compoundSink(*this), typeSink(*this),
|
||||
cacheData(outputData),
|
||||
width(UMEASFMT_WIDTH_COUNT), type(NULL), unitIndex(0), hasPatterns(FALSE) {}
|
||||
width(UMEASFMT_WIDTH_COUNT), type(NULL), unitIndex(0) {}
|
||||
~UnitDataSink();
|
||||
virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) {
|
||||
// Handle aliases like
|
||||
|
@ -388,9 +384,6 @@ struct UnitDataSink : public ResourceTableSink {
|
|||
UMeasureFormatWidth width;
|
||||
const char *type;
|
||||
int32_t unitIndex;
|
||||
|
||||
/** True if we already have plural-form display patterns for width/type/unitIndex. */
|
||||
UBool hasPatterns;
|
||||
};
|
||||
|
||||
// Virtual destructors must be defined out of line.
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
******************************************************************************
|
||||
* quantityformatter.cpp
|
||||
*/
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "quantityformatter.h"
|
||||
#include "simplepatternformatter.h"
|
||||
#include "uassert.h"
|
||||
|
@ -15,9 +20,9 @@
|
|||
#include "charstr.h"
|
||||
#include "unicode/fmtable.h"
|
||||
#include "unicode/fieldpos.h"
|
||||
#include "resource.h"
|
||||
#include "visibledigits.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
#include "uassert.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -101,20 +106,25 @@ void QuantityFormatter::reset() {
|
|||
}
|
||||
}
|
||||
|
||||
UBool QuantityFormatter::add(
|
||||
UBool QuantityFormatter::addIfAbsent(
|
||||
const char *variant,
|
||||
const UnicodeString &rawPattern,
|
||||
const UnicodeString *rawPattern,
|
||||
const ResourceValue *patternValue,
|
||||
UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return FALSE;
|
||||
}
|
||||
int32_t pluralIndex = getPluralIndex(variant);
|
||||
if (pluralIndex == -1) {
|
||||
if (pluralIndex < 0) {
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return FALSE;
|
||||
}
|
||||
SimplePatternFormatter *newFmt =
|
||||
new SimplePatternFormatter(rawPattern);
|
||||
if (formatters[pluralIndex] != NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
const UnicodeString &pattern =
|
||||
rawPattern != NULL ? *rawPattern : patternValue->getUnicodeString(status);
|
||||
SimplePatternFormatter *newFmt = new SimplePatternFormatter(pattern);
|
||||
if (newFmt == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return FALSE;
|
||||
|
@ -124,7 +134,6 @@ UBool QuantityFormatter::add(
|
|||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return FALSE;
|
||||
}
|
||||
delete formatters[pluralIndex];
|
||||
formatters[pluralIndex] = newFmt;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -135,6 +144,7 @@ UBool QuantityFormatter::isValid() const {
|
|||
|
||||
const SimplePatternFormatter *QuantityFormatter::getByVariant(
|
||||
const char *variant) const {
|
||||
U_ASSERT(isValid());
|
||||
int32_t pluralIndex = getPluralIndex(variant);
|
||||
if (pluralIndex == -1) {
|
||||
pluralIndex = 0;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 2014, International Business Machines
|
||||
* Copyright (C) 2014-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* quantityformatter.h
|
||||
|
@ -14,6 +14,8 @@
|
|||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class SimplePatternFormatter;
|
||||
|
@ -64,17 +66,30 @@ public:
|
|||
void reset();
|
||||
|
||||
/**
|
||||
* Adds a plural variant.
|
||||
*
|
||||
* @param variant "zero", "one", "two", "few", "many", "other"
|
||||
* @param rawPattern the pattern for the variant e.g "{0} meters"
|
||||
* @param status any error returned here.
|
||||
* @return TRUE on success; FALSE if status was set to a non zero error.
|
||||
*/
|
||||
UBool add(
|
||||
const char *variant,
|
||||
const UnicodeString &rawPattern,
|
||||
UErrorCode &status);
|
||||
* Adds a plural variant if there is none yet for the plural form.
|
||||
*
|
||||
* @param variant "zero", "one", "two", "few", "many", "other"
|
||||
* @param rawPattern the pattern for the variant e.g "{0} meters"
|
||||
* @param status any error returned here.
|
||||
* @return TRUE on success; FALSE if status was set to a non zero error.
|
||||
*/
|
||||
UBool addIfAbsent(const char *variant, const UnicodeString &rawPattern, UErrorCode &status) {
|
||||
return addIfAbsent(variant, &rawPattern, NULL, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a plural variant if there is none yet for the plural form.
|
||||
* This version only calls ResourceValue::getString()
|
||||
* if there is no template yet for the plural form.
|
||||
*
|
||||
* @param variant "zero", "one", "two", "few", "many", "other"
|
||||
* @param rawPattern the pattern for the variant e.g "{0} meters"
|
||||
* @param status any error returned here.
|
||||
* @return TRUE on success; FALSE if status was set to a non zero error.
|
||||
*/
|
||||
UBool addIfAbsent(const char *variant, const ResourceValue &rawPattern, UErrorCode &status) {
|
||||
return addIfAbsent(variant, NULL, &rawPattern, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns TRUE if this object has at least the "other" variant.
|
||||
|
@ -109,6 +124,12 @@ public:
|
|||
UErrorCode &status) const;
|
||||
|
||||
private:
|
||||
UBool addIfAbsent(
|
||||
const char *variant,
|
||||
const UnicodeString *rawPattern,
|
||||
const ResourceValue *patternValue,
|
||||
UErrorCode &status);
|
||||
|
||||
SimplePatternFormatter *formatters[6];
|
||||
};
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 2014, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
* Copyright (C) 2014-2015, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
*
|
||||
* File RELDATEFMT.CPP
|
||||
*
|
||||
* File reldatefmt.cpp
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
@ -186,7 +186,7 @@ static void initQuantityFormatter(
|
|||
if (!getString(pluralBundle.getAlias(), rawPattern, status)) {
|
||||
return;
|
||||
}
|
||||
if (!formatter.add(
|
||||
if (!formatter.addIfAbsent(
|
||||
ures_getKey(pluralBundle.getAlias()),
|
||||
rawPattern,
|
||||
status)) {
|
||||
|
|
|
@ -124,6 +124,7 @@ void IntlTestUtilities::runIndexedTest( int32_t index, UBool exec, const char* &
|
|||
LocalPointer<IntlTest> test(createQuantityFormatterTest());
|
||||
callTest(*test, par);
|
||||
}
|
||||
break;
|
||||
case 23:
|
||||
name = "PluralMapTest";
|
||||
if (exec) {
|
||||
|
|
|
@ -61,6 +61,7 @@ private:
|
|||
void TestGroupingSeparator();
|
||||
void TestDoubleZero();
|
||||
void TestUnitPerUnitResolution();
|
||||
void TestIndividualPluralFallback();
|
||||
void verifyFormat(
|
||||
const char *description,
|
||||
const MeasureFormat &fmt,
|
||||
|
@ -141,6 +142,7 @@ void MeasureFormatTest::runIndexedTest(
|
|||
TESTCASE_AUTO(TestGroupingSeparator);
|
||||
TESTCASE_AUTO(TestDoubleZero);
|
||||
TESTCASE_AUTO(TestUnitPerUnitResolution);
|
||||
TESTCASE_AUTO(TestIndividualPluralFallback);
|
||||
TESTCASE_AUTO_END;
|
||||
}
|
||||
|
||||
|
@ -1588,6 +1590,19 @@ void MeasureFormatTest::TestUnitPerUnitResolution() {
|
|||
assertEquals("", "50 psi", actual);
|
||||
}
|
||||
|
||||
void MeasureFormatTest::TestIndividualPluralFallback() {
|
||||
// See ticket #11986 "incomplete fallback in MeasureFormat".
|
||||
// In CLDR 28, fr_CA temperature-generic/short has only the "one" form,
|
||||
// and falls back to fr for the "other" form.
|
||||
IcuTestErrorCode errorCode(*this, "TestIndividualPluralFallback");
|
||||
MeasureFormat mf("fr_CA", UMEASFMT_WIDTH_SHORT, errorCode);
|
||||
LocalPointer<Measure> twoDeg(
|
||||
new Measure(2, MeasureUnit::createGenericTemperature(errorCode), errorCode), errorCode);
|
||||
UnicodeString expected = UNICODE_STRING_SIMPLE("2\\u00B0").unescape();
|
||||
UnicodeString actual;
|
||||
assertEquals("2 deg temp in fr_CA", expected, mf.format(twoDeg.orphan(), actual, errorCode));
|
||||
}
|
||||
|
||||
void MeasureFormatTest::verifyFieldPosition(
|
||||
const char *description,
|
||||
const MeasureFormat &fmt,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2014, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
* Copyright (C) 2014-2015, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*
|
||||
* File QUANTITYFORMATTERTEST.CPP
|
||||
|
@ -37,25 +37,25 @@ void QuantityFormatterTest::TestBasic() {
|
|||
QuantityFormatter fmt;
|
||||
assertFalse(
|
||||
"adding bad variant",
|
||||
fmt.add("a bad variant", "{0} pounds", status));
|
||||
fmt.addIfAbsent("a bad variant", "{0} pounds", status));
|
||||
assertEquals("adding bad variant status", U_ILLEGAL_ARGUMENT_ERROR, status);
|
||||
status = U_ZERO_ERROR;
|
||||
assertFalse(
|
||||
"Adding bad pattern",
|
||||
fmt.add("other", "{0} {1} too many placeholders", status));
|
||||
fmt.addIfAbsent("other", "{0} {1} too many placeholders", status));
|
||||
assertEquals("adding bad pattern status", U_ILLEGAL_ARGUMENT_ERROR, status);
|
||||
status = U_ZERO_ERROR;
|
||||
assertFalse("isValid with no patterns", fmt.isValid());
|
||||
assertTrue(
|
||||
"Adding good pattern with no placeholders",
|
||||
fmt.add("other", "no placeholder", status));
|
||||
fmt.addIfAbsent("zero", "no placeholder", status));
|
||||
assertTrue(
|
||||
"Adding good pattern",
|
||||
fmt.add("other", "{0} pounds", status));
|
||||
fmt.addIfAbsent("other", "{0} pounds", status));
|
||||
assertTrue("isValid with other", fmt.isValid());
|
||||
assertTrue(
|
||||
"Adding good pattern",
|
||||
fmt.add("one", "{0} pound", status));
|
||||
fmt.addIfAbsent("one", "{0} pound", status));
|
||||
|
||||
assertEquals(
|
||||
"getByVariant",
|
||||
|
|
|
@ -231,9 +231,9 @@ static WithQuantityExpected kSerbian[] = {
|
|||
};
|
||||
|
||||
static WithQuantityExpected kSerbianNarrow[] = {
|
||||
{0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "\\u0437\\u0430 0 \\u043c\\u0435\\u0441."},
|
||||
{1.2, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "\\u0437\\u0430 1,2 \\u043c\\u0435\\u0441."},
|
||||
{21.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "\\u0437\\u0430 21 \\u043c\\u0435\\u0441."}
|
||||
{0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "\\u0437\\u0430 0 \\u043c."},
|
||||
{1.2, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "\\u0437\\u0430 1,2 \\u043c."},
|
||||
{21.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "\\u0437\\u0430 21 \\u043c."}
|
||||
};
|
||||
|
||||
static WithoutQuantityExpected kEnglishNoQuantity[] = {
|
||||
|
|
Loading…
Add table
Reference in a new issue