]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/dev/test/format/RbnfTest.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / dev / test / format / RbnfTest.java
1 //##header\r
2 /*\r
3  *******************************************************************************\r
4  * Copyright (C) 1996-2009, International Business Machines Corporation and    *\r
5  * others. All Rights Reserved.                                                *\r
6  *******************************************************************************\r
7  */\r
8 package com.ibm.icu.dev.test.format;\r
9 \r
10 import java.math.BigInteger;\r
11 import java.text.DecimalFormat;\r
12 import java.text.NumberFormat;\r
13 import java.text.ParseException;\r
14 import java.util.Locale;\r
15 import java.util.Random;\r
16 \r
17 import com.ibm.icu.dev.test.TestFmwk;\r
18 import com.ibm.icu.text.RuleBasedNumberFormat;\r
19 import com.ibm.icu.util.ULocale;\r
20 \r
21 public class RbnfTest extends TestFmwk {\r
22     public static void main(String[] args) {\r
23         RbnfTest test = new RbnfTest();\r
24 \r
25         try {\r
26             test.run(args);\r
27         }\r
28         catch (Throwable e) {\r
29             System.out.println("Entire test failed because of exception: "\r
30                                + e.toString());\r
31             e.printStackTrace();\r
32         }\r
33     }\r
34 \r
35     static String fracRules = \r
36         "%main:\n" +\r
37         // this rule formats the number if it's 1 or more.  It formats\r
38         // the integral part using a DecimalFormat ("#,##0" puts\r
39         // thousands separators in the right places) and the fractional\r
40         // part using %%frac.  If there is no fractional part, it\r
41         // just shows the integral part.\r
42         "    x.0: <#,##0<[ >%%frac>];\n" +\r
43         // this rule formats the number if it's between 0 and 1.  It\r
44         // shows only the fractional part (0.5 shows up as "1/2," not\r
45         // "0 1/2")\r
46         "    0.x: >%%frac>;\n" +\r
47         // the fraction rule set.  This works the same way as the one in the\r
48         // preceding example: We multiply the fractional part of the number\r
49         // being formatted by each rule's base value and use the rule that\r
50         // produces the result closest to 0 (or the first rule that produces 0).\r
51         // Since we only provide rules for the numbers from 2 to 10, we know\r
52         // we'll get a fraction with a denominator between 2 and 10.\r
53         // "<0<" causes the numerator of the fraction to be formatted\r
54         // using numerals\r
55         "%%frac:\n" +\r
56         "    2: 1/2;\n" +\r
57         "    3: <0</3;\n" +\r
58         "    4: <0</4;\n" +\r
59         "    5: <0</5;\n" +\r
60         "    6: <0</6;\n" +\r
61         "    7: <0</7;\n" +\r
62         "    8: <0</8;\n" +\r
63         "    9: <0</9;\n" +\r
64         "   10: <0</10;\n";\r
65 \r
66     static {\r
67         // mondo hack\r
68     char[] fracRulesArr = fracRules.toCharArray();\r
69         int len = fracRulesArr.length;\r
70         int change = 2;\r
71         for (int i = 0; i < len; ++i) {\r
72             char ch = fracRulesArr[i];\r
73             if (ch == '\n') {\r
74                 change = 2; // change ok\r
75             } else if (ch == ':') {\r
76                 change = 1; // change, but once we hit a non-space char, don't change\r
77             } else if (ch == ' ') {\r
78                 if (change != 0) {\r
79                     fracRulesArr[i] = (char)0x200e;\r
80                 }\r
81             } else {\r
82                 if (change == 1) {\r
83                     change = 0;\r
84                 }\r
85             }\r
86         }\r
87     fracRules = new String(fracRulesArr);\r
88     }\r
89 \r
90     static final String durationInSecondsRules =\r
91         // main rule set for formatting with words\r
92         "%with-words:\n"\r
93         // take care of singular and plural forms of "second"\r
94         + "    0 seconds; 1 second; =0= seconds;\n"\r
95         // use %%min to format values greater than 60 seconds\r
96         + "    60/60: <%%min<[, >>];\n"\r
97         // use %%hr to format values greater than 3,600 seconds\r
98         // (the ">>>" below causes us to see the number of minutes\r
99         // when when there are zero minutes)\r
100         + "    3600/60: <%%hr<[, >>>];\n"\r
101         // this rule set takes care of the singular and plural forms\r
102         // of "minute"\r
103         + "%%min:\n"\r
104         + "    0 minutes; 1 minute; =0= minutes;\n"\r
105         // this rule set takes care of the singular and plural forms\r
106         // of "hour"\r
107         + "%%hr:\n"\r
108         + "    0 hours; 1 hour; =0= hours;\n"\r
109 \r
110         // main rule set for formatting in numerals\r
111         + "%in-numerals:\n"\r
112         // values below 60 seconds are shown with "sec."\r
113         + "    =0= sec.;\n"\r
114         // higher values are shown with colons: %%min-sec is used for\r
115         // values below 3,600 seconds...\r
116         + "    60: =%%min-sec=;\n"\r
117         // ...and %%hr-min-sec is used for values of 3,600 seconds\r
118         // and above\r
119         + "    3600: =%%hr-min-sec=;\n"\r
120         // this rule causes values of less than 10 minutes to show without\r
121         // a leading zero\r
122         + "%%min-sec:\n"\r
123         + "    0: :=00=;\n"\r
124         + "    60/60: <0<>>;\n"\r
125         // this rule set is used for values of 3,600 or more.  Minutes are always\r
126         // shown, and always shown with two digits\r
127         + "%%hr-min-sec:\n"\r
128         + "    0: :=00=;\n"\r
129         + "    60/60: <00<>>;\n"\r
130         + "    3600/60: <#,##0<:>>>;\n"\r
131         // the lenient-parse rules allow several different characters to be used\r
132         // as delimiters between hours, minutes, and seconds\r
133         + "%%lenient-parse:\n"\r
134         + "    & : = . = ' ' = -;\n";\r
135 \r
136     public void TestCoverage() {\r
137         // extra calls to boost coverage numbers\r
138         RuleBasedNumberFormat fmt0 = new RuleBasedNumberFormat(RuleBasedNumberFormat.SPELLOUT);\r
139         RuleBasedNumberFormat fmt1 = (RuleBasedNumberFormat)fmt0.clone();\r
140         RuleBasedNumberFormat fmt2 = new RuleBasedNumberFormat(RuleBasedNumberFormat.SPELLOUT);\r
141         if (!fmt0.equals(fmt0)) {\r
142             errln("self equality fails");\r
143         }\r
144         if (!fmt0.equals(fmt1)) {\r
145             errln("clone equality fails");\r
146         }\r
147         if (!fmt0.equals(fmt2)) {\r
148             errln("duplicate equality fails");\r
149         }\r
150         String str = fmt0.toString();\r
151         logln(str);\r
152 \r
153         RuleBasedNumberFormat fmt3 =  new RuleBasedNumberFormat(durationInSecondsRules);\r
154 \r
155         if (fmt0.equals(fmt3)) {\r
156             errln("nonequal fails");\r
157         }\r
158         if (!fmt3.equals(fmt3)) {\r
159             errln("self equal 2 fails");\r
160         }\r
161         str = fmt3.toString();\r
162         logln(str);\r
163 \r
164         String[] names = fmt3.getRuleSetNames();\r
165 \r
166         try {\r
167             fmt3.setDefaultRuleSet(null);\r
168             fmt3.setDefaultRuleSet("%%foo");\r
169             errln("sdrf %%foo didn't fail");\r
170         }\r
171         catch (Exception e) {\r
172             logln("Got the expected exception");\r
173         }\r
174 \r
175         try {\r
176             fmt3.setDefaultRuleSet("%bogus");\r
177             errln("sdrf %bogus didn't fail");\r
178         }\r
179         catch (Exception e) {\r
180             logln("Got the expected exception");\r
181         }\r
182 \r
183         try {\r
184             str = fmt3.format(2.3, names[0]);\r
185             logln(str);\r
186             str = fmt3.format(2.3, "%%foo");\r
187             errln("format double %%foo didn't fail");\r
188         }\r
189         catch (Exception e) {\r
190             logln("Got the expected exception");\r
191         }\r
192 \r
193         try {\r
194             str = fmt3.format(123L, names[0]);\r
195             logln(str);\r
196             str = fmt3.format(123L, "%%foo");\r
197             errln("format double %%foo didn't fail");\r
198         }\r
199         catch (Exception e) {\r
200             logln("Got the expected exception");\r
201         }\r
202 \r
203         RuleBasedNumberFormat fmt4 = new RuleBasedNumberFormat(fracRules, Locale.ENGLISH);\r
204         RuleBasedNumberFormat fmt5 = new RuleBasedNumberFormat(fracRules, Locale.ENGLISH);\r
205         str = fmt4.toString();\r
206         logln(str);\r
207         if (!fmt4.equals(fmt5)) {\r
208             errln("duplicate 2 equality failed");\r
209         }\r
210         str = fmt4.format(123L);\r
211         logln(str);\r
212         try {\r
213             Number num = fmt4.parse(str);\r
214             logln(num.toString());\r
215         }\r
216         catch (Exception e) {\r
217             errln("parse caught exception");\r
218         }\r
219 \r
220         str = fmt4.format(.000123);\r
221         logln(str);\r
222         try {\r
223             Number num = fmt4.parse(str);\r
224             logln(num.toString());\r
225         }\r
226         catch (Exception e) {\r
227             errln("parse caught exception");\r
228         }\r
229 \r
230         str = fmt4.format(456.000123);\r
231         logln(str);\r
232         try {\r
233             Number num = fmt4.parse(str);\r
234             logln(num.toString());\r
235         }\r
236         catch (Exception e) {\r
237             errln("parse caught exception");\r
238         }\r
239     }\r
240 \r
241     public void TestUndefinedSpellout() {\r
242         Locale greek = new Locale("el", "", "");\r
243         RuleBasedNumberFormat[] formatters = {\r
244             new RuleBasedNumberFormat(greek, RuleBasedNumberFormat.SPELLOUT),\r
245             new RuleBasedNumberFormat(greek, RuleBasedNumberFormat.ORDINAL),\r
246             new RuleBasedNumberFormat(greek, RuleBasedNumberFormat.DURATION),\r
247         };\r
248 \r
249         String[] data = {\r
250             "0",\r
251             "1",\r
252             "15",\r
253             "20",\r
254             "23",\r
255             "73",\r
256             "88",\r
257             "100",\r
258             "106",\r
259             "127",\r
260             "200",\r
261             "579",\r
262             "1,000",\r
263             "2,000",\r
264             "3,004",\r
265             "4,567",\r
266             "15,943",\r
267             "105,000",\r
268             "2,345,678",\r
269             "-36",\r
270             "-36.91215",\r
271             "234.56789"\r
272         };\r
273 \r
274         NumberFormat decFormat = NumberFormat.getInstance(Locale.US);\r
275         for (int j = 0; j < formatters.length; ++j) {\r
276             com.ibm.icu.text.NumberFormat formatter = formatters[j];\r
277             logln("formatter[" + j + "]");\r
278             for (int i = 0; i < data.length; ++i) {\r
279                 try {\r
280                     String result = formatter.format(decFormat.parse(data[i]));\r
281                     logln("[" + i + "] " + data[i] + " ==> " + result);\r
282                 }\r
283                 catch (Exception e) {\r
284                     errln("formatter[" + j + "], data[" + i + "] " + data[i] + " threw exception " + e.getMessage());\r
285                 }\r
286             }\r
287         }\r
288     }\r
289 \r
290     /**\r
291      * Perform a simple spot check on the English spellout rules\r
292      */\r
293     public void TestEnglishSpellout() {\r
294         RuleBasedNumberFormat formatter\r
295             = new RuleBasedNumberFormat(Locale.US,\r
296                                         RuleBasedNumberFormat.SPELLOUT);\r
297         String[][] testData = {\r
298             { "1", "one" },\r
299             { "15", "fifteen" },\r
300             { "20", "twenty" },\r
301             { "23", "twenty-three" },\r
302             { "73", "seventy-three" },\r
303             { "88", "eighty-eight" },\r
304             { "100", "one hundred" },\r
305             { "106", "one hundred six" },\r
306             { "127", "one hundred twenty-seven" },\r
307             { "200", "two hundred" },\r
308             { "579", "five hundred seventy-nine" },\r
309             { "1,000", "one thousand" },\r
310             { "2,000", "two thousand" },\r
311             { "3,004", "three thousand four" },\r
312             { "4,567", "four thousand five hundred sixty-seven" },\r
313             { "15,943", "fifteen thousand nine hundred forty-three" },\r
314             { "2,345,678", "two million three hundred forty-five "\r
315               + "thousand six hundred seventy-eight" },\r
316             { "-36", "minus thirty-six" },\r
317             { "234.567", "two hundred thirty-four point five six seven" }\r
318         };\r
319 \r
320         doTest(formatter, testData, true);\r
321 \r
322         formatter.setLenientParseMode(true);\r
323         String[][] lpTestData = {\r
324             { "FOurhundred     thiRTY six", "436" },\r
325             // test spaces before fifty-7 causing lenient parse match of "fifty-" to " fifty"\r
326             // leaving "-7" for remaining parse, resulting in 2643 as the parse result.\r
327             { "fifty-7", "57" },\r
328             { " fifty-7", "57" },\r
329             { "  fifty-7", "57" },\r
330             { "2 thousand six HUNDRED   fifty-7", "2,657" },\r
331             { "fifteen hundred and zero", "1,500" }\r
332         };\r
333         doLenientParseTest(formatter, lpTestData);\r
334     }\r
335 \r
336     /**\r
337      * Perform a simple spot check on the English ordinal-abbreviation rules\r
338      */\r
339     public void TestOrdinalAbbreviations() {\r
340         RuleBasedNumberFormat formatter\r
341             = new RuleBasedNumberFormat(Locale.US,\r
342                                         RuleBasedNumberFormat.ORDINAL);\r
343         String[][] testData = {\r
344             { "1", "1\u02e2\u1d57" },\r
345             { "2", "2\u207f\u1d48" },\r
346             { "3", "3\u02b3\u1d48" },\r
347             { "4", "4\u1d57\u02b0" },\r
348             { "7", "7\u1d57\u02b0" },\r
349             { "10", "10\u1d57\u02b0" },\r
350             { "11", "11\u1d57\u02b0" },\r
351             { "13", "13\u1d57\u02b0" },\r
352             { "20", "20\u1d57\u02b0" },\r
353             { "21", "21\u02e2\u1d57" },\r
354             { "22", "22\u207f\u1d48" },\r
355             { "23", "23\u02b3\u1d48" },\r
356             { "24", "24\u1d57\u02b0" },\r
357             { "33", "33\u02b3\u1d48" },\r
358             { "102", "102\u207f\u1d48" },\r
359             { "312", "312\u1d57\u02b0" },\r
360             { "12,345", "12,345\u1d57\u02b0" }\r
361         };\r
362 \r
363         doTest(formatter, testData, false);\r
364     }\r
365 \r
366     /**\r
367      * Perform a simple spot check on the duration-formatting rules\r
368      */\r
369     public void TestDurations() {\r
370         RuleBasedNumberFormat formatter\r
371             = new RuleBasedNumberFormat(Locale.US,\r
372                                         RuleBasedNumberFormat.DURATION);\r
373         String[][] testData = {\r
374             { "3,600", "1:00:00" },             //move me and I fail\r
375             { "0", "0 sec." },\r
376             { "1", "1 sec." },\r
377             { "24", "24 sec." },\r
378             { "60", "1:00" },\r
379             { "73", "1:13" },\r
380             { "145", "2:25" },\r
381             { "666", "11:06" },\r
382             //            { "3,600", "1:00:00" },\r
383             { "3,740", "1:02:20" },\r
384             { "10,293", "2:51:33" }\r
385         };\r
386 \r
387         doTest(formatter, testData, true);\r
388 \r
389         formatter.setLenientParseMode(true);\r
390         String[][] lpTestData = {\r
391             { "2-51-33", "10,293" }\r
392         };\r
393         doLenientParseTest(formatter, lpTestData);\r
394     }\r
395 \r
396     /**\r
397      * Perform a simple spot check on the Spanish spellout rules\r
398      */\r
399     public void TestSpanishSpellout() {\r
400         RuleBasedNumberFormat formatter\r
401             = new RuleBasedNumberFormat(new Locale("es", "es",\r
402                                                    ""), RuleBasedNumberFormat.SPELLOUT);\r
403         String[][] testData = {\r
404             { "1", "uno" },\r
405             { "6", "seis" },\r
406             { "16", "diecis\u00e9is" },\r
407             { "20", "veinte" },\r
408             { "24", "veinticuatro" },\r
409             { "26", "veintis\u00e9is" },\r
410             { "73", "setenta y tres" },\r
411             { "88", "ochenta y ocho" },\r
412             { "100", "cien" },\r
413             { "106", "ciento seis" },\r
414             { "127", "ciento veintisiete" },\r
415             { "200", "doscientos" },\r
416             { "579", "quinientos setenta y nueve" },\r
417             { "1,000", "mil" },\r
418             { "2,000", "dos mil" },\r
419             { "3,004", "tres mil cuatro" },\r
420             { "4,567", "cuatro mil quinientos sesenta y siete" },\r
421             { "15,943", "quince mil novecientos cuarenta y tres" },\r
422             { "2,345,678", "dos millones trescientos cuarenta y cinco mil "\r
423               + "seiscientos setenta y ocho"},\r
424             { "-36", "menos treinta y seis" },\r
425             { "234.567", "doscientos treinta y cuatro coma cinco seis siete" }\r
426         };\r
427 \r
428         doTest(formatter, testData, true);\r
429     }\r
430 \r
431     /**\r
432      * Perform a simple spot check on the French spellout rules\r
433      */\r
434     public void TestFrenchSpellout() {\r
435         RuleBasedNumberFormat formatter\r
436             = new RuleBasedNumberFormat(Locale.FRANCE,\r
437                                         RuleBasedNumberFormat.SPELLOUT);\r
438         String[][] testData = {\r
439             { "1", "un" },\r
440             { "15", "quinze" },\r
441             { "20", "vingt" },\r
442             { "21", "vingt-et-un" },\r
443             { "23", "vingt-trois" },\r
444             { "62", "soixante-deux" },\r
445             { "70", "soixante-dix" },\r
446             { "71", "soixante-et-onze" },\r
447             { "73", "soixante-treize" },\r
448             { "80", "quatre-vingts" },\r
449             { "88", "quatre-vingt-huit" },\r
450             { "100", "cent" },\r
451             { "106", "cent-six" },\r
452             { "127", "cent-vingt-sept" },\r
453             { "200", "deux-cents" },\r
454             { "579", "cinq-cent-soixante-dix-neuf" },\r
455             { "1,000", "mille" },\r
456             { "1,123", "mille-cent-vingt-trois" },\r
457             { "1,594", "mille-cinq-cent-quatre-vingt-quatorze" },\r
458             { "2,000", "deux-mille" },\r
459             { "3,004", "trois-mille-quatre" },\r
460             { "4,567", "quatre-mille-cinq-cent-soixante-sept" },\r
461             { "15,943", "quinze-mille-neuf-cent-quarante-trois" },\r
462             { "2,345,678", "deux millions trois-cent-quarante-cinq-mille-"\r
463               + "six-cent-soixante-dix-huit" },\r
464             { "-36", "moins trente-six" },\r
465             { "234.567", "deux-cent-trente-quatre virgule cinq six sept" }\r
466         };\r
467 \r
468         doTest(formatter, testData, true);\r
469 \r
470         formatter.setLenientParseMode(true);\r
471         String[][] lpTestData = {\r
472             { "trente-et-un", "31" },\r
473             { "un cent quatre vingt dix huit", "198" }\r
474         };\r
475         doLenientParseTest(formatter, lpTestData);\r
476     }\r
477 \r
478     /**\r
479      * Perform a simple spot check on the Swiss French spellout rules\r
480      */\r
481     public void TestSwissFrenchSpellout() {\r
482         RuleBasedNumberFormat formatter\r
483             = new RuleBasedNumberFormat(new Locale("fr", "CH",\r
484                                                    ""), RuleBasedNumberFormat.SPELLOUT);\r
485         String[][] testData = {\r
486             { "1", "un" },\r
487             { "15", "quinze" },\r
488             { "20", "vingt" },\r
489             { "21", "vingt-et-un" },\r
490             { "23", "vingt-trois" },\r
491             { "62", "soixante-deux" },\r
492             { "70", "septante" },\r
493             { "71", "septante-et-un" },\r
494             { "73", "septante-trois" },\r
495             { "80", "huitante" },\r
496             { "88", "huitante-huit" },\r
497             { "100", "cent" },\r
498             { "106", "cent-six" },\r
499             { "127", "cent-vingt-sept" },\r
500             { "200", "deux-cents" },\r
501             { "579", "cinq-cent-septante-neuf" },\r
502             { "1,000", "mille" },\r
503             { "1,123", "mille-cent-vingt-trois" },\r
504             { "1,594", "mille-cinq-cent-nonante-quatre" },\r
505             { "2,000", "deux-mille" },\r
506             { "3,004", "trois-mille-quatre" },\r
507             { "4,567", "quatre-mille-cinq-cent-soixante-sept" },\r
508             { "15,943", "quinze-mille-neuf-cent-quarante-trois" },\r
509             { "2,345,678", "deux millions trois-cent-quarante-cinq-mille-"\r
510               + "six-cent-septante-huit" },\r
511             { "-36", "moins trente-six" },\r
512             { "234.567", "deux-cent-trente-quatre virgule cinq six sept" }\r
513         };\r
514 \r
515         doTest(formatter, testData, true);\r
516     }\r
517 \r
518     /**\r
519      * Perform a simple spot check on the Italian spellout rules\r
520      */\r
521     public void TestItalianSpellout() {\r
522         RuleBasedNumberFormat formatter\r
523             = new RuleBasedNumberFormat(Locale.ITALIAN,\r
524                                         RuleBasedNumberFormat.SPELLOUT);\r
525         String[][] testData = {\r
526             { "1", "uno" },\r
527             { "15", "quindici" },\r
528             { "20", "venti" },\r
529             { "23", "venti\u00ADtr\u00E9" },\r
530             { "73", "settanta\u00ADtr\u00E9" },\r
531             { "88", "ottant\u00ADotto" },\r
532             { "100", "cento" },\r
533             { "106", "cento\u00ADsei" },\r
534             { "108", "cent\u00ADotto" },\r
535             { "127", "cento\u00ADventi\u00ADsette" },\r
536             { "181", "cent\u00ADottant\u00ADuno" },\r
537             { "200", "due\u00ADcento" },\r
538             { "579", "cinque\u00ADcento\u00ADsettanta\u00ADnove" },\r
539             { "1,000", "mille" },\r
540             { "2,000", "due\u00ADmila" },\r
541             { "3,004", "tre\u00ADmila\u00ADquattro" },\r
542             { "4,567", "quattro\u00ADmila\u00ADcinque\u00ADcento\u00ADsessanta\u00ADsette" },\r
543             { "15,943", "quindici\u00ADmila\u00ADnove\u00ADcento\u00ADquaranta\u00ADtr\u00E9" },\r
544             { "-36", "meno trenta\u00ADsei" },\r
545             { "234.567", "due\u00ADcento\u00ADtrenta\u00ADquattro virgola cinque sei sette" }\r
546         };\r
547 \r
548         doTest(formatter, testData, true);\r
549     }\r
550 \r
551     /**\r
552      * Perform a simple spot check on the German spellout rules\r
553      */\r
554     public void TestGermanSpellout() {\r
555         RuleBasedNumberFormat formatter\r
556             = new RuleBasedNumberFormat(Locale.GERMANY,\r
557                                         RuleBasedNumberFormat.SPELLOUT);\r
558         String[][] testData = {\r
559             { "1", "eins" },\r
560             { "15", "f\u00fcnfzehn" },\r
561             { "20", "zwanzig" },\r
562             { "23", "drei\u00ADund\u00ADzwanzig" },\r
563             { "73", "drei\u00ADund\u00ADsiebzig" },\r
564             { "88", "acht\u00ADund\u00ADachtzig" },\r
565             { "100", "ein\u00ADhundert" },\r
566             { "106", "ein\u00ADhundert\u00ADsechs" },\r
567             { "127", "ein\u00ADhundert\u00ADsieben\u00ADund\u00ADzwanzig" },\r
568             { "200", "zwei\u00ADhundert" },\r
569             { "579", "f\u00fcnf\u00ADhundert\u00ADneun\u00ADund\u00ADsiebzig" },\r
570             { "1,000", "ein\u00ADtausend" },\r
571             { "2,000", "zwei\u00ADtausend" },\r
572             { "3,004", "drei\u00ADtausend\u00ADvier" },\r
573             { "4,567", "vier\u00ADtausend\u00ADf\u00fcnf\u00ADhundert\u00ADsieben\u00ADund\u00ADsechzig" },\r
574             { "15,943", "f\u00fcnfzehn\u00ADtausend\u00ADneun\u00ADhundert\u00ADdrei\u00ADund\u00ADvierzig" },\r
575             { "2,345,678", "zwei Millionen drei\u00ADhundert\u00ADf\u00fcnf\u00ADund\u00ADvierzig\u00ADtausend\u00AD"\r
576               + "sechs\u00ADhundert\u00ADacht\u00ADund\u00ADsiebzig" }\r
577         };\r
578 \r
579         doTest(formatter, testData, true);\r
580 \r
581         formatter.setLenientParseMode(true);\r
582         String[][] lpTestData = {\r
583             { "ein Tausend sechs Hundert fuenfunddreissig", "1,635" }\r
584         };\r
585         doLenientParseTest(formatter, lpTestData);\r
586     }\r
587 \r
588     /**\r
589      * Perform a simple spot check on the Thai spellout rules\r
590      */\r
591     public void TestThaiSpellout() {\r
592         RuleBasedNumberFormat formatter\r
593             = new RuleBasedNumberFormat(new Locale("th", "TH", ""),\r
594                                         RuleBasedNumberFormat.SPELLOUT);\r
595         String[][] testData = {\r
596             { "0", "\u0e28\u0e39\u0e19\u0e22\u0e4c" },\r
597             { "1", "\u0e2b\u0e19\u0e36\u0e48\u0e07" },\r
598             { "10", "\u0e2a\u0e34\u0e1a" },\r
599             { "11", "\u0e2a\u0e34\u0e1a\u200b\u0e40\u0e2d\u0e47\u0e14" },\r
600             { "21", "\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e40\u0e2d\u0e47\u0e14" },\r
601             { "101", "\u0e2b\u0e19\u0e36\u0e48\u0e07\u200b\u0e23\u0e49\u0e2d\u0e22\u200b\u0e2b\u0e19\u0e36\u0e48\u0e07" },\r
602             { "1.234", "\u0e2b\u0e19\u0e36\u0e48\u0e07\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e2d\u0e07\u0e2a\u0e32\u0e21\u0e2a\u0e35\u0e48" },\r
603             { "21.45", "\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e40\u0e2d\u0e47\u0e14\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e35\u0e48\u0e2b\u0e49\u0e32" },\r
604             { "22.45", "\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e2a\u0e2d\u0e07\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e35\u0e48\u0e2b\u0e49\u0e32" },\r
605             { "23.45", "\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e2a\u0e32\u0e21\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e35\u0e48\u0e2b\u0e49\u0e32" },\r
606             { "123.45", "\u0e2b\u0e19\u0e36\u0e48\u0e07\u200b\u0e23\u0e49\u0e2d\u0e22\u200b\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e2a\u0e32\u0e21\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e35\u0e48\u0e2b\u0e49\u0e32" },\r
607             { "12,345.678", "\u0E2B\u0E19\u0E36\u0E48\u0E07\u200b\u0E2B\u0E21\u0E37\u0E48\u0E19\u200b\u0E2A\u0E2D\u0E07\u200b\u0E1E\u0E31\u0E19\u200b\u0E2A\u0E32\u0E21\u200b\u0E23\u0E49\u0E2D\u0E22\u200b\u0E2A\u0E35\u0E48\u200b\u0E2A\u0E34\u0E1A\u200b\u0E2B\u0E49\u0E32\u200b\u0E08\u0E38\u0E14\u200b\u0E2B\u0E01\u0E40\u0E08\u0E47\u0E14\u0E41\u0E1B\u0E14" },\r
608         };\r
609 \r
610         doTest(formatter, testData, true);\r
611 \r
612         /*\r
613           formatter.setLenientParseMode(true);\r
614           String[][] lpTestData = {\r
615           { "ein Tausend sechs Hundert fuenfunddreissig", "1,635" }\r
616           };\r
617           doLenientParseTest(formatter, lpTestData);\r
618         */\r
619     }\r
620 \r
621     public void TestFractionalRuleSet() {\r
622 \r
623 \r
624         RuleBasedNumberFormat formatter =\r
625             new RuleBasedNumberFormat(fracRules, Locale.ENGLISH);\r
626 \r
627         String[][] testData = {\r
628             { "0", "0" },\r
629             { "1", "1" },\r
630             { "10", "10" },\r
631             { ".1", "1/10" },\r
632             { ".11", "1/9" },\r
633             { ".125", "1/8" },\r
634             { ".1428", "1/7" },\r
635             { ".1667", "1/6" },\r
636             { ".2", "1/5" },\r
637             { ".25", "1/4" },\r
638             { ".333", "1/3" },\r
639             { ".5", "1/2" },\r
640             { "1.1", "1 1/10" },\r
641             { "2.11", "2 1/9" },\r
642             { "3.125", "3 1/8" },\r
643             { "4.1428", "4 1/7" },\r
644             { "5.1667", "5 1/6" },\r
645             { "6.2", "6 1/5" },\r
646             { "7.25", "7 1/4" },\r
647             { "8.333", "8 1/3" },\r
648             { "9.5", "9 1/2" },\r
649             { ".2222", "2/9" },\r
650             { ".4444", "4/9" },\r
651             { ".5555", "5/9" },\r
652             { "1.2856", "1 2/7" }\r
653         };\r
654         doTest(formatter, testData, false); // exact values aren't parsable from fractions\r
655     }\r
656 \r
657     public void TestSwedishSpellout()\r
658     {\r
659         Locale locale = new Locale("sv", "", "");\r
660         RuleBasedNumberFormat formatter = new RuleBasedNumberFormat(locale, RuleBasedNumberFormat.SPELLOUT);\r
661 \r
662         String[][] testDataDefault = {\r
663             { "101", "ett\u00ADhundra\u00ADett" },\r
664             { "123", "ett\u00ADhundra\u00ADtjugo\u00ADtre" },\r
665             { "1,001", "ettusen ett" },\r
666             { "1,100", "ettusen ett\u00ADhundra" },\r
667             { "1,101", "ettusen ett\u00ADhundra\u00ADett" },\r
668             { "1,234", "ettusen tv\u00e5\u00ADhundra\u00ADtrettio\u00ADfyra" },\r
669             { "10,001", "tio\u00ADtusen ett" },\r
670             { "11,000", "elva\u00ADtusen" },\r
671             { "12,000", "tolv\u00ADtusen" },\r
672             { "20,000", "tjugo-tusen" },\r
673             { "21,000", "tjugo\u00ADett-tusen" },\r
674             { "21,001", "tjugo\u00ADett-tusen ett" },\r
675             { "200,000", "tv\u00e5\u00ADhundra-tusen" },\r
676             { "201,000", "tv\u00e5\u00ADhundra\u00ADett-tusen" },\r
677             { "200,200", "tv\u00e5\u00ADhundra-tusen tv\u00e5\u00ADhundra" },\r
678             { "2,002,000", "tv\u00e5 miljoner tv\u00e5\u00ADtusen" },\r
679             { "12,345,678", "tolv miljoner tre\u00ADhundra\u00ADfyrtio\u00ADfem-tusen sex\u00ADhundra\u00ADsjuttio\u00AD\u00e5tta" },\r
680             { "123,456.789", "ett\u00ADhundra\u00ADtjugo\u00ADtre-tusen fyra\u00ADhundra\u00ADfemtio\u00ADsex komma sju \u00e5tta nio" },\r
681             { "-12,345.678", "minus tolv\u00ADtusen tre\u00ADhundra\u00ADfyrtio\u00ADfem komma sex sju \u00e5tta" }\r
682         };\r
683 \r
684         logln("testing default rules");\r
685         doTest(formatter, testDataDefault, true);\r
686 \r
687         String[][] testDataNeutrum = {\r
688             { "101", "ett\u00adhundra\u00aden" },\r
689             { "1,001", "ettusen en" },\r
690             { "1,101", "ettusen ett\u00adhundra\u00aden" },\r
691             { "10,001", "tio\u00adtusen en" },\r
692             { "21,001", "tjugo\u00aden\u00adtusen en" }\r
693         };\r
694 \r
695         formatter.setDefaultRuleSet("%spellout-cardinal-neutre");\r
696         logln("testing neutrum rules");\r
697         doTest(formatter, testDataNeutrum, true);\r
698 \r
699         String[][] testDataYear = {\r
700             { "101", "ett\u00adhundra\u00adett" },\r
701             { "900", "nio\u00adhundra" },\r
702             { "1,001", "ettusen ett" },\r
703             { "1,100", "elva\u00adhundra" },\r
704             { "1,101", "elva\u00adhundra\u00adett" },\r
705             { "1,234", "tolv\u00adhundra\u00adtrettio\u00adfyra" },\r
706             { "2,001", "tjugo\u00adhundra\u00adett" },\r
707             { "10,001", "tio\u00adtusen ett" }\r
708         };\r
709 \r
710         formatter.setDefaultRuleSet("%spellout-numbering-year");\r
711         logln("testing year rules");\r
712         doTest(formatter, testDataYear, true);\r
713     }\r
714 \r
715     public void TestBigNumbers() {\r
716         BigInteger bigI = new BigInteger("1234567890", 10);\r
717         StringBuffer buf = new StringBuffer();\r
718         RuleBasedNumberFormat fmt = new RuleBasedNumberFormat(RuleBasedNumberFormat.SPELLOUT);\r
719         fmt.format(bigI, buf, null);\r
720         logln("big int: " + buf.toString());\r
721 \r
722 //#if defined(FOUNDATION10)\r
723 //#else\r
724         buf.setLength(0);\r
725         java.math.BigDecimal bigD = new java.math.BigDecimal(bigI);\r
726         fmt.format(bigD, buf, null);\r
727         logln("big dec: " + buf.toString());\r
728 //#endif\r
729     }\r
730 \r
731   public void TestTrailingSemicolon() {\r
732     String thaiRules = \r
733         "%default:\n" +\r
734         "  -x: \u0e25\u0e1a>>;\n" +\r
735         "  x.x: <<\u0e08\u0e38\u0e14>>>;\n" +\r
736         "  \u0e28\u0e39\u0e19\u0e22\u0e4c; \u0e2b\u0e19\u0e36\u0e48\u0e07; \u0e2a\u0e2d\u0e07; \u0e2a\u0e32\u0e21;\n" +\r
737         "  \u0e2a\u0e35\u0e48; \u0e2b\u0e49\u0e32; \u0e2b\u0e01; \u0e40\u0e08\u0e47\u0e14; \u0e41\u0e1b\u0e14;\n" +\r
738         "  \u0e40\u0e01\u0e49\u0e32; \u0e2a\u0e34\u0e1a; \u0e2a\u0e34\u0e1a\u0e40\u0e2d\u0e47\u0e14;\n" +\r
739         "  \u0e2a\u0e34\u0e1a\u0e2a\u0e2d\u0e07; \u0e2a\u0e34\u0e1a\u0e2a\u0e32\u0e21;\n" +\r
740         "  \u0e2a\u0e34\u0e1a\u0e2a\u0e35\u0e48; \u0e2a\u0e34\u0e1a\u0e2b\u0e49\u0e32;\n" +\r
741         "  \u0e2a\u0e34\u0e1a\u0e2b\u0e01; \u0e2a\u0e34\u0e1a\u0e40\u0e08\u0e47\u0e14;\n" +\r
742         "  \u0e2a\u0e34\u0e1a\u0e41\u0e1b\u0e14; \u0e2a\u0e34\u0e1a\u0e40\u0e01\u0e49\u0e32;\n" +\r
743         "  20: \u0e22\u0e35\u0e48\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
744         "  30: \u0e2a\u0e32\u0e21\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
745         "  40: \u0e2a\u0e35\u0e48\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
746         "  50: \u0e2b\u0e49\u0e32\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
747         "  60: \u0e2b\u0e01\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
748         "  70: \u0e40\u0e08\u0e47\u0e14\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
749         "  80: \u0e41\u0e1b\u0e14\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
750         "  90: \u0e40\u0e01\u0e49\u0e32\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
751         "  100: <<\u0e23\u0e49\u0e2d\u0e22[>>];\n" +\r
752         "  1000: <<\u0e1e\u0e31\u0e19[>>];\n" +\r
753         "  10000: <<\u0e2b\u0e21\u0e37\u0e48\u0e19[>>];\n" +\r
754         "  100000: <<\u0e41\u0e2a\u0e19[>>];\n" +\r
755         "  1,000,000: <<\u0e25\u0e49\u0e32\u0e19[>>];\n" +\r
756         "  1,000,000,000: <<\u0e1e\u0e31\u0e19\u0e25\u0e49\u0e32\u0e19[>>];\n" +\r
757         "  1,000,000,000,000: <<\u0e25\u0e49\u0e32\u0e19\u0e25\u0e49\u0e32\u0e19[>>];\n" +\r
758         "  1,000,000,000,000,000: =#,##0=;\n" +\r
759         "%%alt-ones:\n" +\r
760         "  \u0e28\u0e39\u0e19\u0e22\u0e4c;\n" +\r
761         "  \u0e40\u0e2d\u0e47\u0e14;\n" +\r
762         "  =%default=;\n ; ;; ";\r
763 \r
764         RuleBasedNumberFormat formatter\r
765             = new RuleBasedNumberFormat(thaiRules, new Locale("th", "TH", ""));\r
766 \r
767         String[][] testData = {\r
768             { "0", "\u0e28\u0e39\u0e19\u0e22\u0e4c" },\r
769             { "1", "\u0e2b\u0e19\u0e36\u0e48\u0e07" },\r
770             { "123.45", "\u0e2b\u0e19\u0e36\u0e48\u0e07\u0e23\u0e49\u0e2d\u0e22\u0e22\u0e35\u0e48\u0e2a\u0e34\u0e1a\u0e2a\u0e32\u0e21\u0e08\u0e38\u0e14\u0e2a\u0e35\u0e48\u0e2b\u0e49\u0e32" }\r
771         };\r
772         \r
773         doTest(formatter, testData, true);\r
774     }\r
775 \r
776     public void TestSmallValues() {\r
777     String[][] testData = {\r
778         { "0.001", "zero point zero zero one" },\r
779         { "0.0001", "zero point zero zero zero one" },\r
780         { "0.00001", "zero point zero zero zero zero one" },\r
781         { "0.000001", "zero point zero zero zero zero zero one" },\r
782         { "0.0000001", "zero point zero zero zero zero zero zero one" },\r
783         { "0.00000001", "zero point zero zero zero zero zero zero zero one" },\r
784         { "0.000000001", "zero point zero zero zero zero zero zero zero zero one" },\r
785         { "0.0000000001", "zero point zero zero zero zero zero zero zero zero zero one" },\r
786         { "0.00000000001", "zero point zero zero zero zero zero zero zero zero zero zero one" },\r
787         { "0.000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero one" },\r
788         { "0.0000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero one" },\r
789         { "0.00000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero one" },\r
790         { "0.000000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero zero one" },\r
791         { "10,000,000.001", "ten million point zero zero one" },\r
792         { "10,000,000.0001", "ten million point zero zero zero one" },\r
793         { "10,000,000.00001", "ten million point zero zero zero zero one" },\r
794         { "10,000,000.000001", "ten million point zero zero zero zero zero one" },\r
795         { "10,000,000.0000001", "ten million point zero zero zero zero zero zero one" },\r
796         { "10,000,000.00000001", "ten million point zero zero zero zero zero zero zero one" },\r
797         { "10,000,000.000000002", "ten million point zero zero zero zero zero zero zero zero two" },\r
798         { "10,000,000", "ten million" },\r
799         { "1,234,567,890.0987654", "one billion two hundred thirty-four million five hundred sixty-seven thousand eight hundred ninety point zero nine eight seven six five four" },\r
800         { "123,456,789.9876543", "one hundred twenty-three million four hundred fifty-six thousand seven hundred eighty-nine point nine eight seven six five four three" },\r
801         { "12,345,678.87654321", "twelve million three hundred forty-five thousand six hundred seventy-eight point eight seven six five four three two one" },\r
802         { "1,234,567.7654321", "one million two hundred thirty-four thousand five hundred sixty-seven point seven six five four three two one" },\r
803         { "123,456.654321", "one hundred twenty-three thousand four hundred fifty-six point six five four three two one" },\r
804         { "12,345.54321", "twelve thousand three hundred forty-five point five four three two one" },\r
805         { "1,234.4321", "one thousand two hundred thirty-four point four three two one" },\r
806         { "123.321", "one hundred twenty-three point three two one" },\r
807         { "0.0000000011754944", "zero point zero zero zero zero zero zero zero zero one one seven five four nine four four" },\r
808         { "0.000001175494351", "zero point zero zero zero zero zero one one seven five four nine four three five one" },\r
809     };\r
810 \r
811     RuleBasedNumberFormat formatter\r
812         = new RuleBasedNumberFormat(Locale.US, RuleBasedNumberFormat.SPELLOUT);\r
813     doTest(formatter, testData, true);\r
814     }\r
815 \r
816     public void TestRuleSetDisplayName() {\r
817         ULocale.setDefault(ULocale.US);\r
818         String[][] localizations = new String[][] {\r
819             /* public rule sets*/\r
820             {"%simplified", "%default", "%ordinal"},\r
821             /* display names in "en_US" locale*/\r
822             {"en_US", "Simplified", "Default", "Ordinal"},\r
823             /* display names in "zh_Hans" locale*/\r
824             {"zh_Hans", "\u7B80\u5316", "\u7F3A\u7701",  "\u5E8F\u5217"},\r
825             /* display names in a fake locale*/\r
826             {"foo_Bar_BAZ", "Simplified", "Default", "Ordinal"}\r
827         };\r
828         \r
829         //Construct RuleBasedNumberFormat by rule sets and localizations list\r
830         RuleBasedNumberFormat formatter\r
831             = new RuleBasedNumberFormat(ukEnglish, localizations, ULocale.US);\r
832         RuleBasedNumberFormat f2= new RuleBasedNumberFormat(ukEnglish, localizations);\r
833         assertTrue("Check the two formatters' equality", formatter.equals(f2));        \r
834 \r
835         //get displayName by name\r
836         String[] ruleSetNames = formatter.getRuleSetNames();\r
837         for (int i=0; i<ruleSetNames.length; i++) {\r
838             logln("Rule set name: " + ruleSetNames[i]);\r
839             String RSName_defLoc = formatter.getRuleSetDisplayName(ruleSetNames[i]);\r
840             assertEquals("Display name in default locale", localizations[1][i+1], RSName_defLoc);\r
841             String RSName_loc = formatter.getRuleSetDisplayName(ruleSetNames[i], ULocale.CHINA);\r
842             assertEquals("Display name in Chinese", localizations[2][i+1], RSName_loc);\r
843         }\r
844                 \r
845         // getDefaultRuleSetName\r
846         String defaultRS = formatter.getDefaultRuleSetName();\r
847         //you know that the default rule set is %simplified according to rule sets string ukEnglish\r
848         assertEquals("getDefaultRuleSetName", "%simplified", defaultRS);\r
849         \r
850         //get locales of localizations\r
851         ULocale[] locales = formatter.getRuleSetDisplayNameLocales();\r
852         for (int i=0; i<locales.length; i++) {\r
853             logln(locales[i].getName());\r
854         }\r
855         \r
856         //get displayNames\r
857         String[] RSNames_defLoc = formatter.getRuleSetDisplayNames();\r
858         for (int i=0; i<RSNames_defLoc.length; i++) {\r
859             assertEquals("getRuleSetDisplayNames in default locale", localizations[1][i+1], RSNames_defLoc[i]);\r
860         }\r
861         \r
862         String[] RSNames_loc = formatter.getRuleSetDisplayNames(ULocale.UK);\r
863         for (int i=0; i<RSNames_loc.length; i++) {\r
864             assertEquals("getRuleSetDisplayNames in English", localizations[1][i+1], RSNames_loc[i]);\r
865         }    \r
866         \r
867         RSNames_loc = formatter.getRuleSetDisplayNames(ULocale.CHINA);\r
868         for (int i=0; i<RSNames_loc.length; i++) {\r
869             assertEquals("getRuleSetDisplayNames in Chinese", localizations[2][i+1], RSNames_loc[i]);\r
870         }        \r
871 \r
872         RSNames_loc = formatter.getRuleSetDisplayNames(new ULocale("foo_Bar_BAZ"));\r
873         for (int i=0; i<RSNames_loc.length; i++) {\r
874             assertEquals("getRuleSetDisplayNames in fake locale", localizations[3][i+1], RSNames_loc[i]);\r
875         }              \r
876     }\r
877 \r
878     public void TestAllLocales() {\r
879         StringBuffer errors = null;\r
880         ULocale[] locales = ULocale.getAvailableLocales();\r
881         String[] names = {\r
882             " (spellout) ",\r
883             " (ordinal)  ",\r
884             " (duration) "\r
885         };\r
886         double[] numbers = {45.678, 1, 2, 10, 11, 100, 110, 200, 1000, 1111, -1111};\r
887         Random r = null;\r
888 \r
889         // RBNF parse is extremely slow when lenient option is enabled.\r
890         // For non-exhaustive mode, we only test a few locales.\r
891         // "nl_NL", "be" had crash problem reported by #6534\r
892         String[] parseLocales = {"en_US", "nl_NL", "be"};\r
893 \r
894         for (int i = 0; i < locales.length; ++i) {\r
895             ULocale loc = locales[i];\r
896             int count = numbers.length;\r
897             boolean testParse = true;\r
898             if (getInclusion() <= 5) {\r
899                 testParse = false;\r
900                 for (int k = 0; k < parseLocales.length; k++) {\r
901                     if (loc.toString().equals(parseLocales[k])) {\r
902                         testParse = true;\r
903                         break;\r
904                     }\r
905                 }\r
906             } else {\r
907                 //RBNF parse is too slow.  Increase count only for debugging purpose for now.\r
908                 //count = 100;\r
909             }\r
910 \r
911             for (int j = 0; j < 3; ++j) {\r
912                 RuleBasedNumberFormat fmt = new RuleBasedNumberFormat(loc, j+1);\r
913 \r
914                 for (int c = 0; c < count; c++) {\r
915                     double n;\r
916                     if (c < numbers.length) {\r
917                         n = numbers[c];\r
918                     } else {\r
919                         if (r == null) {\r
920                             r = createRandom();\r
921                         }\r
922                         n = ((int)(r.nextInt(10000) - 3000)) / 16d;\r
923                     }\r
924 \r
925                     String s = fmt.format(n);\r
926                     logln(loc.getName() + names[j] + "success format: " + n + " -> " + s);\r
927 \r
928                     if (testParse) {\r
929                         // We do not validate the result in this test case,\r
930                         // because there are cases which do not round trip by design.\r
931                         try {\r
932                             // non-lenient parse\r
933                             fmt.setLenientParseMode(false);\r
934                             Number num = fmt.parse(s);\r
935                             logln(loc.getName() + names[j] + "success parse: " + s + " -> " + num);\r
936 \r
937                             // lenient parse\r
938                             fmt.setLenientParseMode(true);\r
939                             num = fmt.parse(s);\r
940                             logln(loc.getName() + names[j] + "success parse (lenient): " + s + " -> " + num);\r
941                         } catch (ParseException pe) {\r
942                             String msg = loc.getName() + names[j] + "ERROR:" + pe.getMessage();\r
943                             logln(msg);\r
944                             if (errors == null) {\r
945                                 errors = new StringBuffer();\r
946                             }\r
947                             errors.append("\n" + msg);\r
948                         }\r
949                     }\r
950                 }\r
951             }\r
952         }\r
953         if (errors != null) {\r
954             //TODO: We need to fix parse problems - see #6895 / #6896\r
955             //errln(errors.toString());\r
956             logln(errors.toString());\r
957         }\r
958     }\r
959 \r
960     void doTest(RuleBasedNumberFormat formatter, String[][] testData,\r
961                 boolean testParsing) {\r
962     //        NumberFormat decFmt = NumberFormat.getInstance(Locale.US);\r
963     NumberFormat decFmt = new DecimalFormat("#,###.################");\r
964         try {\r
965             for (int i = 0; i < testData.length; i++) {\r
966                 String number = testData[i][0];\r
967                 String expectedWords = testData[i][1];\r
968                 logln("test[" + i + "] number: " + number + " target: " + expectedWords);\r
969                 Number num = decFmt.parse(number);\r
970                 String actualWords = formatter.format(num);\r
971 \r
972                 if (!actualWords.equals(expectedWords)) {\r
973                     errln("Spot check format failed: for " + number + ", expected\n    "\r
974                           + expectedWords + ", but got\n    " +\r
975                           actualWords);\r
976                 }\r
977                 else if (testParsing) {\r
978                     String actualNumber = decFmt.format(formatter\r
979                                                         .parse(actualWords));\r
980 \r
981                     if (!actualNumber.equals(number)) {\r
982                         errln("Spot check parse failed: for " + actualWords +\r
983                               ", expected " + number + ", but got " +\r
984                               actualNumber);\r
985                     }\r
986                 }\r
987             }\r
988         }\r
989         catch (Throwable e) {\r
990             e.printStackTrace();\r
991             errln("Test failed with exception: " + e.toString());\r
992         }\r
993     }\r
994 \r
995     void doLenientParseTest(RuleBasedNumberFormat formatter,\r
996                             String[][] testData) {\r
997         NumberFormat decFmt = NumberFormat.getInstance(Locale.US);\r
998 \r
999         try {\r
1000             for (int i = 0; i < testData.length; i++) {\r
1001                 String words = testData[i][0];\r
1002                 String expectedNumber = testData[i][1];\r
1003                 String actualNumber = decFmt.format(formatter.parse(words));\r
1004 \r
1005                 if (!actualNumber.equals(expectedNumber)) {\r
1006                     errln("Lenient-parse spot check failed: for "\r
1007                           + words + ", expected " + expectedNumber\r
1008                           + ", but got " + actualNumber);\r
1009                 }\r
1010             }\r
1011         }\r
1012         catch (Throwable e) {\r
1013             errln("Test failed with exception: " + e.toString());\r
1014             e.printStackTrace();\r
1015         }\r
1016     }\r
1017 \r
1018 \r
1019     /**\r
1020      * Spellout rules for U.K. English.  \r
1021      * I borrow the rule sets for TestRuleSetDisplayName()\r
1022      */\r
1023     public static final String ukEnglish =\r
1024         "%simplified:\n"\r
1025         + "    -x: minus >>;\n"\r
1026         + "    x.x: << point >>;\n"\r
1027         + "    zero; one; two; three; four; five; six; seven; eight; nine;\n"\r
1028         + "    ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n"\r
1029         + "        seventeen; eighteen; nineteen;\n"\r
1030         + "    20: twenty[->>];\n"\r
1031         + "    30: thirty[->>];\n"\r
1032         + "    40: forty[->>];\n"\r
1033         + "    50: fifty[->>];\n"\r
1034         + "    60: sixty[->>];\n"\r
1035         + "    70: seventy[->>];\n"\r
1036         + "    80: eighty[->>];\n"\r
1037         + "    90: ninety[->>];\n"\r
1038         + "    100: << hundred[ >>];\n"\r
1039         + "    1000: << thousand[ >>];\n"\r
1040         + "    1,000,000: << million[ >>];\n"\r
1041         + "    1,000,000,000,000: << billion[ >>];\n"\r
1042         + "    1,000,000,000,000,000: =#,##0=;\n"\r
1043         + "%alt-teens:\n"\r
1044         + "    =%simplified=;\n"\r
1045         + "    1000>: <%%alt-hundreds<[ >>];\n"\r
1046         + "    10,000: =%simplified=;\n"\r
1047         + "    1,000,000: << million[ >%simplified>];\n"\r
1048         + "    1,000,000,000,000: << billion[ >%simplified>];\n"\r
1049         + "    1,000,000,000,000,000: =#,##0=;\n"\r
1050         + "%%alt-hundreds:\n"\r
1051         + "    0: SHOULD NEVER GET HERE!;\n"\r
1052         + "    10: <%simplified< thousand;\n"\r
1053         + "    11: =%simplified= hundred>%%empty>;\n"\r
1054         + "%%empty:\n"\r
1055         + "    0:;"\r
1056         + "%ordinal:\n"\r
1057         + "    zeroth; first; second; third; fourth; fifth; sixth; seventh;\n"\r
1058         + "        eighth; ninth;\n"\r
1059         + "    tenth; eleventh; twelfth; thirteenth; fourteenth;\n"\r
1060         + "        fifteenth; sixteenth; seventeenth; eighteenth;\n"\r
1061         + "        nineteenth;\n"\r
1062         + "    twentieth; twenty->>;\n"\r
1063         + "    30: thirtieth; thirty->>;\n"\r
1064         + "    40: fortieth; forty->>;\n"\r
1065         + "    50: fiftieth; fifty->>;\n"\r
1066         + "    60: sixtieth; sixty->>;\n"\r
1067         + "    70: seventieth; seventy->>;\n"\r
1068         + "    80: eightieth; eighty->>;\n"\r
1069         + "    90: ninetieth; ninety->>;\n"\r
1070         + "    100: <%simplified< hundredth; <%simplified< hundred >>;\n"\r
1071         + "    1000: <%simplified< thousandth; <%simplified< thousand >>;\n"\r
1072         + "    1,000,000: <%simplified< millionth; <%simplified< million >>;\n"\r
1073         + "    1,000,000,000,000: <%simplified< billionth;\n"\r
1074         + "        <%simplified< billion >>;\n"\r
1075         + "    1,000,000,000,000,000: =#,##0=;"\r
1076         + "%default:\n"\r
1077         + "    -x: minus >>;\n"\r
1078         + "    x.x: << point >>;\n"\r
1079         + "    =%simplified=;\n"\r
1080         + "    100: << hundred[ >%%and>];\n"\r
1081         + "    1000: << thousand[ >%%and>];\n"\r
1082         + "    100,000>>: << thousand[>%%commas>];\n"\r
1083         + "    1,000,000: << million[>%%commas>];\n"\r
1084         + "    1,000,000,000,000: << billion[>%%commas>];\n"\r
1085         + "    1,000,000,000,000,000: =#,##0=;\n"\r
1086         + "%%and:\n"\r
1087         + "    and =%default=;\n"\r
1088         + "    100: =%default=;\n"\r
1089         + "%%commas:\n"\r
1090         + "    ' and =%default=;\n"\r
1091         + "    100: , =%default=;\n"\r
1092         + "    1000: , <%default< thousand, >%default>;\n"\r
1093         + "    1,000,000: , =%default=;"\r
1094         + "%%lenient-parse:\n"\r
1095         + "    & ' ' , ',' ;\n";\r
1096 \r
1097 }\r
1098 \r