// per line.
//
// Field names:
-// H = ICU58
-// K = JDK
-// C = ICU4C
-// P = ICU4J parsing
-// Q = ICU4J formatting
-// S = ICU4J toPattern
+// H = ICU4J 58 (archive)
+// J = ICU4J (current)
+// K = JDK (ignored if not OpenJDK 1.8)
+// C = ICU4C (current)
+// P = Properties-based ICU4J (bypasses DecimalFormat wrapper)
//
// For more information on the format of this file, including all the available
// field names, please see
*y%4.2###### 4.33 yyyy%432,6 K
// In J ICU adds padding as if 'EUR' is only 2 chars (2 * 0xa4)
\u00a4\u00a4 **####0.00 433.0 EUR *433,00 HK
-// In J ICU adds padding as if 'EUR' is only 2 chars (2 * 0xa4)
-// Q fails this one because the test code bypasses CurrencyUsage
-\u00a4\u00a4 **#######0 433.0 EUR *433,00 HKQ
+// In H ICU adds padding as if 'EUR' is only 2 chars (2 * 0xa4)
+// P fails this one because the test code bypasses CurrencyUsage
+\u00a4\u00a4 **#######0 433.0 EUR *433,00 HKP
test padding and currencies
begin
format maxIntegerDigits output breaks
123 1 3
// C obeys maxIntegerDigits and prints after the decimal place
-0 0 .0 HKQ
-// C and Q ignore max integer if it is less than zero and prints "123"
-123 -2147483648 0 CJQ
+0 0 .0 HKP
+// CJP ignore max integer if it is less than zero and prints "123"
+123 -2147483648 0 CJP
12345 1 5
-12345 -2147483648 0 CJQ
+12345 -2147483648 0 CJP
5.3 1 5.3
-5.3 -2147483648 .3 CJQ
+5.3 -2147483648 .3 CJP
test patterns with zero
set locale en
format output breaks
-0.35 -0.25 K
0.35 0.25 K
-// Q doesn't support mixing minFrac with roundingIncrement (prints 0.50).
-0.39 0.5 JKQ
-0.62 0.5 JKQ
+// P doesn't support mixing minFrac with roundingIncrement (prints 0.50).
+0.39 0.5 JKP
+0.62 0.5 JKP
0.63 0.75 K
test padding setters
set currency USD
begin
pattern format output breaks
-# 123 123 Q
+# 123 123 P
// Currency rounding should always override the pattern.
// K prints the currency in ISO format for some reason.
\u00a4# 123 $123.00 K
**0,000 **0,000 HK
**##0,000 **##0,000 K
**###0,000 **###0,000 K
-**####0,000 **#,##0,000 CJKS
+**####0,000 **#,##0,000 CJKP
###,000. #,000.
-0,000 #0,000 CJS
+0,000 #0,000 CJP
.00 #.00
-000 #000 CJS
-000,000 #,000,000 CJS
+000 #000 CJP
+000,000 #,000,000 CJP
pp#,000 pp#,000
-00.## #00.## CJS
+00.## #00.## CJP
#,#00.025 #,#00.025
// No secondary grouping in JDK
#,##,###.02500 #,##,###.02500 K
pp#,000;(#) pp#,000;(#,000) K
-**####,##,##0.0##;(#) **#,##,##,##0.0##;**(##,##,##0.0##) CJKS
+**####,##,##0.0##;(#) **#,##,##,##0.0##;**(##,##,##0.0##) CJKP
// No significant digits in JDK
@@### @@### K
@,@#,### @,@#,### K
begin
format output breaks
// C and J get "1"
-// Q gets "1.0"
+// P gets "1.0"
// K gets "1.1" (??)
-0.975 0.98 CHJKQ
+0.975 0.98 CHJKP
test lenient parse currency match
// This test is for #13112
// per line.
//
// Field names:
-// H = ICU58
-// K = JDK
-// C = ICU4C
-// P = ICU4J parsing
-// Q = ICU4J formatting
-// S = ICU4J toPattern
+// H = ICU4J 58 (archive)
+// J = ICU4J (current)
+// K = JDK (ignored if not OpenJDK 1.8)
+// C = ICU4C (current)
+// P = Properties-based ICU4J (bypasses DecimalFormat wrapper)
//
// For more information on the format of this file, including all the available
// field names, please see
*y%4.2###### 4.33 yyyy%432,6 K
// In J ICU adds padding as if 'EUR' is only 2 chars (2 * 0xa4)
\u00a4\u00a4 **####0.00 433.0 EUR *433,00 HK
-// In J ICU adds padding as if 'EUR' is only 2 chars (2 * 0xa4)
-// Q fails this one because the test code bypasses CurrencyUsage
-\u00a4\u00a4 **#######0 433.0 EUR *433,00 HKQ
+// In H ICU adds padding as if 'EUR' is only 2 chars (2 * 0xa4)
+// P fails this one because the test code bypasses CurrencyUsage
+\u00a4\u00a4 **#######0 433.0 EUR *433,00 HKP
test padding and currencies
begin
format maxIntegerDigits output breaks
123 1 3
// C obeys maxIntegerDigits and prints after the decimal place
-0 0 .0 HKQ
-// C and Q ignore max integer if it is less than zero and prints "123"
-123 -2147483648 0 CJQ
+0 0 .0 HKP
+// CJP ignore max integer if it is less than zero and prints "123"
+123 -2147483648 0 CJP
12345 1 5
-12345 -2147483648 0 CJQ
+12345 -2147483648 0 CJP
5.3 1 5.3
-5.3 -2147483648 .3 CJQ
+5.3 -2147483648 .3 CJP
test patterns with zero
set locale en
format output breaks
-0.35 -0.25 K
0.35 0.25 K
-// Q doesn't support mixing minFrac with roundingIncrement (prints 0.50).
-0.39 0.5 JKQ
-0.62 0.5 JKQ
+// P doesn't support mixing minFrac with roundingIncrement (prints 0.50).
+0.39 0.5 JKP
+0.62 0.5 JKP
0.63 0.75 K
test padding setters
set currency USD
begin
pattern format output breaks
-# 123 123 Q
+# 123 123 P
// Currency rounding should always override the pattern.
// K prints the currency in ISO format for some reason.
\u00a4# 123 $123.00 K
**0,000 **0,000 HK
**##0,000 **##0,000 K
**###0,000 **###0,000 K
-**####0,000 **#,##0,000 CJKS
+**####0,000 **#,##0,000 CJKP
###,000. #,000.
-0,000 #0,000 CJS
+0,000 #0,000 CJP
.00 #.00
-000 #000 CJS
-000,000 #,000,000 CJS
+000 #000 CJP
+000,000 #,000,000 CJP
pp#,000 pp#,000
-00.## #00.## CJS
+00.## #00.## CJP
#,#00.025 #,#00.025
// No secondary grouping in JDK
#,##,###.02500 #,##,###.02500 K
pp#,000;(#) pp#,000;(#,000) K
-**####,##,##0.0##;(#) **#,##,##,##0.0##;**(##,##,##0.0##) CJKS
+**####,##,##0.0##;(#) **#,##,##,##0.0##;**(##,##,##0.0##) CJKP
// No significant digits in JDK
@@### @@### K
@,@#,### @,@#,### K
begin
format output breaks
// C and J get "1"
-// Q gets "1.0"
+// P gets "1.0"
// K gets "1.1" (??)
-0.975 0.98 CHJKQ
+0.975 0.98 CHJKP
test lenient parse currency match
// This test is for #13112
private static enum RunMode {
SKIP_KNOWN_FAILURES,
- INCLUDE_KNOWN_FAILURES
+ INCLUDE_KNOWN_FAILURES,
+ CHECK_FOR_UNKNOWN_IDS
}
private final CodeUnderTest codeUnderTest;
+ private final String allowedIDs;
private String fileLine = null;
private int fileLineNumber = 0;
private String fileTestName = "";
.run(fileName, RunMode.INCLUDE_KNOWN_FAILURES);
}
- private DataDrivenNumberFormatTestUtility(
- CodeUnderTest codeUnderTest) {
+ /**
+ * Checks the data file for no unknown IDs in "breaks" columns.
+ */
+ public static void checkNoUnknownIDs(String fileName, String allowedIDs) {
+ new DataDrivenNumberFormatTestUtility(allowedIDs).run(fileName, RunMode.CHECK_FOR_UNKNOWN_IDS);
+ }
+
+ private DataDrivenNumberFormatTestUtility(CodeUnderTest codeUnderTest) {
this.codeUnderTest = codeUnderTest;
+ this.allowedIDs = null;
+ }
+
+ private DataDrivenNumberFormatTestUtility(String allowedIDs) {
+ this.codeUnderTest = null;
+ this.allowedIDs = allowedIDs;
}
private void run(String fileName, RunMode runMode) {
- Character codeUnderTestIdObj = codeUnderTest.Id();
- char codeUnderTestId =
- codeUnderTestIdObj == null ? 0 : Character.toUpperCase(codeUnderTestIdObj.charValue());
+ char codeUnderTestId = (codeUnderTest == null) ? 0 : codeUnderTest.Id();
BufferedReader in = null;
try {
in = TestUtil.getDataReader("numberformattestspecification.txt", "UTF-8");
return;
}
}
- if (runMode == RunMode.INCLUDE_KNOWN_FAILURES || !breaks(codeUnderTestId)) {
+ if (runMode == RunMode.CHECK_FOR_UNKNOWN_IDS) {
+ String actualIDs = tuple.breaks;
+ if (actualIDs != null) {
+ // Make sure there are no IDs in actualIDs that are not in allowedIDs.
+ // As a bonus, check that actualIDs are in alphabetical order.
+ char prevID = 0;
+ for (int i=0; i<actualIDs.length(); i++) {
+ char currID = actualIDs.charAt(i);
+ if (allowedIDs.indexOf(currID) == -1) {
+ showError("Unknown ID: " + currID);
+ }
+ if (prevID > currID) {
+ showError("IDs not in alphabetical order: " + actualIDs);
+ }
+ prevID = currID;
+ }
+ }
+ } else if (runMode == RunMode.INCLUDE_KNOWN_FAILURES || !breaks(codeUnderTestId)) {
String errorMessage;
Exception err = null;
boolean shouldFail = (tuple.output != null && tuple.output.equals("fail"))
return null;
}
+ /**
+ * Main ICU4J DecimalFormat data-driven test.
+ */
private DataDrivenNumberFormatTestUtility.CodeUnderTest ICU4J = new DataDrivenNumberFormatTestUtility.CodeUnderTest() {
@Override
public Character Id() {
}
};
+ /**
+ * Backwards-compatibility test: snapshot of DecimalFormat from ICU 58.
+ */
private DataDrivenNumberFormatTestUtility.CodeUnderTest ICU58 = new DataDrivenNumberFormatTestUtility.CodeUnderTest() {
@Override
public Character Id() {
}
};
+ /**
+ * Test of available JDK APIs.
+ */
private DataDrivenNumberFormatTestUtility.CodeUnderTest JDK = new DataDrivenNumberFormatTestUtility.CodeUnderTest() {
@Override
public Character Id() {
}
/**
- * Formatting, but no other features.
+ * Same as ICU4J, but bypasses the DecimalFormat wrapper and goes directly to the
+ * DecimalFormatProperties.
*/
- private DataDrivenNumberFormatTestUtility.CodeUnderTest ICU60 = new DataDrivenNumberFormatTestUtility.CodeUnderTest() {
+ private DataDrivenNumberFormatTestUtility.CodeUnderTest ICU4J_Properties = new DataDrivenNumberFormatTestUtility.CodeUnderTest() {
@Override
public Character Id() {
- return 'Q';
+ return 'P';
}
/**
}
return null;
}
- };
-
- /**
- * Parsing, but no other features.
- */
- private DataDrivenNumberFormatTestUtility.CodeUnderTest ICU61_Parsing = new DataDrivenNumberFormatTestUtility.CodeUnderTest() {
-
- @Override
- public Character Id() {
- return 'P';
- }
-
- @Override
- public String parse(DataDrivenNumberFormatTestData tuple) {
- String pattern = (tuple.pattern == null) ? "0" : tuple.pattern;
- DecimalFormatProperties properties;
- ParsePosition ppos = new ParsePosition(0);
- Number actual;
- try {
- properties = PatternStringParser.parseToProperties(pattern,
- tuple.currency != null ? PatternStringParser.IGNORE_ROUNDING_ALWAYS
- : PatternStringParser.IGNORE_ROUNDING_NEVER);
- propertiesFromTuple(tuple, properties);
- actual = NumberParserImpl.parseStatic(tuple.parse,
- ppos,
- properties,
- DecimalFormatSymbols.getInstance(tuple.locale));
- } catch (IllegalArgumentException e) {
- return "parse exception: " + e.getMessage();
- }
- return compareParseResult(tuple.output, actual, ppos);
- }
-
- @Override
- public String parseCurrency(DataDrivenNumberFormatTestData tuple) {
- String pattern = (tuple.pattern == null) ? "0" : tuple.pattern;
- DecimalFormatProperties properties;
- ParsePosition ppos = new ParsePosition(0);
- CurrencyAmount actual;
- try {
- properties = PatternStringParser.parseToProperties(pattern,
- tuple.currency != null ? PatternStringParser.IGNORE_ROUNDING_ALWAYS
- : PatternStringParser.IGNORE_ROUNDING_NEVER);
- propertiesFromTuple(tuple, properties);
- actual = NumberParserImpl.parseStaticCurrency(tuple.parse,
- ppos,
- properties,
- DecimalFormatSymbols.getInstance(tuple.locale));
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- return "parse exception: " + e.getMessage();
- }
- return compareParseCurrencyResult(tuple.output, tuple.outputCurrency, actual, ppos);
- }
- };
-
- /**
- * All features except formatting.
- */
- private DataDrivenNumberFormatTestUtility.CodeUnderTest ICU59_Other = new DataDrivenNumberFormatTestUtility.CodeUnderTest() {
-
- @Override
- public Character Id() {
- return 'S';
- }
/**
* Runs a single toPattern test. On success, returns null. On failure, returns the error. This
return null;
}
- /**
- * Runs a single select test. On success, returns null. On failure, returns the error. This
- * implementation just returns null. Subclasses should override.
- *
- * @param tuple
- * contains the parameters of the format test.
- */
@Override
- public String select(DataDrivenNumberFormatTestData tuple) {
- return null;
+ public String parse(DataDrivenNumberFormatTestData tuple) {
+ String pattern = (tuple.pattern == null) ? "0" : tuple.pattern;
+ DecimalFormatProperties properties;
+ ParsePosition ppos = new ParsePosition(0);
+ Number actual;
+ try {
+ properties = PatternStringParser.parseToProperties(pattern,
+ tuple.currency != null ? PatternStringParser.IGNORE_ROUNDING_ALWAYS
+ : PatternStringParser.IGNORE_ROUNDING_NEVER);
+ propertiesFromTuple(tuple, properties);
+ actual = NumberParserImpl.parseStatic(tuple.parse,
+ ppos,
+ properties,
+ DecimalFormatSymbols.getInstance(tuple.locale));
+ } catch (IllegalArgumentException e) {
+ return "parse exception: " + e.getMessage();
+ }
+ return compareParseResult(tuple.output, actual, ppos);
+ }
+
+ @Override
+ public String parseCurrency(DataDrivenNumberFormatTestData tuple) {
+ String pattern = (tuple.pattern == null) ? "0" : tuple.pattern;
+ DecimalFormatProperties properties;
+ ParsePosition ppos = new ParsePosition(0);
+ CurrencyAmount actual;
+ try {
+ properties = PatternStringParser.parseToProperties(pattern,
+ tuple.currency != null ? PatternStringParser.IGNORE_ROUNDING_ALWAYS
+ : PatternStringParser.IGNORE_ROUNDING_NEVER);
+ propertiesFromTuple(tuple, properties);
+ actual = NumberParserImpl.parseStaticCurrency(tuple.parse,
+ ppos,
+ properties,
+ DecimalFormatSymbols.getInstance(tuple.locale));
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ return "parse exception: " + e.getMessage();
+ }
+ return compareParseCurrencyResult(tuple.output, tuple.outputCurrency, actual, ppos);
}
};
+ @Test
+ public void TestNoUnknownIDs() {
+ DataDrivenNumberFormatTestUtility.checkNoUnknownIDs("numberformattestspecification.txt", "CHJKP");
+ }
+
@Test
public void TestDataDrivenICU4J() {
DataDrivenNumberFormatTestUtility
}
@Test
- public void TestDataDrivenICULatest_Format() {
- DataDrivenNumberFormatTestUtility
- .runFormatSuiteIncludingKnownFailures("numberformattestspecification.txt", ICU60);
- }
-
- @Test
- public void TestDataDrivenICULatest_Parsing() {
- DataDrivenNumberFormatTestUtility.runFormatSuiteIncludingKnownFailures(
- "numberformattestspecification.txt",
- ICU61_Parsing);
- }
-
- @Test
- public void TestDataDrivenICULatest_Other() {
+ public void TestDataDrivenICU4JProperties() {
DataDrivenNumberFormatTestUtility
- .runFormatSuiteIncludingKnownFailures("numberformattestspecification.txt", ICU59_Other);
+ .runFormatSuiteIncludingKnownFailures("numberformattestspecification.txt", ICU4J_Properties);
}
}