]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/tests/collate/src/com/ibm/icu/dev/test/format/RbnfLenientScannerTest.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / tests / collate / src / com / ibm / icu / dev / test / format / RbnfLenientScannerTest.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 2009-2010, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 package com.ibm.icu.dev.test.format;\r
8 \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
13 \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
19 \r
20 public class RbnfLenientScannerTest extends TestFmwk {\r
21     private static final RbnfLenientScannerProvider provider = new RbnfScannerProviderImpl();\r
22 \r
23     public static void main(String[] args) {\r
24         try {\r
25           new RbnfLenientScannerTest().run(args);\r
26         }\r
27         catch (Throwable e) {\r
28             System.out.println("Entire test failed because of exception: "\r
29                                + e.toString());\r
30             e.printStackTrace();\r
31         }\r
32     }\r
33 \r
34     /**\r
35      * Ensure that the default provider is instantiated and used if none is set\r
36      * and lenient parse is on.\r
37      */\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
46         };\r
47         doLenientParseTest(formatter, lpTestData);\r
48     }\r
49 \r
50     /**\r
51      * Perform a simple spot check on the English spellout rules\r
52      */\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
68         };\r
69         doLenientParseTest(formatter, lpTestData);\r
70     }\r
71 \r
72     /**\r
73      * Perform a simple spot check on the duration-formatting rules\r
74      */\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
83         };\r
84         doLenientParseTest(formatter, lpTestData);\r
85     }\r
86 \r
87     /**\r
88      * Perform a simple spot check on the French spellout rules\r
89      */\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
99         };\r
100         doLenientParseTest(formatter, lpTestData);\r
101     }\r
102 \r
103     /**\r
104      * Perform a simple spot check on the German spellout rules\r
105      */\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
114         };\r
115         doLenientParseTest(formatter, lpTestData);\r
116     }\r
117 \r
118     public void TestAllLocales() {\r
119         StringBuffer errors = null;\r
120         ULocale[] locales = ULocale.getAvailableLocales();\r
121         String[] names = {\r
122             " (spellout) ",\r
123             " (ordinal)  ",\r
124             " (duration) "\r
125         };\r
126         double[] numbers = {45.678, 1, 2, 10, 11, 100, 110, 200, 1000, 1111, -1111};\r
127         Random r = null;\r
128 \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
133 \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
139                 testParse = false;\r
140                 for (int k = 0; k < parseLocales.length; k++) {\r
141                     if (loc.toString().equals(parseLocales[k])) {\r
142                         testParse = true;\r
143                         break;\r
144                     }\r
145                 }\r
146             } else {\r
147                 //RBNF parse is too slow.  Increase count only for debugging purpose for now.\r
148                 //count = 100;\r
149             }\r
150 \r
151             for (int j = 0; j < 3; ++j) {\r
152                 RuleBasedNumberFormat fmt = new RuleBasedNumberFormat(loc, j+1);\r
153 \r
154                 for (int c = 0; c < count; c++) {\r
155                     double n;\r
156                     if (c < numbers.length) {\r
157                         n = numbers[c];\r
158                     } else {\r
159                         if (r == null) {\r
160                             r = createRandom();\r
161                         }\r
162                         n = ((int)(r.nextInt(10000) - 3000)) / 16d;\r
163                     }\r
164 \r
165                     String s = fmt.format(n);\r
166                     logln(loc.getName() + names[j] + "success format: " + n + " -> " + s);\r
167 \r
168                     if (testParse) {\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
171                         try {\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
176 \r
177                             // lenient parse\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
184                             logln(msg);\r
185                             if (errors == null) {\r
186                                 errors = new StringBuffer();\r
187                             }\r
188                             errors.append("\n" + msg);\r
189                         }\r
190                     }\r
191                 }\r
192             }\r
193         }\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
198         }\r
199     }\r
200 \r
201     void doLenientParseTest(RuleBasedNumberFormat formatter,\r
202                             String[][] testData) {\r
203         NumberFormat decFmt = NumberFormat.getInstance(Locale.US);\r
204 \r
205         try {\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
210 \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
215                 }\r
216             }\r
217         }\r
218         catch (Throwable e) {\r
219             errln("Test failed with exception: " + e.toString());\r
220             e.printStackTrace();\r
221         }\r
222     }\r
223 }\r