Skip to content

Commit

Permalink
CLDR-15954 Enable test of icu, fixed Rational support for NaN, INF, -INF
Browse files Browse the repository at this point in the history
  • Loading branch information
macchiati committed Mar 18, 2024
1 parent 1d23642 commit 16131bb
Show file tree
Hide file tree
Showing 4 changed files with 311 additions and 396 deletions.
12 changes: 6 additions & 6 deletions common/testData/units/unitLocalePreferencesTest.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ fahrenheit; 1; default; en; fahrenheit; 1 # likely region = US
gallon-imperial; 2.5; fluid; en-u-rg-uszzzz-ms-metric; liter; 11.365225
gallon-imperial; 2.5; fluid; en-u-rg-dezzzz; liter; 11.365225
gallon-imperial; 2.5; fluid; en-DE; liter; 11.365225
gallon-imperial; 2.5; fluid; en-u-rg-uszzzz-ms-uksystem; gallon-imperial; 2.5
gallon-imperial; 2.5; fluid; en-US-u-rg-uszzzz-ms-uksystem; gallon-imperial; 2.5 # ms-uksystem should behave like GB
gallon-imperial; 2.5; fluid; en-u-rg-gbzzzz; gallon-imperial; 2.5
gallon-imperial; 2.5; fluid; en-GB; gallon-imperial; 2.5
gallon-imperial; 2.5; fluid; en-u-rg-uszzzz-ms-ussystem; gallon; 1,420,653,125/473176473
gallon-imperial; 2.5; fluid; en-u-rg-uszzzz; gallon; 1,420,653,125/473176473
gallon-imperial; 2.5; fluid; en-US; gallon; 1,420,653,125/473176473
gallon-imperial; 2.5; fluid; en; gallon; 1,420,653,125/473176473 # likely region = US
ampere; 2.5; default; en; ampere; 2.5
ampere; 2.5; default; en; ampere; 2.5 # an input unit whose quantity has no preference data should get base units
pound-force-foot; 12,345; default; en; kilowatt-hour; 0.004649325714486427205
kilocandela; 1; default; en; candela; 1,000 # an input unit whose quantity has no preference data gets base units
candela-per-byte; 1; default; en; candela-per-bit; 0.125 # an input unit that has no quantity gets base units
candela-per-cubic-foot; 1; default; en; candela-per-cubic-meter; 1,953,125,000/55306341 # an input unit that has no quantity gets base units
foot; 1; default; de-u-mu-celsius; centimeter; 30.48 # a -mu unit that is not convertable from the input unit is ignored
kilocandela; 1; default; en; candela; 1,000 # an input unit whose quantity has no preference data should get base units
candela-per-byte; 1; default; en; candela-per-bit; 0.125 # an input unit that has no quantity should get base units
candela-per-cubic-foot; 1; default; en; candela-per-cubic-meter; 1,953,125,000/55306341 # an input unit that has no quantity should get base units
foot; 1; default; de-u-mu-celsius; centimeter; 30.48 # a -mu unit that is not convertible from the input unit should get ignored
#pound; 28; default; en-u-mu-stone; stone; 2 # only temperature units are supported
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,26 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
import com.ibm.icu.number.LocalizedNumberFormatter;
import com.ibm.icu.number.NumberFormatter;
import com.ibm.icu.number.NumberFormatter.UnitWidth;
import com.ibm.icu.number.UnlocalizedNumberFormatter;
import com.ibm.icu.util.Measure;
import com.ibm.icu.util.MeasureUnit;
import com.ibm.icu.util.Output;
import java.math.BigInteger;
import java.math.MathContext;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.unicode.cldr.util.CLDRLocale;
import org.unicode.cldr.util.CLDRPaths;
import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.Pair;
Expand Down Expand Up @@ -47,6 +55,7 @@ public static void main(String[] args) {
GenerateUnitTestData item = new GenerateUnitTestData();
item.TestParseUnit();
item.TestUnitPreferences();
item.testIcu();
}

