From 65a9177ae269f20afeaaada347d4e4e287952ac0 Mon Sep 17 00:00:00 2001 From: younies Date: Fri, 19 Sep 2025 12:16:32 +0200 Subject: [PATCH] ICU-23105 Update NumberFormatterApiTest/formatUnitsAliases to fail when the units are not parsable - Refactor test cases to use unique_ptr for MeasureUnit in C++ and adjust constructor in Java. - Introduce logging for known issues related to unit aliases to ensure compatibility with callers. - Update expected formats for unit aliases in both C++ and Java test files. --- icu4c/source/test/intltest/numbertest_api.cpp | 38 ++++++++++++------- .../test/number/NumberFormatterApiTest.java | 27 ++++++++++--- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/icu4c/source/test/intltest/numbertest_api.cpp b/icu4c/source/test/intltest/numbertest_api.cpp index 450fd93e29a6..4fb8ec859823 100644 --- a/icu4c/source/test/intltest/numbertest_api.cpp +++ b/icu4c/source/test/intltest/numbertest_api.cpp @@ -6059,30 +6059,40 @@ void NumberFormatterApiTest::microPropsInternals() { void NumberFormatterApiTest::formatUnitsAliases() { IcuTestErrorCode status(*this, "formatUnitsAliases"); - if (logKnownIssue("ICU-23105", "With CLDR 48m1, C++ NumberFormatterApiTest::formatUnitsAliases fails (J passes)")) { - return; - } struct TestCase { - const MeasureUnit measureUnit; + std::unique_ptr measureUnit; + const char * measureUnitString; // Only used if measureUnit is nullptr const UnicodeString expectedFormat; } testCases[]{ // Aliases - {MeasureUnit::getMilligramPerDeciliter(), u"2 milligrams per deciliter"}, - {MeasureUnit::getLiterPer100Kilometers(), u"2 liters per 100 kilometers"}, - {MeasureUnit::getPartPerMillion(), u"2 parts per million"}, - {MeasureUnit::forIdentifier("permillion", status), u"2 parts per million"}, - {MeasureUnit::getMillimeterOfMercury(), u"2 millimeters of mercury"}, + {std::make_unique(MeasureUnit::getMilligramOfglucosePerDeciliter()), nullptr, u"2 milligrams per deciliter"}, + {std::make_unique(MeasureUnit::getMilligramPerDeciliter()), nullptr, u"2 milligrams per deciliter"}, + {std::make_unique(MeasureUnit::getLiterPer100Kilometers()), nullptr,u"2 liters per 100 kilometers"}, + {std::make_unique(MeasureUnit::getPartPerMillion()), nullptr, u"2 parts per million"}, + {std::make_unique(MeasureUnit::getMillimeterOfMercury()), nullptr, u"2 millimeters of mercury"}, // Some replacements - {MeasureUnit::getMilligramOfglucosePerDeciliter(), u"2 milligrams per deciliter"}, - {MeasureUnit::getLiterPer100Kilometers(), u"2 liters per 100 kilometers"}, - {MeasureUnit::getPartPer1E6(), u"2 parts per million"}, - {MeasureUnit::forIdentifier("millimeter-ofhg", status), u"2 millimeters of mercury"}, + {nullptr, "millimeter-ofhg", u"2 millimeters of mercury"}, + {nullptr, "liter-per-100-kilometer", u"2 liters per 100 kilometers"}, + {nullptr, "permillion", u"2 parts per million"}, + {nullptr, "part-per-million", u"2 parts per million"}, + {nullptr, "part-per-1e6", u"2 parts per million"}, }; for (const auto &testCase : testCases) { + if (testCase.measureUnitString != nullptr && + (uprv_strcmp("permillion", testCase.measureUnitString) == 0 || + uprv_strcmp("part-per-million", testCase.measureUnitString) == 0)) { + logKnownIssue("ICU-23222", "Ensure unit aliases work correctly to avoid breaking callers"); + continue; + } + + MeasureUnit unit = testCase.measureUnit ? *testCase.measureUnit : MeasureUnit::forIdentifier(testCase.measureUnitString, status); + if (status.errIfFailureAndReset()) { + continue; + } UnicodeString actualFormat = NumberFormatter::withLocale(icu::Locale::getEnglish()) - .unit(testCase.measureUnit) + .unit(unit) .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME) .formatDouble(2.0, status) .toString(status); diff --git a/icu4j/main/common_tests/src/test/java/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java b/icu4j/main/common_tests/src/test/java/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java index 7caec88221c4..32621e082653 100644 --- a/icu4j/main/common_tests/src/test/java/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java +++ b/icu4j/main/common_tests/src/test/java/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java @@ -5995,32 +5995,49 @@ public void formatUnitsAliases() { class TestCase { final MeasureUnit measureUnit; + final String measureUnitString; // Only used if measureUnit is nullptr final String expectedFormat; TestCase(MeasureUnit measureUnit, String expectedFormat) { this.measureUnit = measureUnit; + this.measureUnitString = null; + this.expectedFormat = expectedFormat; + } + + TestCase(String measureUnitString, String expectedFormat) { + this.measureUnit = null; + this.measureUnitString = measureUnitString; this.expectedFormat = expectedFormat; } } TestCase[] testCases = { // Aliases + new TestCase(MeasureUnit.MILLIGRAM_OFGLUCOSE_PER_DECILITER, "2 milligrams per deciliter"), new TestCase(MeasureUnit.MILLIGRAM_PER_DECILITER, "2 milligrams per deciliter"), new TestCase(MeasureUnit.LITER_PER_100KILOMETERS, "2 liters per 100 kilometers"), new TestCase(MeasureUnit.PART_PER_MILLION, "2 parts per million"), new TestCase(MeasureUnit.MILLIMETER_OF_MERCURY, "2 millimeters of mercury"), // Replacements - new TestCase(MeasureUnit.MILLIGRAM_OFGLUCOSE_PER_DECILITER, "2 milligrams per deciliter"), - new TestCase(MeasureUnit.forIdentifier("millimeter-ofhg"), "2 millimeters of mercury"), - new TestCase(MeasureUnit.forIdentifier("liter-per-100-kilometer"), "2 liters per 100 kilometers"), - new TestCase(MeasureUnit.forIdentifier("part-per-1e6"), "2 parts per million"), + new TestCase("millimeter-ofhg", "2 millimeters of mercury"), + new TestCase("liter-per-100-kilometer", "2 liters per 100 kilometers"), + new TestCase("permillion", "2 parts per million"), + new TestCase("part-per-million", "2 parts per million"), + new TestCase("part-per-1e6", "2 parts per million"), }; for (TestCase testCase : testCases) { + if ("permillion".equals(testCase.measureUnitString) || + "part-per-million".equals(testCase.measureUnitString)) { + logKnownIssue("ICU-23222", "Ensure unit aliases work correctly to avoid breaking callers"); + continue; + } + + MeasureUnit measureUnit = testCase.measureUnitString != null ? MeasureUnit.forIdentifier(testCase.measureUnitString) : testCase.measureUnit; String actualFormat = NumberFormatter .withLocale(ULocale.ENGLISH) - .unit(testCase.measureUnit) + .unit(measureUnit) .unitWidth(UnitWidth.FULL_NAME) .format(2.0) .toString();