2 *******************************************************************************
\r
3 * Copyright (C) 1996-2009, 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.math.BigInteger;
\r
10 import java.text.DecimalFormat;
\r
11 import java.text.NumberFormat;
\r
12 import java.text.ParseException;
\r
13 import java.util.Locale;
\r
14 import java.util.Random;
\r
16 import com.ibm.icu.dev.test.TestFmwk;
\r
17 import com.ibm.icu.text.RuleBasedNumberFormat;
\r
18 import com.ibm.icu.util.ULocale;
\r
21 * This does not test lenient parse mode, since testing the default implementation
\r
22 * introduces a dependency on collation. See RbnfLenientScannerTest.
\r
24 public class RbnfTest extends TestFmwk {
\r
25 public static void main(String[] args) {
\r
26 RbnfTest test = new RbnfTest();
\r
31 catch (Throwable e) {
\r
32 System.out.println("Entire test failed because of exception: "
\r
34 e.printStackTrace();
\r
38 static String fracRules =
\r
40 // this rule formats the number if it's 1 or more. It formats
\r
41 // the integral part using a DecimalFormat ("#,##0" puts
\r
42 // thousands separators in the right places) and the fractional
\r
43 // part using %%frac. If there is no fractional part, it
\r
44 // just shows the integral part.
\r
45 " x.0: <#,##0<[ >%%frac>];\n" +
\r
46 // this rule formats the number if it's between 0 and 1. It
\r
47 // shows only the fractional part (0.5 shows up as "1/2," not
\r
49 " 0.x: >%%frac>;\n" +
\r
50 // the fraction rule set. This works the same way as the one in the
\r
51 // preceding example: We multiply the fractional part of the number
\r
52 // being formatted by each rule's base value and use the rule that
\r
53 // produces the result closest to 0 (or the first rule that produces 0).
\r
54 // Since we only provide rules for the numbers from 2 to 10, we know
\r
55 // we'll get a fraction with a denominator between 2 and 10.
\r
56 // "<0<" causes the numerator of the fraction to be formatted
\r
71 char[] fracRulesArr = fracRules.toCharArray();
\r
72 int len = fracRulesArr.length;
\r
74 for (int i = 0; i < len; ++i) {
\r
75 char ch = fracRulesArr[i];
\r
77 change = 2; // change ok
\r
78 } else if (ch == ':') {
\r
79 change = 1; // change, but once we hit a non-space char, don't change
\r
80 } else if (ch == ' ') {
\r
82 fracRulesArr[i] = (char)0x200e;
\r
90 fracRules = new String(fracRulesArr);
\r
93 static final String durationInSecondsRules =
\r
94 // main rule set for formatting with words
\r
96 // take care of singular and plural forms of "second"
\r
97 + " 0 seconds; 1 second; =0= seconds;\n"
\r
98 // use %%min to format values greater than 60 seconds
\r
99 + " 60/60: <%%min<[, >>];\n"
\r
100 // use %%hr to format values greater than 3,600 seconds
\r
101 // (the ">>>" below causes us to see the number of minutes
\r
102 // when when there are zero minutes)
\r
103 + " 3600/60: <%%hr<[, >>>];\n"
\r
104 // this rule set takes care of the singular and plural forms
\r
107 + " 0 minutes; 1 minute; =0= minutes;\n"
\r
108 // this rule set takes care of the singular and plural forms
\r
111 + " 0 hours; 1 hour; =0= hours;\n"
\r
113 // main rule set for formatting in numerals
\r
114 + "%in-numerals:\n"
\r
115 // values below 60 seconds are shown with "sec."
\r
117 // higher values are shown with colons: %%min-sec is used for
\r
118 // values below 3,600 seconds...
\r
119 + " 60: =%%min-sec=;\n"
\r
120 // ...and %%hr-min-sec is used for values of 3,600 seconds
\r
122 + " 3600: =%%hr-min-sec=;\n"
\r
123 // this rule causes values of less than 10 minutes to show without
\r
127 + " 60/60: <0<>>;\n"
\r
128 // this rule set is used for values of 3,600 or more. Minutes are always
\r
129 // shown, and always shown with two digits
\r
130 + "%%hr-min-sec:\n"
\r
132 + " 60/60: <00<>>;\n"
\r
133 + " 3600/60: <#,##0<:>>>;\n"
\r
134 // the lenient-parse rules allow several different characters to be used
\r
135 // as delimiters between hours, minutes, and seconds
\r
136 + "%%lenient-parse:\n"
\r
137 + " & : = . = ' ' = -;\n";
\r
139 public void TestCoverage() {
\r
140 // extra calls to boost coverage numbers
\r
141 RuleBasedNumberFormat fmt0 = new RuleBasedNumberFormat(RuleBasedNumberFormat.SPELLOUT);
\r
142 RuleBasedNumberFormat fmt1 = (RuleBasedNumberFormat)fmt0.clone();
\r
143 RuleBasedNumberFormat fmt2 = new RuleBasedNumberFormat(RuleBasedNumberFormat.SPELLOUT);
\r
144 if (!fmt0.equals(fmt0)) {
\r
145 errln("self equality fails");
\r
147 if (!fmt0.equals(fmt1)) {
\r
148 errln("clone equality fails");
\r
150 if (!fmt0.equals(fmt2)) {
\r
151 errln("duplicate equality fails");
\r
153 String str = fmt0.toString();
\r
156 RuleBasedNumberFormat fmt3 = new RuleBasedNumberFormat(durationInSecondsRules);
\r
158 if (fmt0.equals(fmt3)) {
\r
159 errln("nonequal fails");
\r
161 if (!fmt3.equals(fmt3)) {
\r
162 errln("self equal 2 fails");
\r
164 str = fmt3.toString();
\r
167 String[] names = fmt3.getRuleSetNames();
\r
170 fmt3.setDefaultRuleSet(null);
\r
171 fmt3.setDefaultRuleSet("%%foo");
\r
172 errln("sdrf %%foo didn't fail");
\r
174 catch (Exception e) {
\r
175 logln("Got the expected exception");
\r
179 fmt3.setDefaultRuleSet("%bogus");
\r
180 errln("sdrf %bogus didn't fail");
\r
182 catch (Exception e) {
\r
183 logln("Got the expected exception");
\r
187 str = fmt3.format(2.3, names[0]);
\r
189 str = fmt3.format(2.3, "%%foo");
\r
190 errln("format double %%foo didn't fail");
\r
192 catch (Exception e) {
\r
193 logln("Got the expected exception");
\r
197 str = fmt3.format(123L, names[0]);
\r
199 str = fmt3.format(123L, "%%foo");
\r
200 errln("format double %%foo didn't fail");
\r
202 catch (Exception e) {
\r
203 logln("Got the expected exception");
\r
206 RuleBasedNumberFormat fmt4 = new RuleBasedNumberFormat(fracRules, Locale.ENGLISH);
\r
207 RuleBasedNumberFormat fmt5 = new RuleBasedNumberFormat(fracRules, Locale.ENGLISH);
\r
208 str = fmt4.toString();
\r
210 if (!fmt4.equals(fmt5)) {
\r
211 errln("duplicate 2 equality failed");
\r
213 str = fmt4.format(123L);
\r
216 Number num = fmt4.parse(str);
\r
217 logln(num.toString());
\r
219 catch (Exception e) {
\r
220 errln("parse caught exception");
\r
223 str = fmt4.format(.000123);
\r
226 Number num = fmt4.parse(str);
\r
227 logln(num.toString());
\r
229 catch (Exception e) {
\r
230 errln("parse caught exception");
\r
233 str = fmt4.format(456.000123);
\r
236 Number num = fmt4.parse(str);
\r
237 logln(num.toString());
\r
239 catch (Exception e) {
\r
240 errln("parse caught exception");
\r
244 public void TestUndefinedSpellout() {
\r
245 Locale greek = new Locale("el", "", "");
\r
246 RuleBasedNumberFormat[] formatters = {
\r
247 new RuleBasedNumberFormat(greek, RuleBasedNumberFormat.SPELLOUT),
\r
248 new RuleBasedNumberFormat(greek, RuleBasedNumberFormat.ORDINAL),
\r
249 new RuleBasedNumberFormat(greek, RuleBasedNumberFormat.DURATION),
\r
277 NumberFormat decFormat = NumberFormat.getInstance(Locale.US);
\r
278 for (int j = 0; j < formatters.length; ++j) {
\r
279 com.ibm.icu.text.NumberFormat formatter = formatters[j];
\r
280 logln("formatter[" + j + "]");
\r
281 for (int i = 0; i < data.length; ++i) {
\r
283 String result = formatter.format(decFormat.parse(data[i]));
\r
284 logln("[" + i + "] " + data[i] + " ==> " + result);
\r
286 catch (Exception e) {
\r
287 errln("formatter[" + j + "], data[" + i + "] " + data[i] + " threw exception " + e.getMessage());
\r
294 * Perform a simple spot check on the English spellout rules
\r
296 public void TestEnglishSpellout() {
\r
297 RuleBasedNumberFormat formatter
\r
298 = new RuleBasedNumberFormat(Locale.US,
\r
299 RuleBasedNumberFormat.SPELLOUT);
\r
300 String[][] testData = {
\r
302 { "15", "fifteen" },
\r
303 { "20", "twenty" },
\r
304 { "23", "twenty-three" },
\r
305 { "73", "seventy-three" },
\r
306 { "88", "eighty-eight" },
\r
307 { "100", "one hundred" },
\r
308 { "106", "one hundred six" },
\r
309 { "127", "one hundred twenty-seven" },
\r
310 { "200", "two hundred" },
\r
311 { "579", "five hundred seventy-nine" },
\r
312 { "1,000", "one thousand" },
\r
313 { "2,000", "two thousand" },
\r
314 { "3,004", "three thousand four" },
\r
315 { "4,567", "four thousand five hundred sixty-seven" },
\r
316 { "15,943", "fifteen thousand nine hundred forty-three" },
\r
317 { "2,345,678", "two million three hundred forty-five "
\r
318 + "thousand six hundred seventy-eight" },
\r
319 { "-36", "minus thirty-six" },
\r
320 { "234.567", "two hundred thirty-four point five six seven" }
\r
323 doTest(formatter, testData, true);
\r
327 * Perform a simple spot check on the English ordinal-abbreviation rules
\r
329 public void TestOrdinalAbbreviations() {
\r
330 RuleBasedNumberFormat formatter
\r
331 = new RuleBasedNumberFormat(Locale.US,
\r
332 RuleBasedNumberFormat.ORDINAL);
\r
333 String[][] testData = {
\r
334 { "1", "1\u02e2\u1d57" },
\r
335 { "2", "2\u207f\u1d48" },
\r
336 { "3", "3\u02b3\u1d48" },
\r
337 { "4", "4\u1d57\u02b0" },
\r
338 { "7", "7\u1d57\u02b0" },
\r
339 { "10", "10\u1d57\u02b0" },
\r
340 { "11", "11\u1d57\u02b0" },
\r
341 { "13", "13\u1d57\u02b0" },
\r
342 { "20", "20\u1d57\u02b0" },
\r
343 { "21", "21\u02e2\u1d57" },
\r
344 { "22", "22\u207f\u1d48" },
\r
345 { "23", "23\u02b3\u1d48" },
\r
346 { "24", "24\u1d57\u02b0" },
\r
347 { "33", "33\u02b3\u1d48" },
\r
348 { "102", "102\u207f\u1d48" },
\r
349 { "312", "312\u1d57\u02b0" },
\r
350 { "12,345", "12,345\u1d57\u02b0" }
\r
353 doTest(formatter, testData, false);
\r
357 * Perform a simple spot check on the duration-formatting rules
\r
359 public void TestDurations() {
\r
360 RuleBasedNumberFormat formatter
\r
361 = new RuleBasedNumberFormat(Locale.US,
\r
362 RuleBasedNumberFormat.DURATION);
\r
363 String[][] testData = {
\r
364 { "3,600", "1:00:00" }, //move me and I fail
\r
367 { "24", "24 sec." },
\r
371 { "666", "11:06" },
\r
372 // { "3,600", "1:00:00" },
\r
373 { "3,740", "1:02:20" },
\r
374 { "10,293", "2:51:33" }
\r
377 doTest(formatter, testData, true);
\r
381 * Perform a simple spot check on the Spanish spellout rules
\r
383 public void TestSpanishSpellout() {
\r
384 RuleBasedNumberFormat formatter
\r
385 = new RuleBasedNumberFormat(new Locale("es", "es",
\r
386 ""), RuleBasedNumberFormat.SPELLOUT);
\r
387 String[][] testData = {
\r
390 { "16", "diecis\u00e9is" },
\r
391 { "20", "veinte" },
\r
392 { "24", "veinticuatro" },
\r
393 { "26", "veintis\u00e9is" },
\r
394 { "73", "setenta y tres" },
\r
395 { "88", "ochenta y ocho" },
\r
397 { "106", "ciento seis" },
\r
398 { "127", "ciento veintisiete" },
\r
399 { "200", "doscientos" },
\r
400 { "579", "quinientos setenta y nueve" },
\r
401 { "1,000", "mil" },
\r
402 { "2,000", "dos mil" },
\r
403 { "3,004", "tres mil cuatro" },
\r
404 { "4,567", "cuatro mil quinientos sesenta y siete" },
\r
405 { "15,943", "quince mil novecientos cuarenta y tres" },
\r
406 { "2,345,678", "dos millones trescientos cuarenta y cinco mil "
\r
407 + "seiscientos setenta y ocho"},
\r
408 { "-36", "menos treinta y seis" },
\r
409 { "234.567", "doscientos treinta y cuatro coma cinco seis siete" }
\r
412 doTest(formatter, testData, true);
\r
416 * Perform a simple spot check on the French spellout rules
\r
418 public void TestFrenchSpellout() {
\r
419 RuleBasedNumberFormat formatter
\r
420 = new RuleBasedNumberFormat(Locale.FRANCE,
\r
421 RuleBasedNumberFormat.SPELLOUT);
\r
422 String[][] testData = {
\r
424 { "15", "quinze" },
\r
426 { "21", "vingt-et-un" },
\r
427 { "23", "vingt-trois" },
\r
428 { "62", "soixante-deux" },
\r
429 { "70", "soixante-dix" },
\r
430 { "71", "soixante-et-onze" },
\r
431 { "73", "soixante-treize" },
\r
432 { "80", "quatre-vingts" },
\r
433 { "88", "quatre-vingt-huit" },
\r
435 { "106", "cent-six" },
\r
436 { "127", "cent-vingt-sept" },
\r
437 { "200", "deux-cents" },
\r
438 { "579", "cinq-cent-soixante-dix-neuf" },
\r
439 { "1,000", "mille" },
\r
440 { "1,123", "mille-cent-vingt-trois" },
\r
441 { "1,594", "mille-cinq-cent-quatre-vingt-quatorze" },
\r
442 { "2,000", "deux-mille" },
\r
443 { "3,004", "trois-mille-quatre" },
\r
444 { "4,567", "quatre-mille-cinq-cent-soixante-sept" },
\r
445 { "15,943", "quinze-mille-neuf-cent-quarante-trois" },
\r
446 { "2,345,678", "deux millions trois-cent-quarante-cinq-mille-"
\r
447 + "six-cent-soixante-dix-huit" },
\r
448 { "-36", "moins trente-six" },
\r
449 { "234.567", "deux-cent-trente-quatre virgule cinq six sept" }
\r
452 doTest(formatter, testData, true);
\r
456 * Perform a simple spot check on the Swiss French spellout rules
\r
458 public void TestSwissFrenchSpellout() {
\r
459 RuleBasedNumberFormat formatter
\r
460 = new RuleBasedNumberFormat(new Locale("fr", "CH",
\r
461 ""), RuleBasedNumberFormat.SPELLOUT);
\r
462 String[][] testData = {
\r
464 { "15", "quinze" },
\r
466 { "21", "vingt-et-un" },
\r
467 { "23", "vingt-trois" },
\r
468 { "62", "soixante-deux" },
\r
469 { "70", "septante" },
\r
470 { "71", "septante-et-un" },
\r
471 { "73", "septante-trois" },
\r
472 { "80", "huitante" },
\r
473 { "88", "huitante-huit" },
\r
475 { "106", "cent-six" },
\r
476 { "127", "cent-vingt-sept" },
\r
477 { "200", "deux-cents" },
\r
478 { "579", "cinq-cent-septante-neuf" },
\r
479 { "1,000", "mille" },
\r
480 { "1,123", "mille-cent-vingt-trois" },
\r
481 { "1,594", "mille-cinq-cent-nonante-quatre" },
\r
482 { "2,000", "deux-mille" },
\r
483 { "3,004", "trois-mille-quatre" },
\r
484 { "4,567", "quatre-mille-cinq-cent-soixante-sept" },
\r
485 { "15,943", "quinze-mille-neuf-cent-quarante-trois" },
\r
486 { "2,345,678", "deux millions trois-cent-quarante-cinq-mille-"
\r
487 + "six-cent-septante-huit" },
\r
488 { "-36", "moins trente-six" },
\r
489 { "234.567", "deux-cent-trente-quatre virgule cinq six sept" }
\r
492 doTest(formatter, testData, true);
\r
496 * Perform a simple spot check on the Italian spellout rules
\r
498 public void TestItalianSpellout() {
\r
499 RuleBasedNumberFormat formatter
\r
500 = new RuleBasedNumberFormat(Locale.ITALIAN,
\r
501 RuleBasedNumberFormat.SPELLOUT);
\r
502 String[][] testData = {
\r
504 { "15", "quindici" },
\r
506 { "23", "venti\u00ADtr\u00E9" },
\r
507 { "73", "settanta\u00ADtr\u00E9" },
\r
508 { "88", "ottant\u00ADotto" },
\r
509 { "100", "cento" },
\r
510 { "106", "cento\u00ADsei" },
\r
511 { "108", "cent\u00ADotto" },
\r
512 { "127", "cento\u00ADventi\u00ADsette" },
\r
513 { "181", "cent\u00ADottant\u00ADuno" },
\r
514 { "200", "due\u00ADcento" },
\r
515 { "579", "cinque\u00ADcento\u00ADsettanta\u00ADnove" },
\r
516 { "1,000", "mille" },
\r
517 { "2,000", "due\u00ADmila" },
\r
518 { "3,004", "tre\u00ADmila\u00ADquattro" },
\r
519 { "4,567", "quattro\u00ADmila\u00ADcinque\u00ADcento\u00ADsessanta\u00ADsette" },
\r
520 { "15,943", "quindici\u00ADmila\u00ADnove\u00ADcento\u00ADquaranta\u00ADtr\u00E9" },
\r
521 { "-36", "meno trenta\u00ADsei" },
\r
522 { "234.567", "due\u00ADcento\u00ADtrenta\u00ADquattro virgola cinque sei sette" }
\r
525 doTest(formatter, testData, true);
\r
529 * Perform a simple spot check on the German spellout rules
\r
531 public void TestGermanSpellout() {
\r
532 RuleBasedNumberFormat formatter
\r
533 = new RuleBasedNumberFormat(Locale.GERMANY,
\r
534 RuleBasedNumberFormat.SPELLOUT);
\r
535 String[][] testData = {
\r
537 { "15", "f\u00fcnfzehn" },
\r
538 { "20", "zwanzig" },
\r
539 { "23", "drei\u00ADund\u00ADzwanzig" },
\r
540 { "73", "drei\u00ADund\u00ADsiebzig" },
\r
541 { "88", "acht\u00ADund\u00ADachtzig" },
\r
542 { "100", "ein\u00ADhundert" },
\r
543 { "106", "ein\u00ADhundert\u00ADsechs" },
\r
544 { "127", "ein\u00ADhundert\u00ADsieben\u00ADund\u00ADzwanzig" },
\r
545 { "200", "zwei\u00ADhundert" },
\r
546 { "579", "f\u00fcnf\u00ADhundert\u00ADneun\u00ADund\u00ADsiebzig" },
\r
547 { "1,000", "ein\u00ADtausend" },
\r
548 { "2,000", "zwei\u00ADtausend" },
\r
549 { "3,004", "drei\u00ADtausend\u00ADvier" },
\r
550 { "4,567", "vier\u00ADtausend\u00ADf\u00fcnf\u00ADhundert\u00ADsieben\u00ADund\u00ADsechzig" },
\r
551 { "15,943", "f\u00fcnfzehn\u00ADtausend\u00ADneun\u00ADhundert\u00ADdrei\u00ADund\u00ADvierzig" },
\r
552 { "2,345,678", "zwei Millionen drei\u00ADhundert\u00ADf\u00fcnf\u00ADund\u00ADvierzig\u00ADtausend\u00AD"
\r
553 + "sechs\u00ADhundert\u00ADacht\u00ADund\u00ADsiebzig" }
\r
556 doTest(formatter, testData, true);
\r
560 * Perform a simple spot check on the Thai spellout rules
\r
562 public void TestThaiSpellout() {
\r
563 RuleBasedNumberFormat formatter
\r
564 = new RuleBasedNumberFormat(new Locale("th", "TH", ""),
\r
565 RuleBasedNumberFormat.SPELLOUT);
\r
566 String[][] testData = {
\r
567 { "0", "\u0e28\u0e39\u0e19\u0e22\u0e4c" },
\r
568 { "1", "\u0e2b\u0e19\u0e36\u0e48\u0e07" },
\r
569 { "10", "\u0e2a\u0e34\u0e1a" },
\r
570 { "11", "\u0e2a\u0e34\u0e1a\u200b\u0e40\u0e2d\u0e47\u0e14" },
\r
571 { "21", "\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e40\u0e2d\u0e47\u0e14" },
\r
572 { "101", "\u0e2b\u0e19\u0e36\u0e48\u0e07\u200b\u0e23\u0e49\u0e2d\u0e22\u200b\u0e2b\u0e19\u0e36\u0e48\u0e07" },
\r
573 { "1.234", "\u0e2b\u0e19\u0e36\u0e48\u0e07\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e2d\u0e07\u0e2a\u0e32\u0e21\u0e2a\u0e35\u0e48" },
\r
574 { "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
575 { "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
576 { "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
577 { "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
578 { "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
581 doTest(formatter, testData, true);
\r
584 public void TestFractionalRuleSet() {
\r
587 RuleBasedNumberFormat formatter =
\r
588 new RuleBasedNumberFormat(fracRules, Locale.ENGLISH);
\r
590 String[][] testData = {
\r
597 { ".1428", "1/7" },
\r
598 { ".1667", "1/6" },
\r
603 { "1.1", "1 1/10" },
\r
604 { "2.11", "2 1/9" },
\r
605 { "3.125", "3 1/8" },
\r
606 { "4.1428", "4 1/7" },
\r
607 { "5.1667", "5 1/6" },
\r
608 { "6.2", "6 1/5" },
\r
609 { "7.25", "7 1/4" },
\r
610 { "8.333", "8 1/3" },
\r
611 { "9.5", "9 1/2" },
\r
612 { ".2222", "2/9" },
\r
613 { ".4444", "4/9" },
\r
614 { ".5555", "5/9" },
\r
615 { "1.2856", "1 2/7" }
\r
617 doTest(formatter, testData, false); // exact values aren't parsable from fractions
\r
620 public void TestSwedishSpellout()
\r
622 Locale locale = new Locale("sv", "", "");
\r
623 RuleBasedNumberFormat formatter = new RuleBasedNumberFormat(locale, RuleBasedNumberFormat.SPELLOUT);
\r
625 String[][] testDataDefault = {
\r
626 { "101", "ett\u00ADhundra\u00ADett" },
\r
627 { "123", "ett\u00ADhundra\u00ADtjugo\u00ADtre" },
\r
628 { "1,001", "ettusen ett" },
\r
629 { "1,100", "ettusen ett\u00ADhundra" },
\r
630 { "1,101", "ettusen ett\u00ADhundra\u00ADett" },
\r
631 { "1,234", "ettusen tv\u00e5\u00ADhundra\u00ADtrettio\u00ADfyra" },
\r
632 { "10,001", "tio\u00ADtusen ett" },
\r
633 { "11,000", "elva\u00ADtusen" },
\r
634 { "12,000", "tolv\u00ADtusen" },
\r
635 { "20,000", "tjugo-tusen" },
\r
636 { "21,000", "tjugo\u00ADett-tusen" },
\r
637 { "21,001", "tjugo\u00ADett-tusen ett" },
\r
638 { "200,000", "tv\u00e5\u00ADhundra-tusen" },
\r
639 { "201,000", "tv\u00e5\u00ADhundra\u00ADett-tusen" },
\r
640 { "200,200", "tv\u00e5\u00ADhundra-tusen tv\u00e5\u00ADhundra" },
\r
641 { "2,002,000", "tv\u00e5 miljoner tv\u00e5\u00ADtusen" },
\r
642 { "12,345,678", "tolv miljoner tre\u00ADhundra\u00ADfyrtio\u00ADfem-tusen sex\u00ADhundra\u00ADsjuttio\u00AD\u00e5tta" },
\r
643 { "123,456.789", "ett\u00ADhundra\u00ADtjugo\u00ADtre-tusen fyra\u00ADhundra\u00ADfemtio\u00ADsex komma sju \u00e5tta nio" },
\r
644 { "-12,345.678", "minus tolv\u00ADtusen tre\u00ADhundra\u00ADfyrtio\u00ADfem komma sex sju \u00e5tta" }
\r
647 logln("testing default rules");
\r
648 doTest(formatter, testDataDefault, true);
\r
650 String[][] testDataNeutrum = {
\r
651 { "101", "ett\u00adhundra\u00aden" },
\r
652 { "1,001", "ettusen en" },
\r
653 { "1,101", "ettusen ett\u00adhundra\u00aden" },
\r
654 { "10,001", "tio\u00adtusen en" },
\r
655 { "21,001", "tjugo\u00aden\u00adtusen en" }
\r
658 formatter.setDefaultRuleSet("%spellout-cardinal-neutre");
\r
659 logln("testing neutrum rules");
\r
660 doTest(formatter, testDataNeutrum, true);
\r
662 String[][] testDataYear = {
\r
663 { "101", "ett\u00adhundra\u00adett" },
\r
664 { "900", "nio\u00adhundra" },
\r
665 { "1,001", "ettusen ett" },
\r
666 { "1,100", "elva\u00adhundra" },
\r
667 { "1,101", "elva\u00adhundra\u00adett" },
\r
668 { "1,234", "tolv\u00adhundra\u00adtrettio\u00adfyra" },
\r
669 { "2,001", "tjugo\u00adhundra\u00adett" },
\r
670 { "10,001", "tio\u00adtusen ett" }
\r
673 formatter.setDefaultRuleSet("%spellout-numbering-year");
\r
674 logln("testing year rules");
\r
675 doTest(formatter, testDataYear, true);
\r
678 public void TestBigNumbers() {
\r
679 BigInteger bigI = new BigInteger("1234567890", 10);
\r
680 StringBuffer buf = new StringBuffer();
\r
681 RuleBasedNumberFormat fmt = new RuleBasedNumberFormat(RuleBasedNumberFormat.SPELLOUT);
\r
682 fmt.format(bigI, buf, null);
\r
683 logln("big int: " + buf.toString());
\r
686 java.math.BigDecimal bigD = new java.math.BigDecimal(bigI);
\r
687 fmt.format(bigD, buf, null);
\r
688 logln("big dec: " + buf.toString());
\r
691 public void TestTrailingSemicolon() {
\r
692 String thaiRules =
\r
694 " -x: \u0e25\u0e1a>>;\n" +
\r
695 " x.x: <<\u0e08\u0e38\u0e14>>>;\n" +
\r
696 " \u0e28\u0e39\u0e19\u0e22\u0e4c; \u0e2b\u0e19\u0e36\u0e48\u0e07; \u0e2a\u0e2d\u0e07; \u0e2a\u0e32\u0e21;\n" +
\r
697 " \u0e2a\u0e35\u0e48; \u0e2b\u0e49\u0e32; \u0e2b\u0e01; \u0e40\u0e08\u0e47\u0e14; \u0e41\u0e1b\u0e14;\n" +
\r
698 " \u0e40\u0e01\u0e49\u0e32; \u0e2a\u0e34\u0e1a; \u0e2a\u0e34\u0e1a\u0e40\u0e2d\u0e47\u0e14;\n" +
\r
699 " \u0e2a\u0e34\u0e1a\u0e2a\u0e2d\u0e07; \u0e2a\u0e34\u0e1a\u0e2a\u0e32\u0e21;\n" +
\r
700 " \u0e2a\u0e34\u0e1a\u0e2a\u0e35\u0e48; \u0e2a\u0e34\u0e1a\u0e2b\u0e49\u0e32;\n" +
\r
701 " \u0e2a\u0e34\u0e1a\u0e2b\u0e01; \u0e2a\u0e34\u0e1a\u0e40\u0e08\u0e47\u0e14;\n" +
\r
702 " \u0e2a\u0e34\u0e1a\u0e41\u0e1b\u0e14; \u0e2a\u0e34\u0e1a\u0e40\u0e01\u0e49\u0e32;\n" +
\r
703 " 20: \u0e22\u0e35\u0e48\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
\r
704 " 30: \u0e2a\u0e32\u0e21\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
\r
705 " 40: \u0e2a\u0e35\u0e48\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
\r
706 " 50: \u0e2b\u0e49\u0e32\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
\r
707 " 60: \u0e2b\u0e01\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
\r
708 " 70: \u0e40\u0e08\u0e47\u0e14\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
\r
709 " 80: \u0e41\u0e1b\u0e14\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
\r
710 " 90: \u0e40\u0e01\u0e49\u0e32\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
\r
711 " 100: <<\u0e23\u0e49\u0e2d\u0e22[>>];\n" +
\r
712 " 1000: <<\u0e1e\u0e31\u0e19[>>];\n" +
\r
713 " 10000: <<\u0e2b\u0e21\u0e37\u0e48\u0e19[>>];\n" +
\r
714 " 100000: <<\u0e41\u0e2a\u0e19[>>];\n" +
\r
715 " 1,000,000: <<\u0e25\u0e49\u0e32\u0e19[>>];\n" +
\r
716 " 1,000,000,000: <<\u0e1e\u0e31\u0e19\u0e25\u0e49\u0e32\u0e19[>>];\n" +
\r
717 " 1,000,000,000,000: <<\u0e25\u0e49\u0e32\u0e19\u0e25\u0e49\u0e32\u0e19[>>];\n" +
\r
718 " 1,000,000,000,000,000: =#,##0=;\n" +
\r
720 " \u0e28\u0e39\u0e19\u0e22\u0e4c;\n" +
\r
721 " \u0e40\u0e2d\u0e47\u0e14;\n" +
\r
722 " =%default=;\n ; ;; ";
\r
724 RuleBasedNumberFormat formatter
\r
725 = new RuleBasedNumberFormat(thaiRules, new Locale("th", "TH", ""));
\r
727 String[][] testData = {
\r
728 { "0", "\u0e28\u0e39\u0e19\u0e22\u0e4c" },
\r
729 { "1", "\u0e2b\u0e19\u0e36\u0e48\u0e07" },
\r
730 { "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
733 doTest(formatter, testData, true);
\r
736 public void TestSmallValues() {
\r
737 String[][] testData = {
\r
738 { "0.001", "zero point zero zero one" },
\r
739 { "0.0001", "zero point zero zero zero one" },
\r
740 { "0.00001", "zero point zero zero zero zero one" },
\r
741 { "0.000001", "zero point zero zero zero zero zero one" },
\r
742 { "0.0000001", "zero point zero zero zero zero zero zero one" },
\r
743 { "0.00000001", "zero point zero zero zero zero zero zero zero one" },
\r
744 { "0.000000001", "zero point zero zero zero zero zero zero zero zero one" },
\r
745 { "0.0000000001", "zero point zero zero zero zero zero zero zero zero zero one" },
\r
746 { "0.00000000001", "zero point zero zero zero zero zero zero zero zero zero zero one" },
\r
747 { "0.000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero one" },
\r
748 { "0.0000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero one" },
\r
749 { "0.00000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
\r
750 { "0.000000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
\r
751 { "10,000,000.001", "ten million point zero zero one" },
\r
752 { "10,000,000.0001", "ten million point zero zero zero one" },
\r
753 { "10,000,000.00001", "ten million point zero zero zero zero one" },
\r
754 { "10,000,000.000001", "ten million point zero zero zero zero zero one" },
\r
755 { "10,000,000.0000001", "ten million point zero zero zero zero zero zero one" },
\r
756 { "10,000,000.00000001", "ten million point zero zero zero zero zero zero zero one" },
\r
757 { "10,000,000.000000002", "ten million point zero zero zero zero zero zero zero zero two" },
\r
758 { "10,000,000", "ten million" },
\r
759 { "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
760 { "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
761 { "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
762 { "1,234,567.7654321", "one million two hundred thirty-four thousand five hundred sixty-seven point seven six five four three two one" },
\r
763 { "123,456.654321", "one hundred twenty-three thousand four hundred fifty-six point six five four three two one" },
\r
764 { "12,345.54321", "twelve thousand three hundred forty-five point five four three two one" },
\r
765 { "1,234.4321", "one thousand two hundred thirty-four point four three two one" },
\r
766 { "123.321", "one hundred twenty-three point three two one" },
\r
767 { "0.0000000011754944", "zero point zero zero zero zero zero zero zero zero one one seven five four nine four four" },
\r
768 { "0.000001175494351", "zero point zero zero zero zero zero one one seven five four nine four three five one" },
\r
771 RuleBasedNumberFormat formatter
\r
772 = new RuleBasedNumberFormat(Locale.US, RuleBasedNumberFormat.SPELLOUT);
\r
773 doTest(formatter, testData, true);
\r
776 public void TestRuleSetDisplayName() {
\r
777 ULocale.setDefault(ULocale.US);
\r
778 String[][] localizations = new String[][] {
\r
779 /* public rule sets*/
\r
780 {"%simplified", "%default", "%ordinal"},
\r
781 /* display names in "en_US" locale*/
\r
782 {"en_US", "Simplified", "Default", "Ordinal"},
\r
783 /* display names in "zh_Hans" locale*/
\r
784 {"zh_Hans", "\u7B80\u5316", "\u7F3A\u7701", "\u5E8F\u5217"},
\r
785 /* display names in a fake locale*/
\r
786 {"foo_Bar_BAZ", "Simplified", "Default", "Ordinal"}
\r
789 //Construct RuleBasedNumberFormat by rule sets and localizations list
\r
790 RuleBasedNumberFormat formatter
\r
791 = new RuleBasedNumberFormat(ukEnglish, localizations, ULocale.US);
\r
792 RuleBasedNumberFormat f2= new RuleBasedNumberFormat(ukEnglish, localizations);
\r
793 assertTrue("Check the two formatters' equality", formatter.equals(f2));
\r
795 //get displayName by name
\r
796 String[] ruleSetNames = formatter.getRuleSetNames();
\r
797 for (int i=0; i<ruleSetNames.length; i++) {
\r
798 logln("Rule set name: " + ruleSetNames[i]);
\r
799 String RSName_defLoc = formatter.getRuleSetDisplayName(ruleSetNames[i]);
\r
800 assertEquals("Display name in default locale", localizations[1][i+1], RSName_defLoc);
\r
801 String RSName_loc = formatter.getRuleSetDisplayName(ruleSetNames[i], ULocale.CHINA);
\r
802 assertEquals("Display name in Chinese", localizations[2][i+1], RSName_loc);
\r
805 // getDefaultRuleSetName
\r
806 String defaultRS = formatter.getDefaultRuleSetName();
\r
807 //you know that the default rule set is %simplified according to rule sets string ukEnglish
\r
808 assertEquals("getDefaultRuleSetName", "%simplified", defaultRS);
\r
810 //get locales of localizations
\r
811 ULocale[] locales = formatter.getRuleSetDisplayNameLocales();
\r
812 for (int i=0; i<locales.length; i++) {
\r
813 logln(locales[i].getName());
\r
817 String[] RSNames_defLoc = formatter.getRuleSetDisplayNames();
\r
818 for (int i=0; i<RSNames_defLoc.length; i++) {
\r
819 assertEquals("getRuleSetDisplayNames in default locale", localizations[1][i+1], RSNames_defLoc[i]);
\r
822 String[] RSNames_loc = formatter.getRuleSetDisplayNames(ULocale.UK);
\r
823 for (int i=0; i<RSNames_loc.length; i++) {
\r
824 assertEquals("getRuleSetDisplayNames in English", localizations[1][i+1], RSNames_loc[i]);
\r
827 RSNames_loc = formatter.getRuleSetDisplayNames(ULocale.CHINA);
\r
828 for (int i=0; i<RSNames_loc.length; i++) {
\r
829 assertEquals("getRuleSetDisplayNames in Chinese", localizations[2][i+1], RSNames_loc[i]);
\r
832 RSNames_loc = formatter.getRuleSetDisplayNames(new ULocale("foo_Bar_BAZ"));
\r
833 for (int i=0; i<RSNames_loc.length; i++) {
\r
834 assertEquals("getRuleSetDisplayNames in fake locale", localizations[3][i+1], RSNames_loc[i]);
\r
838 public void TestAllLocales() {
\r
839 StringBuffer errors = null;
\r
840 ULocale[] locales = ULocale.getAvailableLocales();
\r
846 double[] numbers = {45.678, 1, 2, 10, 11, 100, 110, 200, 1000, 1111, -1111};
\r
849 // RBNF parse is extremely slow when lenient option is enabled.
\r
850 // For non-exhaustive mode, we only test a few locales.
\r
851 // "nl_NL", "be" had crash problem reported by #6534
\r
852 String[] parseLocales = {"en_US", "nl_NL", "be"};
\r
854 for (int i = 0; i < locales.length; ++i) {
\r
855 ULocale loc = locales[i];
\r
856 int count = numbers.length;
\r
857 boolean testParse = true;
\r
858 if (getInclusion() <= 5) {
\r
860 for (int k = 0; k < parseLocales.length; k++) {
\r
861 if (loc.toString().equals(parseLocales[k])) {
\r
867 //RBNF parse is too slow. Increase count only for debugging purpose for now.
\r
871 for (int j = 0; j < 3; ++j) {
\r
872 RuleBasedNumberFormat fmt = new RuleBasedNumberFormat(loc, j+1);
\r
874 for (int c = 0; c < count; c++) {
\r
876 if (c < numbers.length) {
\r
880 r = createRandom();
\r
882 n = ((int)(r.nextInt(10000) - 3000)) / 16d;
\r
885 String s = fmt.format(n);
\r
886 logln(loc.getName() + names[j] + "success format: " + n + " -> " + s);
\r
889 // We do not validate the result in this test case,
\r
890 // because there are cases which do not round trip by design.
\r
892 // non-lenient parse
\r
893 fmt.setLenientParseMode(false);
\r
894 Number num = fmt.parse(s);
\r
895 logln(loc.getName() + names[j] + "success parse: " + s + " -> " + num);
\r
896 } catch (ParseException pe) {
\r
897 String msg = loc.getName() + names[j] + "ERROR:" + pe.getMessage();
\r
899 if (errors == null) {
\r
900 errors = new StringBuffer();
\r
902 errors.append("\n" + msg);
\r
908 if (errors != null) {
\r
909 //TODO: We need to fix parse problems - see #6895 / #6896
\r
910 //errln(errors.toString());
\r
911 logln(errors.toString());
\r
915 void doTest(RuleBasedNumberFormat formatter, String[][] testData,
\r
916 boolean testParsing) {
\r
917 // NumberFormat decFmt = NumberFormat.getInstance(Locale.US);
\r
918 NumberFormat decFmt = new DecimalFormat("#,###.################");
\r
920 for (int i = 0; i < testData.length; i++) {
\r
921 String number = testData[i][0];
\r
922 String expectedWords = testData[i][1];
\r
923 logln("test[" + i + "] number: " + number + " target: " + expectedWords);
\r
924 Number num = decFmt.parse(number);
\r
925 String actualWords = formatter.format(num);
\r
927 if (!actualWords.equals(expectedWords)) {
\r
928 errln("Spot check format failed: for " + number + ", expected\n "
\r
929 + expectedWords + ", but got\n " +
\r
932 else if (testParsing) {
\r
933 String actualNumber = decFmt.format(formatter
\r
934 .parse(actualWords));
\r
936 if (!actualNumber.equals(number)) {
\r
937 errln("Spot check parse failed: for " + actualWords +
\r
938 ", expected " + number + ", but got " +
\r
944 catch (Throwable e) {
\r
945 e.printStackTrace();
\r
946 errln("Test failed with exception: " + e.toString());
\r
951 * Spellout rules for U.K. English.
\r
952 * I borrow the rule sets for TestRuleSetDisplayName()
\r
954 public static final String ukEnglish =
\r
956 + " -x: minus >>;\n"
\r
957 + " x.x: << point >>;\n"
\r
958 + " zero; one; two; three; four; five; six; seven; eight; nine;\n"
\r
959 + " ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n"
\r
960 + " seventeen; eighteen; nineteen;\n"
\r
961 + " 20: twenty[->>];\n"
\r
962 + " 30: thirty[->>];\n"
\r
963 + " 40: forty[->>];\n"
\r
964 + " 50: fifty[->>];\n"
\r
965 + " 60: sixty[->>];\n"
\r
966 + " 70: seventy[->>];\n"
\r
967 + " 80: eighty[->>];\n"
\r
968 + " 90: ninety[->>];\n"
\r
969 + " 100: << hundred[ >>];\n"
\r
970 + " 1000: << thousand[ >>];\n"
\r
971 + " 1,000,000: << million[ >>];\n"
\r
972 + " 1,000,000,000,000: << billion[ >>];\n"
\r
973 + " 1,000,000,000,000,000: =#,##0=;\n"
\r
975 + " =%simplified=;\n"
\r
976 + " 1000>: <%%alt-hundreds<[ >>];\n"
\r
977 + " 10,000: =%simplified=;\n"
\r
978 + " 1,000,000: << million[ >%simplified>];\n"
\r
979 + " 1,000,000,000,000: << billion[ >%simplified>];\n"
\r
980 + " 1,000,000,000,000,000: =#,##0=;\n"
\r
981 + "%%alt-hundreds:\n"
\r
982 + " 0: SHOULD NEVER GET HERE!;\n"
\r
983 + " 10: <%simplified< thousand;\n"
\r
984 + " 11: =%simplified= hundred>%%empty>;\n"
\r
988 + " zeroth; first; second; third; fourth; fifth; sixth; seventh;\n"
\r
989 + " eighth; ninth;\n"
\r
990 + " tenth; eleventh; twelfth; thirteenth; fourteenth;\n"
\r
991 + " fifteenth; sixteenth; seventeenth; eighteenth;\n"
\r
993 + " twentieth; twenty->>;\n"
\r
994 + " 30: thirtieth; thirty->>;\n"
\r
995 + " 40: fortieth; forty->>;\n"
\r
996 + " 50: fiftieth; fifty->>;\n"
\r
997 + " 60: sixtieth; sixty->>;\n"
\r
998 + " 70: seventieth; seventy->>;\n"
\r
999 + " 80: eightieth; eighty->>;\n"
\r
1000 + " 90: ninetieth; ninety->>;\n"
\r
1001 + " 100: <%simplified< hundredth; <%simplified< hundred >>;\n"
\r
1002 + " 1000: <%simplified< thousandth; <%simplified< thousand >>;\n"
\r
1003 + " 1,000,000: <%simplified< millionth; <%simplified< million >>;\n"
\r
1004 + " 1,000,000,000,000: <%simplified< billionth;\n"
\r
1005 + " <%simplified< billion >>;\n"
\r
1006 + " 1,000,000,000,000,000: =#,##0=;"
\r
1008 + " -x: minus >>;\n"
\r
1009 + " x.x: << point >>;\n"
\r
1010 + " =%simplified=;\n"
\r
1011 + " 100: << hundred[ >%%and>];\n"
\r
1012 + " 1000: << thousand[ >%%and>];\n"
\r
1013 + " 100,000>>: << thousand[>%%commas>];\n"
\r
1014 + " 1,000,000: << million[>%%commas>];\n"
\r
1015 + " 1,000,000,000,000: << billion[>%%commas>];\n"
\r
1016 + " 1,000,000,000,000,000: =#,##0=;\n"
\r
1018 + " and =%default=;\n"
\r
1019 + " 100: =%default=;\n"
\r
1021 + " ' and =%default=;\n"
\r
1022 + " 100: , =%default=;\n"
\r
1023 + " 1000: , <%default< thousand, >%default>;\n"
\r
1024 + " 1,000,000: , =%default=;"
\r
1025 + "%%lenient-parse:\n"
\r
1026 + " & ' ' , ',' ;\n";
\r
1028 /* Tests the method
\r
1029 * public boolean equals(Object that)
\r
1031 public void TestEquals(){
\r
1032 // Tests when "if (!(that instanceof RuleBasedNumberFormat))" is true
\r
1033 RuleBasedNumberFormat rbnf = new RuleBasedNumberFormat("dummy");
\r
1034 if( rbnf.equals(new String("dummy")) != false ||
\r
1035 rbnf.equals(new Character('a')) != false ||
\r
1036 rbnf.equals(new Object()) != false ||
\r
1037 rbnf.equals(-1) != false ||
\r
1038 rbnf.equals(0) != false ||
\r
1039 rbnf.equals(1) != false ||
\r
1040 rbnf.equals(-1.0) != false ||
\r
1041 rbnf.equals(0.0) != false ||
\r
1042 rbnf.equals(1.0) != false){
\r
1043 errln("RuleBasedNumberFormat.equals(Object that) was suppose to " +
\r
1044 "be false for an invalid object.");
\r
1048 // "if (!locale.equals(that2.locale) || lenientParse != that2.lenientParse)"
\r
1050 RuleBasedNumberFormat rbnf1 = new RuleBasedNumberFormat("dummy", new Locale("en"));
\r
1051 RuleBasedNumberFormat rbnf2 = new RuleBasedNumberFormat("dummy", new Locale("jp"));
\r
1052 RuleBasedNumberFormat rbnf3 = new RuleBasedNumberFormat("dummy", new Locale("sp"));
\r
1053 RuleBasedNumberFormat rbnf4 = new RuleBasedNumberFormat("dummy", new Locale("fr"));
\r
1055 if(rbnf1.equals(rbnf2) != false || rbnf1.equals(rbnf3) != false ||
\r
1056 rbnf1.equals(rbnf4) != false || rbnf2.equals(rbnf3) != false ||
\r
1057 rbnf2.equals(rbnf4) != false || rbnf3.equals(rbnf4) != false){
\r
1058 errln("RuleBasedNumberFormat.equals(Object that) was suppose to " +
\r
1059 "be false for an invalid object.");
\r
1062 if(rbnf1.equals(rbnf1) == false){
\r
1063 errln("RuleBasedNumberFormat.equals(Object that) was not suppose to " +
\r
1064 "be false for an invalid object.");
\r
1067 if(rbnf2.equals(rbnf2) == false){
\r
1068 errln("RuleBasedNumberFormat.equals(Object that) was not suppose to " +
\r
1069 "be false for an invalid object.");
\r
1072 if(rbnf3.equals(rbnf3) == false){
\r
1073 errln("RuleBasedNumberFormat.equals(Object that) was not suppose to " +
\r
1074 "be false for an invalid object.");
\r
1077 if(rbnf4.equals(rbnf4) == false){
\r
1078 errln("RuleBasedNumberFormat.equals(Object that) was not suppose to " +
\r
1079 "be false for an invalid object.");
\r
1082 RuleBasedNumberFormat rbnf5 = new RuleBasedNumberFormat("dummy", new Locale("en"));
\r
1083 RuleBasedNumberFormat rbnf6 = new RuleBasedNumberFormat("dummy", new Locale("en"));
\r
1085 if(rbnf5.equals(rbnf6) == false){
\r
1086 errln("RuleBasedNumberFormat.equals(Object that) was not suppose to " +
\r
1087 "be false for an invalid object.");
\r
1089 rbnf6.setLenientParseMode(true);
\r
1091 if(rbnf5.equals(rbnf6) != false){
\r
1092 errln("RuleBasedNumberFormat.equals(Object that) was suppose to " +
\r
1093 "be false for an invalid object.");
\r
1096 // Tests when "if (!ruleSets[i].equals(that2.ruleSets[i]))" is true
\r
1097 RuleBasedNumberFormat rbnf7 = new RuleBasedNumberFormat("not_dummy", new Locale("en"));
\r
1098 if(rbnf5.equals(rbnf7) != false){
\r
1099 errln("RuleBasedNumberFormat.equals(Object that) was suppose to " +
\r
1100 "be false for an invalid object.");
\r
1104 /* Tests the method
\r
1105 * public ULocale[] getRuleSetDisplayNameLocales()
\r
1107 public void TestGetRuleDisplayNameLocales(){
\r
1108 // Tests when "if (ruleSetDisplayNames != null" is false
\r
1109 RuleBasedNumberFormat rbnf = new RuleBasedNumberFormat("dummy");
\r
1110 rbnf.getRuleSetDisplayNameLocales();
\r
1111 if(rbnf.getRuleSetDisplayNameLocales() != null){
\r
1112 errln("RuleBasedNumberFormat.getRuleDisplayNameLocales() was suppose to " +
\r
1117 /* Tests the method
\r
1118 * private String[] getNameListForLocale(ULocale loc)
\r
1119 * public String[] getRuleSetDisplayNames(ULocale loc)
\r
1121 public void TestGetNameListForLocale(){
\r
1122 // Tests when "if (names != null)" is false and
\r
1123 // "if (loc != null && ruleSetDisplayNames != null)" is false
\r
1124 RuleBasedNumberFormat rbnf = new RuleBasedNumberFormat("dummy");
\r
1125 rbnf.getRuleSetDisplayNames(null);
\r
1127 rbnf.getRuleSetDisplayNames(null);
\r
1128 } catch(Exception e){
\r
1129 errln("RuleBasedNumberFormat.getRuleSetDisplayNames(ULocale loc) " +
\r
1130 "was not suppose to have an exception.");
\r
1134 /* Tests the method
\r
1135 * public String getRuleSetDisplayName(String ruleSetName, ULocale loc)
\r
1137 public void TestGetRulesSetDisplayName(){
\r
1138 RuleBasedNumberFormat rbnf = new RuleBasedNumberFormat("dummy");
\r
1139 //rbnf.getRuleSetDisplayName("dummy", new ULocale("en_US"));
\r
1141 // Tests when "if (names != null) " is true
\r
1143 // Tests when the method throws an exception
\r
1145 rbnf.getRuleSetDisplayName("", new ULocale("en_US"));
\r
1146 errln("RuleBasedNumberFormat.getRuleSetDisplayName(String ruleSetName, ULocale loc) " +
\r
1147 "was suppose to have an exception.");
\r
1148 } catch(Exception e){}
\r
1151 rbnf.getRuleSetDisplayName("dummy", new ULocale("en_US"));
\r
1152 errln("RuleBasedNumberFormat.getRuleSetDisplayName(String ruleSetName, ULocale loc) " +
\r
1153 "was suppose to have an exception.");
\r
1154 } catch(Exception e){}
\r
1157 /* Test the method
\r
1158 * public void process(StringBuffer buf, NFRuleSet ruleSet)
\r
1160 public void TestChineseProcess(){
\r
1161 String ruleWithChinese =
\r
1163 + " -x: minus >>;\n"
\r
1164 + " x.x: << point >>;\n"
\r
1165 + " zero; one; two; three; four; five; six; seven; eight; nine;\n"
\r
1166 + " ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n"
\r
1167 + " seventeen; eighteen; nineteen;\n"
\r
1168 + " 20: twenty[->>];\n"
\r
1169 + " 30: thirty[->>];\n"
\r
1170 + " 40: forty[->>];\n"
\r
1171 + " 50: fifty[->>];\n"
\r
1172 + " 60: sixty[->>];\n"
\r
1173 + " 70: seventy[->>];\n"
\r
1174 + " 80: eighty[->>];\n"
\r
1175 + " 90: ninety[->>];\n"
\r
1176 + " 100: << hundred[ >>];\n"
\r
1177 + " 1000: << thousand[ >>];\n"
\r
1178 + " 1,000,000: << million[ >>];\n"
\r
1179 + " 1,000,000,000,000: << billion[ >>];\n"
\r
1180 + " 1,000,000,000,000,000: =#,##0=;\n"
\r
1182 + " =%simplified=;\n"
\r
1183 + " 1000>: <%%alt-hundreds<[ >>];\n"
\r
1184 + " 10,000: =%simplified=;\n"
\r
1185 + " 1,000,000: << million[ >%simplified>];\n"
\r
1186 + " 1,000,000,000,000: << billion[ >%simplified>];\n"
\r
1187 + " 1,000,000,000,000,000: =#,##0=;\n"
\r
1188 + "%%alt-hundreds:\n"
\r
1189 + " 0: SHOULD NEVER GET HERE!;\n"
\r
1190 + " 10: <%simplified< thousand;\n"
\r
1191 + " 11: =%simplified= hundred>%%empty>;\n"
\r
1194 + "%accounting:\n"
\r
1195 + " \u842c; \u842c; \u842c; \u842c; \u842c; \u842c; \u842c; \u842c;\n"
\r
1196 + " \u842c; \u842c;\n"
\r
1197 + " \u842c; \u842c; \u842c; \u842c; \u842c;\n"
\r
1198 + " \u842c; \u842c; \u842c; \u842c;\n"
\r
1200 + " twentieth; \u96f6|>>;\n"
\r
1201 + " 30: \u96f6; \u96f6|>>;\n"
\r
1202 + " 40: \u96f6; \u96f6|>>;\n"
\r
1203 + " 50: \u96f6; \u96f6|>>;\n"
\r
1204 + " 60: \u96f6; \u96f6|>>;\n"
\r
1205 + " 70: \u96f6; \u96f6|>>;\n"
\r
1206 + " 80: \u96f6; \u96f6|>>;\n"
\r
1207 + " 90: \u96f6; \u96f6|>>;\n"
\r
1208 + " 100: <%simplified< \u96f6; <%simplified< \u96f6 >>;\n"
\r
1209 + " 1000: <%simplified< \u96f6; <%simplified< \u96f6 >>;\n"
\r
1210 + " 1,000,000: <%simplified< \u96f6; <%simplified< \u96f6 >>;\n"
\r
1211 + " 1,000,000,000,000: <%simplified< \u96f6;\n"
\r
1212 + " <%simplified< \u96f6 >>;\n"
\r
1213 + " 1,000,000,000,000,000: =#,##0=;"
\r
1215 + " -x: minus >>;\n"
\r
1216 + " x.x: << point >>;\n"
\r
1217 + " =%simplified=;\n"
\r
1218 + " 100: << hundred[ >%%and>];\n"
\r
1219 + " 1000: << thousand[ >%%and>];\n"
\r
1220 + " 100,000>>: << thousand[>%%commas>];\n"
\r
1221 + " 1,000,000: << million[>%%commas>];\n"
\r
1222 + " 1,000,000,000,000: << billion[>%%commas>];\n"
\r
1223 + " 1,000,000,000,000,000: =#,##0=;\n"
\r
1225 + " and =%default=;\n"
\r
1226 + " 100: =%default=;\n"
\r
1228 + " ' and =%default=;\n"
\r
1229 + " 100: , =%default=;\n"
\r
1230 + " 1000: , <%default< thousand, >%default>;\n"
\r
1231 + " 1,000,000: , =%default=;"
\r
1232 + "%traditional:\n"
\r
1233 + " -x: \u3007| >>;\n"
\r
1234 + " x.x: << \u9ede >>;\n"
\r
1235 + " \u842c; \u842c; \u842c; \u842c; \u842c; \u842c; \u842c; \u842c; \u842c; \u842c;\n"
\r
1236 + " \u842c; \u842c; \u842c; \u842c; \u842c; \u842c; \u842c;\n"
\r
1237 + " \u842c; \u842c; \u842c;\n"
\r
1238 + " 20: \u842c[->>];\n"
\r
1239 + " 30: \u842c[->>];\n"
\r
1240 + " 40: \u842c[->>];\n"
\r
1241 + " 50: \u842c[->>];\n"
\r
1242 + " 60: \u842c[->>];\n"
\r
1243 + " 70: \u842c[->>];\n"
\r
1244 + " 80: \u842c[->>];\n"
\r
1245 + " 90: \u842c[->>];\n"
\r
1246 + " 100: << \u842c[ >>];\n"
\r
1247 + " 1000: << \u842c[ >>];\n"
\r
1248 + " 1,000,000: << \u842c[ >>];\n"
\r
1249 + " 1,000,000,000,000: << \u842c[ >>];\n"
\r
1250 + " 1,000,000,000,000,000: =#,##0=;\n"
\r
1253 + " 60: =%%min-sec=;\n"
\r
1254 + " 3600: =%%hr-min-sec=;\n"
\r
1257 + " 60/60: <0<>>;\n"
\r
1258 + "%%hr-min-sec:\n"
\r
1260 + " 60/60: <00<>>;\n"
\r
1261 + " 3600/60: <#,##0<:>>>;\n"
\r
1262 + "%%post-process:com.ibm.icu.text.RBNFChinesePostProcessor\n";
\r
1264 RuleBasedNumberFormat rbnf = new RuleBasedNumberFormat(ruleWithChinese, ULocale.CHINESE);
\r
1265 String[] ruleNames = rbnf.getRuleSetNames();
\r
1267 // Test with "null" rules
\r
1268 rbnf.format(0.0,null);
\r
1269 errln("This was suppose to return an exception for a null format");
\r
1270 } catch(Exception e){}
\r
1271 for(int i=0; i<ruleNames.length; i++){
\r
1273 rbnf.format(-123450.6789,ruleNames[i]);
\r
1274 } catch(Exception e){
\r
1275 errln("RBNFChinesePostProcessor was not suppose to return an exception " +
\r
1276 "when being formatted with parameters 0.0 and " + ruleNames[i]);
\r