static {
Expand Down Expand Up @@ -117,7 +126,7 @@ public void TestParseUnit() {
+ "# round to 4 decimal digits before comparing.\n"
+ "# Note that certain conversions are approximate, such as degrees to radians\n"
+ "#\n"
+ "# Generation: Set GENERATE_TESTS in TestUnits.java to regenerate unitsTest.txt.\n");
+ "# Generation: Use GenerateUnitTestData.java to regenerate unitsTest.txt.\n");
for (Entry<Pair<String, Double>, String> entry : testPrintout.entries()) {
pw.println(entry.getValue());
}
Expand All @@ -129,32 +138,15 @@ public void TestUnitPreferences() {
UnitPreferences prefs = SDI.getUnitPreferences();
if (true) {
try (TempPrintWriter pw =
TempPrintWriter.openUTF8Writer(
CLDRPaths.TEST_DATA + "units", "unitPreferencesTest.txt")) {
TempPrintWriter.openUTF8Writer(
CLDRPaths.TEST_DATA + "units", "unitPreferencesTest.txt");
TempPrintWriter pwLocale =
TempPrintWriter.openUTF8Writer(
CLDRPaths.TEST_DATA + "units",
"unitLocalePreferencesTest.txt")) {

pw.println(
"\n# Test data for unit preferences\n"
+ CldrUtility.getCopyrightString("# ")
+ "\n"
+ "#\n"
+ "# Format:\n"
+ "#\tQuantity;\tUsage;\tRegion;\tInput (r);\tInput (d);\tInput Unit;\tOutput (r);\tOutput (d);\tOutput Unit\n"
+ "#\n"
+ "# Use: Convert the Input amount & unit according to the Usage and Region.\n"
+ "#\t The result should match the Output amount and unit.\n"
+ "#\t Both rational (r) and double64 (d) forms of the input and output amounts are supplied so that implementations\n"
+ "#\t have two options for testing based on the precision in their implementations. For example:\n"
+ "#\t 3429 / 12500; 0.27432; meter;\n"
+ "#\t The Output amount and Unit are repeated for mixed units. In such a case, only the smallest unit will have\n"
+ "#\t both a rational and decimal amount; the others will have a single integer value, such as:\n"
+ "#\t length; person-height; CA; 3429 / 12500; 0.27432; meter; 2; foot; 54 / 5; 10.8; inch\n"
+ "#\t The input and output units are unit identifers; in particular, the output does not have further processing:\n"
+ "#\t\t • no localization\n"
+ "#\t\t • no adjustment for pluralization\n"
+ "#\t\t • no formatted with the skeleton\n"
+ "#\t\t • no suppression of zero values (for secondary -and- units such as pound in stone-and-pound)\n"
+ "#\n"
+ "# Generation: Set GENERATE_TESTS in TestUnits.java to regenerate unitPreferencesTest.txt.\n");
pw.println(getHeader("Region"));
pwLocale.println(getHeader("Locale"));
Rational ONE_TENTH = Rational.of(1, 10);

// Note that for production usage, precomputed data like the
Expand Down Expand Up @@ -209,19 +201,76 @@ public void TestUnitPreferences() {
baseUnit,
uprefs,
pw);
for (String sampleLocale : getSampleLocales(regions)) {
showSample(
quantity,
usage,
sampleLocale,
sample,
baseUnit,
uprefs,
pwLocale);
}
}
pw.println();
pwLocale.println();
}
}
}
}
}
}

static LikelySubtags likely = new LikelySubtags();

private Set<String> getSampleLocales(Set<String> regions) {
Set<String> result = new TreeSet<>();
int count = 2;
for (String region : regions) {
if (--count < 0) {
break;
}
String max = likely.maximize("und_" + region);
String lang = CLDRLocale.getInstance(max).getLanguage();
result.add(lang);
result.add("zu_" + region);
}
return result;
}

