mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-06 14:05:32 +00:00
ICU-22017 Fix numbering system resolution in NumberRangeFormatter
See #2085
This commit is contained in:
parent
df8fbc22e8
commit
c5872e7f67
6 changed files with 97 additions and 2 deletions
|
@ -354,6 +354,7 @@ LocalizedNumberRangeFormatter::getFormatter(UErrorCode& status) const {
|
|||
// Try computing the formatter on our own
|
||||
auto* temp = new NumberRangeFormatterImpl(fMacros, status);
|
||||
if (U_FAILURE(status)) {
|
||||
delete temp;
|
||||
return nullptr;
|
||||
}
|
||||
if (temp == nullptr) {
|
||||
|
|
|
@ -130,7 +130,7 @@ NumberRangeFormatterImpl::NumberRangeFormatterImpl(const RangeMacroProps& macros
|
|||
fApproximatelyFormatter(status) {
|
||||
|
||||
const char* nsName = formatterImpl1.getRawMicroProps().nsName;
|
||||
if (uprv_strcmp(nsName, formatterImpl2.getRawMicroProps().nsName) != 0) {
|
||||
if (!fSameFormatters && uprv_strcmp(nsName, formatterImpl2.getRawMicroProps().nsName) != 0) {
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -326,6 +326,7 @@ class NumberRangeFormatterTest : public IntlTestWithFieldPosition {
|
|||
void test21684_Performance();
|
||||
void test21358_SignPosition();
|
||||
void test21683_StateLeak();
|
||||
void testCreateLNRFFromNumberingSystemInSkeleton();
|
||||
|
||||
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ void NumberRangeFormatterTest::runIndexedTest(int32_t index, UBool exec, const c
|
|||
TESTCASE_AUTO(test21684_Performance);
|
||||
TESTCASE_AUTO(test21358_SignPosition);
|
||||
TESTCASE_AUTO(test21683_StateLeak);
|
||||
TESTCASE_AUTO(testCreateLNRFFromNumberingSystemInSkeleton);
|
||||
TESTCASE_AUTO_END;
|
||||
}
|
||||
|
||||
|
@ -1031,6 +1032,51 @@ void NumberRangeFormatterTest::test21358_SignPosition() {
|
|||
}
|
||||
}
|
||||
|
||||
void NumberRangeFormatterTest::testCreateLNRFFromNumberingSystemInSkeleton() {
|
||||
IcuTestErrorCode status(*this, "testCreateLNRFFromNumberingSystemInSkeleton");
|
||||
{
|
||||
LocalizedNumberRangeFormatter lnrf = NumberRangeFormatter::withLocale("en")
|
||||
.numberFormatterBoth(NumberFormatter::forSkeleton(
|
||||
u".### rounding-mode-half-up", status));
|
||||
UnicodeString actual = lnrf.formatFormattableRange(1, 234, status).toString(status);
|
||||
assertEquals("default numbering system", u"1–234", actual);
|
||||
status.errIfFailureAndReset("default numbering system");
|
||||
}
|
||||
{
|
||||
LocalizedNumberRangeFormatter lnrf = NumberRangeFormatter::withLocale("th")
|
||||
.numberFormatterBoth(NumberFormatter::forSkeleton(
|
||||
u".### rounding-mode-half-up numbering-system/thai", status));
|
||||
UnicodeString actual = lnrf.formatFormattableRange(1, 234, status).toString(status);
|
||||
assertEquals("Thai numbering system", u"๑-๒๓๔", actual);
|
||||
status.errIfFailureAndReset("thai numbering system");
|
||||
}
|
||||
{
|
||||
LocalizedNumberRangeFormatter lnrf = NumberRangeFormatter::withLocale("en")
|
||||
.numberFormatterBoth(NumberFormatter::forSkeleton(
|
||||
u".### rounding-mode-half-up numbering-system/arab", status));
|
||||
UnicodeString actual = lnrf.formatFormattableRange(1, 234, status).toString(status);
|
||||
assertEquals("Arabic numbering system", u"١–٢٣٤", actual);
|
||||
status.errIfFailureAndReset("arab numbering system");
|
||||
}
|
||||
{
|
||||
LocalizedNumberRangeFormatter lnrf = NumberRangeFormatter::withLocale("en")
|
||||
.numberFormatterFirst(NumberFormatter::forSkeleton(u"numbering-system/arab", status))
|
||||
.numberFormatterSecond(NumberFormatter::forSkeleton(u"numbering-system/arab", status));
|
||||
UnicodeString actual = lnrf.formatFormattableRange(1, 234, status).toString(status);
|
||||
assertEquals("Double Arabic numbering system", u"١–٢٣٤", actual);
|
||||
status.errIfFailureAndReset("double arab numbering system");
|
||||
}
|
||||
{
|
||||
LocalizedNumberRangeFormatter lnrf = NumberRangeFormatter::withLocale("en")
|
||||
.numberFormatterFirst(NumberFormatter::forSkeleton(u"numbering-system/arab", status))
|
||||
.numberFormatterSecond(NumberFormatter::forSkeleton(u"numbering-system/latn", status));
|
||||
// Note: The error is not set until `formatFormattableRange` because this is where the
|
||||
// formatter object gets built.
|
||||
lnrf.formatFormattableRange(1, 234, status);
|
||||
status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
void NumberRangeFormatterTest::test21683_StateLeak() {
|
||||
IcuTestErrorCode status(*this, "test21683_StateLeak");
|
||||
UNumberRangeFormatter* nrf = nullptr;
|
||||
|
|
|
@ -157,7 +157,7 @@ class NumberRangeFormatterImpl {
|
|||
: NumberRangeFormatter.RangeIdentityFallback.APPROXIMATELY;
|
||||
|
||||
String nsName = formatterImpl1.getRawMicroProps().nsName;
|
||||
if (nsName == null || !nsName.equals(formatterImpl2.getRawMicroProps().nsName)) {
|
||||
if (nsName == null || (!fSameFormatters && !nsName.equals(formatterImpl2.getRawMicroProps().nsName))) {
|
||||
throw new IllegalArgumentException("Both formatters must have same numbering system");
|
||||
}
|
||||
getNumberRangeData(macros.loc, nsName, this);
|
||||
|
|
|
@ -966,6 +966,53 @@ public class NumberRangeFormatterTest extends TestFmwk {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateLNRFFromNumberingSystemInSkeleton() {
|
||||
{
|
||||
LocalizedNumberRangeFormatter lnrf = NumberRangeFormatter
|
||||
.withLocale(ULocale.forLanguageTag("en"))
|
||||
.numberFormatterBoth(NumberFormatter.forSkeleton(
|
||||
".### rounding-mode-half-up"));
|
||||
String actual = lnrf.formatRange(1, 234).toString();
|
||||
assertEquals("default numbering system", "1–234", actual);
|
||||
}
|
||||
{
|
||||
LocalizedNumberRangeFormatter lnrf = NumberRangeFormatter
|
||||
.withLocale(ULocale.forLanguageTag("th"))
|
||||
.numberFormatterBoth(NumberFormatter.forSkeleton(
|
||||
".### rounding-mode-half-up numbering-system/thai"));
|
||||
String actual = lnrf.formatRange(1, 234).toString();
|
||||
assertEquals("Thai numbering system", "๑-๒๓๔", actual);
|
||||
}
|
||||
{
|
||||
LocalizedNumberRangeFormatter lnrf = NumberRangeFormatter
|
||||
.withLocale(ULocale.forLanguageTag("en"))
|
||||
.numberFormatterBoth(NumberFormatter.forSkeleton(
|
||||
".### rounding-mode-half-up numbering-system/arab"));
|
||||
String actual = lnrf.formatRange(1, 234).toString();
|
||||
assertEquals("Arabic numbering system", "١–٢٣٤", actual);
|
||||
}
|
||||
{
|
||||
LocalizedNumberRangeFormatter lnrf = NumberRangeFormatter
|
||||
.withLocale(ULocale.forLanguageTag("en"))
|
||||
.numberFormatterFirst(NumberFormatter.forSkeleton("numbering-system/arab"))
|
||||
.numberFormatterSecond(NumberFormatter.forSkeleton("numbering-system/arab"));
|
||||
String actual = lnrf.formatRange(1, 234).toString();
|
||||
assertEquals("Double Arabic numbering system", "١–٢٣٤", actual);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateLNRFFromNumberingSystemInSkeletonError() {
|
||||
LocalizedNumberRangeFormatter lnrf = NumberRangeFormatter
|
||||
.withLocale(ULocale.forLanguageTag("en"))
|
||||
.numberFormatterFirst(NumberFormatter.forSkeleton("numbering-system/arab"))
|
||||
.numberFormatterSecond(NumberFormatter.forSkeleton("numbering-system/latn"));
|
||||
// Note: The error is not thrown until `formatRange` because this is where the
|
||||
// formatter object gets built.
|
||||
lnrf.formatRange(1, 234);
|
||||
}
|
||||
|
||||
static void assertFormatRange(
|
||||
String message,
|
||||
UnlocalizedNumberRangeFormatter f,
|
||||
|
|
Loading…
Add table
Reference in a new issue