Skip to content

Commit

Permalink
ICU-23009 Enhance MeasureUnit handling for constant denominators
Browse files Browse the repository at this point in the history
- Updated MeasureUnit class to allow constant denominators for both COMPOUND and SINGLE complexities.
- Modified error handling to throw exceptions for unsupported complexities.
- Added new test cases in MeasureUnitTest to validate constant denominators, including edge cases and non-acceptable identifiers.

This change improves the robustness of the MeasureUnit functionality and expands the test coverage for constant denominators.
  • Loading branch information
younies committed Jan 20, 2025
1 parent 9e03b30 commit 1e8b0cb
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1334,6 +1334,7 @@ class ConstantDenominatorTestCase {
new ConstantDenominatorTestCase("second-per-1000-minute", 1000),
new ConstantDenominatorTestCase("gram-per-1000-kilogram", 1000),
new ConstantDenominatorTestCase("meter-per-100", 100),
// Test for constant denominators that are powers of 10
new ConstantDenominatorTestCase("portion-per-1", 1),
new ConstantDenominatorTestCase("portion-per-10", 10),
new ConstantDenominatorTestCase("portion-per-100", 100),
Expand All @@ -1353,16 +1354,23 @@ class ConstantDenominatorTestCase {
new ConstantDenominatorTestCase("portion-per-10000000000000000", 10000000000000000L),
new ConstantDenominatorTestCase("portion-per-100000000000000000", 100000000000000000L),
new ConstantDenominatorTestCase("portion-per-1000000000000000000", 1000000000000000000L),
// Test for constant denominators that are represented as scientific notation
// numbers.
new ConstantDenominatorTestCase("portion-per-1e9", 1000000000L),
new ConstantDenominatorTestCase("portion-per-1E9", 1000000000L),
new ConstantDenominatorTestCase("portion-per-10e9", 10000000000L),
new ConstantDenominatorTestCase("portion-per-10E9", 10000000000L),
new ConstantDenominatorTestCase("portion-per-1e10", 10000000000L),
new ConstantDenominatorTestCase("portion-per-1E10", 10000000000L),
new ConstantDenominatorTestCase("portion-per-1e3-kilometer", 1000),
// Test for constant denominators that are randomely selected.
new ConstantDenominatorTestCase("liter-per-12345-kilometer", 12345),
new ConstantDenominatorTestCase("per-1000-kilometer", 1000),
new ConstantDenominatorTestCase("liter-per-1000-kiloliter", 1000),
// Test for constant denominators that gives 0.
new ConstantDenominatorTestCase("meter", 0),
new ConstantDenominatorTestCase("meter-per-second", 0),
new ConstantDenominatorTestCase("meter-per-square-second", 0),
// NOTE: The following constant denominator should be 0. However, since
// `100-kilometer` is treated as a unit in CLDR,
// the unit does not have a constant denominator.
Expand All @@ -1379,7 +1387,35 @@ class ConstantDenominatorTestCase {
MeasureUnit unit = MeasureUnit.forIdentifier(testCase.identifier);
assertEquals("Constant denominator for " + testCase.identifier, testCase.expectedConstantDenominator,
unit.getConstantDenominator());
assertEquals("Complexity for " + testCase.identifier, Complexity.COMPOUND, unit.getComplexity());
assertTrue("Complexity for " + testCase.identifier,
unit.getComplexity() == Complexity.COMPOUND || unit.getComplexity() == Complexity.SINGLE);
}
}

@Test
public void TestNonAcceptableConstantDenominator() {
class NonAcceptableConstantDenominatorTestCase {
String identifier;

NonAcceptableConstantDenominatorTestCase(String identifier) {
this.identifier = identifier;
}
}

List<NonAcceptableConstantDenominatorTestCase> testCases = Arrays.asList(
new NonAcceptableConstantDenominatorTestCase("meter-and-second"),
new NonAcceptableConstantDenominatorTestCase("meter-per--20--second"),
new NonAcceptableConstantDenominatorTestCase("meter-per-1000-1e9-second"),
new NonAcceptableConstantDenominatorTestCase("meter-per-1e20-second"));

for (NonAcceptableConstantDenominatorTestCase testCase : testCases) {
try {
MeasureUnit unit = MeasureUnit.forIdentifier(testCase.identifier);
unit.getConstantDenominator();
Assert.fail("An IllegalArgumentException must be thrown");
} catch (Exception e) {
continue;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ public MeasurePrefix getPrefix() {
* @draft ICU 77
*/
public MeasureUnit withConstantDenominator(long denominator) {
if (this.getComplexity() == Complexity.MIXED) {
if (this.getComplexity() != Complexity.COMPOUND && this.getComplexity() != Complexity.SINGLE) {
throw new UnsupportedOperationException(
"Constant denominator can only be applied to COMPOUND & SINGLE units");
}
Expand All @@ -581,7 +581,7 @@ public MeasureUnit withConstantDenominator(long denominator) {
* zero.</li>
* </ul>
* <p>
* This method is applicable only to COMPOUND units. If invoked on a SINGLE or
* This method is applicable only to COMPOUND & SINGLE units. If invoked on a
* MIXED unit, an exception will be thrown.
* For further details, refer to {@link Complexity}.
* <p>
Expand All @@ -593,8 +593,9 @@ public MeasureUnit withConstantDenominator(long denominator) {
* @draft ICU 77
*/
public long getConstantDenominator() {
if (this.getComplexity() != Complexity.COMPOUND) {
throw new UnsupportedOperationException("Constant denominator is only supported for COMPOUND units");
if (this.getComplexity() != Complexity.COMPOUND && this.getComplexity() != Complexity.SINGLE) {
throw new UnsupportedOperationException(
"Constant denominator is only supported for COMPOUND & SINGLE units");
}

if (this.measureUnitImpl == null) {
Expand Down

0 comments on commit 1e8b0cb

Please sign in to comment.