public String getHeader(String regionOrLocale) {
return "\n# Test data for unit preferences\n"
+ CldrUtility.getCopyrightString("# ")
+ "\n"
+ "#\n"
+ "# Format:\n"
+ "#\tQuantity;\tUsage;\t"
+ regionOrLocale
+ ";\tInput (r);\tInput (d);\tInput Unit;\tOutput (r);\tOutput (d);\tOutput Unit\n"
+ "#\n"
+ "# Use: Convert the Input amount & unit according to the Usage and "
+ regionOrLocale
+ ".\n"
+ "#\t The result should match the Output amount and unit.\n"
+ "#\t Both rational (r) and double64 (d) forms of the input and output amounts are supplied so that implementations\n"
+ "#\t have two options for testing based on the precision in their implementations. For example:\n"
+ "#\t 3429 / 12500; 0.27432; meter;\n"
+ "#\t The Output amount and Unit are repeated for mixed units. In such a case, only the smallest unit will have\n"
+ "#\t both a rational and decimal amount; the others will have a single integer value, such as:\n"
+ "#\t length; person-height; CA; 3429 / 12500; 0.27432; meter; 2; foot; 54 / 5; 10.8; inch\n"
+ "#\t The input and output units are unit identifers; in particular, the output does not have further processing:\n"
+ "#\t\t • no localization\n"
+ "#\t\t • no adjustment for pluralization\n"
+ "#\t\t • no formatted with the skeleton\n"
+ "#\t\t • no suppression of zero values (for secondary -and- units such as pound in stone-and-pound)\n"
+ "#\n"
+ "# Generation: Use GenerateUnitTestData.java to regenerate unitPreferencesTest.txt.\n";
}

private void showSample(
String quantity,
String usage,
String sampleRegion,
String sampleRegionOrLocale,
Rational sampleBaseValue,
String baseUnit,
Collection<UnitPreference> prefs,
Expand All @@ -233,21 +282,28 @@ private void showSample(
Rational baseGeq = converter.convert(pref.geq, topUnit, baseUnit, false);
if (sampleBaseValue.compareTo(baseGeq) >= 0) {
showSample2(
quantity, usage, sampleRegion, sampleBaseValue, baseUnit, pref.unit, pw);
quantity,
usage,
sampleRegionOrLocale,
sampleBaseValue,
baseUnit,
pref.unit,
pw);
gotOne = true;
break;
}
lastUnit = pref.unit;
}
if (!gotOne) {
showSample2(quantity, usage, sampleRegion, sampleBaseValue, baseUnit, lastUnit, pw);
showSample2(
quantity, usage, sampleRegionOrLocale, sampleBaseValue, baseUnit, lastUnit, pw);
}
}

private void showSample2(
String quantity,
String usage,
String sampleRegion,
String sampleRegionOrLocale,
Rational sampleBaseValue,
String baseUnit,
String lastUnit,
Expand Down Expand Up @@ -279,7 +335,7 @@ private void showSample2(
+ TEST_SEP
+ usage
+ TEST_SEP
+ sampleRegion
+ sampleRegionOrLocale
+ TEST_SEP
+ originalSampleBaseValue
+ TEST_SEP
Expand Down Expand Up @@ -342,4 +398,19 @@ private void checkUnitConvertability(
}
}
}

private void testIcu() {
UnlocalizedNumberFormatter nf =
NumberFormatter.with().unitWidth(UnitWidth.FULL_NAME).usage("road");

Object tests[][] = {{1d, MeasureUnit.MILE, "en", "result"}};
for (Object test[] : tests) {
Double value = (Double) test[0];
MeasureUnit unit = (MeasureUnit) test[1];
final LocalizedNumberFormatter localized =
nf.locale(Locale.forLanguageTag((String) test[2]));
String actual = (String) test[3];
actual = localized.format(new Measure(value, unit)).toString();
}
}
}
Loading

0 comments on commit 16131bb

Please sign in to comment.