2 *******************************************************************************
\r
3 * Copyright (C) 2009-2010, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.dev.test.format;
\r
9 import java.text.NumberFormat;
\r
10 import java.text.ParseException;
\r
11 import java.util.Locale;
\r
12 import java.util.Random;
\r
14 import com.ibm.icu.dev.test.TestFmwk;
\r
15 import com.ibm.icu.text.RbnfLenientScannerProvider;
\r
16 import com.ibm.icu.text.RbnfScannerProviderImpl;
\r
17 import com.ibm.icu.text.RuleBasedNumberFormat;
\r
18 import com.ibm.icu.util.ULocale;
\r
20 public class RbnfLenientScannerTest extends TestFmwk {
\r
21 private static final RbnfLenientScannerProvider provider = new RbnfScannerProviderImpl();
\r
23 public static void main(String[] args) {
\r
25 new RbnfLenientScannerTest().run(args);
\r
27 catch (Throwable e) {
\r
28 System.out.println("Entire test failed because of exception: "
\r
30 e.printStackTrace();
\r
35 * Ensure that the default provider is instantiated and used if none is set
\r
36 * and lenient parse is on.
\r
38 public void TestDefaultProvider() {
\r
39 RuleBasedNumberFormat formatter
\r
40 = new RuleBasedNumberFormat(Locale.US,
\r
41 RuleBasedNumberFormat.SPELLOUT);
\r
42 formatter.setLenientScannerProvider(null);
\r
43 formatter.setLenientParseMode(true);
\r
44 String[][] lpTestData = {
\r
45 { "2 thousand six HUNDRED fifty-7", "2,657" },
\r
47 doLenientParseTest(formatter, lpTestData);
\r
51 * Perform a simple spot check on the English spellout rules
\r
53 public void TestEnglishSpellout() {
\r
54 RuleBasedNumberFormat formatter
\r
55 = new RuleBasedNumberFormat(Locale.US,
\r
56 RuleBasedNumberFormat.SPELLOUT);
\r
57 formatter.setLenientScannerProvider(provider);
\r
58 formatter.setLenientParseMode(true);
\r
59 String[][] lpTestData = {
\r
60 { "FOurhundred thiRTY six", "436" },
\r
61 // test spaces before fifty-7 causing lenient parse match of "fifty-" to " fifty"
\r
62 // leaving "-7" for remaining parse, resulting in 2643 as the parse result.
\r
63 { "fifty-7", "57" },
\r
64 { " fifty-7", "57" },
\r
65 { " fifty-7", "57" },
\r
66 { "2 thousand six HUNDRED fifty-7", "2,657" },
\r
67 { "fifteen hundred and zero", "1,500" }
\r
69 doLenientParseTest(formatter, lpTestData);
\r
73 * Perform a simple spot check on the duration-formatting rules
\r
75 public void TestDurations() {
\r
76 RuleBasedNumberFormat formatter
\r
77 = new RuleBasedNumberFormat(Locale.US,
\r
78 RuleBasedNumberFormat.DURATION);
\r
79 formatter.setLenientScannerProvider(provider);
\r
80 formatter.setLenientParseMode(true);
\r
81 String[][] lpTestData = {
\r
82 { "2-51-33", "10,293" }
\r
84 doLenientParseTest(formatter, lpTestData);
\r
88 * Perform a simple spot check on the French spellout rules
\r
90 public void TestFrenchSpellout() {
\r
91 RuleBasedNumberFormat formatter
\r
92 = new RuleBasedNumberFormat(Locale.FRANCE,
\r
93 RuleBasedNumberFormat.SPELLOUT);
\r
94 formatter.setLenientScannerProvider(provider);
\r
95 formatter.setLenientParseMode(true);
\r
96 String[][] lpTestData = {
\r
97 { "trente-et-un", "31" },
\r
98 { "un cent quatre vingt dix huit", "198" }
\r
100 doLenientParseTest(formatter, lpTestData);
\r
104 * Perform a simple spot check on the German spellout rules
\r
106 public void TestGermanSpellout() {
\r
107 RuleBasedNumberFormat formatter
\r
108 = new RuleBasedNumberFormat(Locale.GERMANY,
\r
109 RuleBasedNumberFormat.SPELLOUT);
\r
110 formatter.setLenientScannerProvider(provider);
\r
111 formatter.setLenientParseMode(true);
\r
112 String[][] lpTestData = {
\r
113 { "ein Tausend sechs Hundert fuenfunddreissig", "1,635" }
\r
115 doLenientParseTest(formatter, lpTestData);
\r
118 public void TestAllLocales() {
\r
119 StringBuffer errors = null;
\r
120 ULocale[] locales = ULocale.getAvailableLocales();
\r
126 double[] numbers = {45.678, 1, 2, 10, 11, 100, 110, 200, 1000, 1111, -1111};
\r
129 // RBNF parse is extremely slow when lenient option is enabled.
\r
130 // For non-exhaustive mode, we only test a few locales.
\r
131 // "nl_NL", "be" had crash problem reported by #6534
\r
132 String[] parseLocales = {"en_US", "nl_NL", "be"};
\r
134 for (int i = 0; i < locales.length; ++i) {
\r
135 ULocale loc = locales[i];
\r
136 int count = numbers.length;
\r
137 boolean testParse = true;
\r
138 if (getInclusion() <= 5) {
\r
140 for (int k = 0; k < parseLocales.length; k++) {
\r
141 if (loc.toString().equals(parseLocales[k])) {
\r
147 //RBNF parse is too slow. Increase count only for debugging purpose for now.
\r
151 for (int j = 0; j < 3; ++j) {
\r
152 RuleBasedNumberFormat fmt = new RuleBasedNumberFormat(loc, j+1);
\r
154 for (int c = 0; c < count; c++) {
\r
156 if (c < numbers.length) {
\r
160 r = createRandom();
\r
162 n = ((int)(r.nextInt(10000) - 3000)) / 16d;
\r
165 String s = fmt.format(n);
\r
166 logln(loc.getName() + names[j] + "success format: " + n + " -> " + s);
\r
169 // We do not validate the result in this test case,
\r
170 // because there are cases which do not round trip by design.
\r
172 // non-lenient parse
\r
173 fmt.setLenientParseMode(false);
\r
174 Number num = fmt.parse(s);
\r
175 logln(loc.getName() + names[j] + "success parse: " + s + " -> " + num);
\r
178 fmt.setLenientScannerProvider(provider);
\r
179 fmt.setLenientParseMode(true);
\r
180 num = fmt.parse(s);
\r
181 logln(loc.getName() + names[j] + "success parse (lenient): " + s + " -> " + num);
\r
182 } catch (ParseException pe) {
\r
183 String msg = loc.getName() + names[j] + "ERROR:" + pe.getMessage();
\r
185 if (errors == null) {
\r
186 errors = new StringBuffer();
\r
188 errors.append("\n" + msg);
\r
194 if (errors != null) {
\r
195 //TODO: We need to fix parse problems - see #6895 / #6896
\r
196 //errln(errors.toString());
\r
197 logln(errors.toString());
\r
201 void doLenientParseTest(RuleBasedNumberFormat formatter,
\r
202 String[][] testData) {
\r
203 NumberFormat decFmt = NumberFormat.getInstance(Locale.US);
\r
206 for (int i = 0; i < testData.length; i++) {
\r
207 String words = testData[i][0];
\r
208 String expectedNumber = testData[i][1];
\r
209 String actualNumber = decFmt.format(formatter.parse(words));
\r
211 if (!actualNumber.equals(expectedNumber)) {
\r
212 errln("Lenient-parse spot check failed: for "
\r
213 + words + ", expected " + expectedNumber
\r
214 + ", but got " + actualNumber);
\r
218 catch (Throwable e) {
\r
219 errln("Test failed with exception: " + e.toString());
\r
220 e.printStackTrace();
\r