• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4  *******************************************************************************
5  * Copyright (C) 1996-2016, International Business Machines Corporation and
6  * others. All Rights Reserved.
7  *******************************************************************************
8  */
9 
10 #include "unicode/utypes.h"
11 
12 #if !UCONFIG_NO_FORMATTING
13 
14 #include "itrbnf.h"
15 
16 #include "unicode/umachine.h"
17 
18 #include "unicode/tblcoll.h"
19 #include "unicode/coleitr.h"
20 #include "unicode/ures.h"
21 #include "unicode/ustring.h"
22 #include "unicode/decimfmt.h"
23 #include "unicode/udata.h"
24 #include "cmemory.h"
25 #include "putilimp.h"
26 #include "testutil.h"
27 
28 #include <string.h>
29 
30 // import com.ibm.text.RuleBasedNumberFormat;
31 // import com.ibm.test.TestFmwk;
32 
33 // import java.util.Locale;
34 // import java.text.NumberFormat;
35 
36 // current macro not in icu1.8.1
37 #define TESTCASE(id,test)             \
38     case id:                          \
39         name = #test;                 \
40         if (exec) {                   \
41             logln(#test "---");       \
42             logln();                  \
43             test();                   \
44         }                             \
45         break
46 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)47 void IntlTestRBNF::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par*/)
48 {
49     if (exec) logln("TestSuite RuleBasedNumberFormat");
50     switch (index) {
51 #if U_HAVE_RBNF
52         TESTCASE(0, TestEnglishSpellout);
53         TESTCASE(1, TestOrdinalAbbreviations);
54         TESTCASE(2, TestDurations);
55         TESTCASE(3, TestSpanishSpellout);
56         TESTCASE(4, TestFrenchSpellout);
57         TESTCASE(5, TestSwissFrenchSpellout);
58         TESTCASE(6, TestItalianSpellout);
59         TESTCASE(7, TestGermanSpellout);
60         TESTCASE(8, TestThaiSpellout);
61         TESTCASE(9, TestAPI);
62         TESTCASE(10, TestFractionalRuleSet);
63         TESTCASE(11, TestSwedishSpellout);
64         TESTCASE(12, TestBelgianFrenchSpellout);
65         TESTCASE(13, TestSmallValues);
66         TESTCASE(14, TestLocalizations);
67         TESTCASE(15, TestAllLocales);
68         TESTCASE(16, TestHebrewFraction);
69         TESTCASE(17, TestPortugueseSpellout);
70         TESTCASE(18, TestMultiplierSubstitution);
71         TESTCASE(19, TestSetDecimalFormatSymbols);
72         TESTCASE(20, TestPluralRules);
73         TESTCASE(21, TestMultiplePluralRules);
74         TESTCASE(22, TestInfinityNaN);
75         TESTCASE(23, TestVariableDecimalPoint);
76         TESTCASE(24, TestLargeNumbers);
77         TESTCASE(25, TestCompactDecimalFormatStyle);
78         TESTCASE(26, TestParseFailure);
79         TESTCASE(27, TestMinMaxIntegerDigitsIgnored);
80 #else
81         TESTCASE(0, TestRBNFDisabled);
82 #endif
83     default:
84         name = "";
85         break;
86     }
87 }
88 
89 #if U_HAVE_RBNF
90 
TestHebrewFraction()91 void IntlTestRBNF::TestHebrewFraction() {
92 
93     // this is the expected output for 123.45, with no '<' in it.
94     UChar text1[] = {
95         0x05de, 0x05d0, 0x05d4, 0x0020,
96         0x05e2, 0x05e9, 0x05e8, 0x05d9, 0x05dd, 0x0020,
97         0x05d5, 0x05e9, 0x05dc, 0x05d5, 0x05e9, 0x0020,
98         0x05e0, 0x05e7, 0x05d5, 0x05d3, 0x05d4, 0x0020,
99         0x05d0, 0x05e8, 0x05d1, 0x05e2, 0x0020,
100         0x05d7, 0x05de, 0x05e9, 0x0000,
101     };
102     UChar text2[] = {
103         0x05DE, 0x05D0, 0x05D4, 0x0020,
104         0x05E2, 0x05E9, 0x05E8, 0x05D9, 0x05DD, 0x0020,
105         0x05D5, 0x05E9, 0x05DC, 0x05D5, 0x05E9, 0x0020,
106         0x05E0, 0x05E7, 0x05D5, 0x05D3, 0x05D4, 0x0020,
107         0x05D0, 0x05E4, 0x05E1, 0x0020,
108         0x05D0, 0x05E4, 0x05E1, 0x0020,
109         0x05D0, 0x05E8, 0x05D1, 0x05E2, 0x0020,
110         0x05D7, 0x05DE, 0x05E9, 0x0000,
111     };
112     UErrorCode status = U_ZERO_ERROR;
113     RuleBasedNumberFormat* formatter = new RuleBasedNumberFormat(URBNF_SPELLOUT, "he_IL", status);
114     if (status == U_MISSING_RESOURCE_ERROR || status == U_FILE_ACCESS_ERROR) {
115         errcheckln(status, "Failed in constructing RuleBasedNumberFormat - %s", u_errorName(status));
116         delete formatter;
117         return;
118     }
119     UnicodeString result;
120     Formattable parseResult;
121     ParsePosition pp(0);
122     {
123         UnicodeString expected(text1);
124         formatter->format(123.45, result);
125         if (result != expected) {
126             errln((UnicodeString)"expected '" + TestUtility::hex(expected) + "'\nbut got: '" + TestUtility::hex(result) + "'");
127         } else {
128 //            formatter->parse(result, parseResult, pp);
129 //            if (parseResult.getDouble() != 123.45) {
130 //                errln("expected 123.45 but got: %g", parseResult.getDouble());
131 //            }
132         }
133     }
134     {
135         UnicodeString expected(text2);
136         result.remove();
137         formatter->format(123.0045, result);
138         if (result != expected) {
139             errln((UnicodeString)"expected '" + TestUtility::hex(expected) + "'\nbut got: '" + TestUtility::hex(result) + "'");
140         } else {
141             pp.setIndex(0);
142 //            formatter->parse(result, parseResult, pp);
143 //            if (parseResult.getDouble() != 123.0045) {
144 //                errln("expected 123.0045 but got: %g", parseResult.getDouble());
145 //            }
146         }
147     }
148     delete formatter;
149 }
150 
151 void
TestAPI()152 IntlTestRBNF::TestAPI() {
153   // This test goes through the APIs that were not tested before.
154   // These tests are too small to have separate test classes/functions
155 
156   UErrorCode status = U_ZERO_ERROR;
157   RuleBasedNumberFormat* formatter
158       = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getUS(), status);
159   if (status == U_MISSING_RESOURCE_ERROR || status == U_FILE_ACCESS_ERROR) {
160     dataerrln("Unable to create formatter. - %s", u_errorName(status));
161     delete formatter;
162     return;
163   }
164 
165   logln("RBNF API test starting");
166   // test clone
167   {
168     logln("Testing Clone");
169     RuleBasedNumberFormat* rbnfClone = (RuleBasedNumberFormat *)formatter->clone();
170     if(rbnfClone != NULL) {
171       if(!(*rbnfClone == *formatter)) {
172         errln("Clone should be semantically equivalent to the original!");
173       }
174       delete rbnfClone;
175     } else {
176       errln("Cloning failed!");
177     }
178   }
179 
180   // test assignment
181   {
182     logln("Testing assignment operator");
183     RuleBasedNumberFormat assignResult(URBNF_SPELLOUT, Locale("es", "ES", ""), status);
184     assignResult = *formatter;
185     if(!(assignResult == *formatter)) {
186       errln("Assignment result should be semantically equivalent to the original!");
187     }
188   }
189 
190   // test rule constructor
191   {
192     logln("Testing rule constructor");
193     LocalUResourceBundlePointer en(ures_open(U_ICUDATA_NAME U_TREE_SEPARATOR_STRING "rbnf", "en", &status));
194     if(U_FAILURE(status)) {
195       errln("Unable to access resource bundle with data!");
196     } else {
197       int32_t ruleLen = 0;
198       int32_t len = 0;
199       LocalUResourceBundlePointer rbnfRules(ures_getByKey(en.getAlias(), "RBNFRules", NULL, &status));
200       LocalUResourceBundlePointer ruleSets(ures_getByKey(rbnfRules.getAlias(), "SpelloutRules", NULL, &status));
201       UnicodeString desc;
202       while (ures_hasNext(ruleSets.getAlias())) {
203            const UChar* currentString = ures_getNextString(ruleSets.getAlias(), &len, NULL, &status);
204            ruleLen += len;
205            desc.append(currentString);
206       }
207 
208       const UChar *spelloutRules = desc.getTerminatedBuffer();
209 
210       if(U_FAILURE(status) || ruleLen == 0 || spelloutRules == NULL) {
211         errln("Unable to access the rules string!");
212       } else {
213         UParseError perror;
214         RuleBasedNumberFormat ruleCtorResult(spelloutRules, Locale::getUS(), perror, status);
215         if(!(ruleCtorResult == *formatter)) {
216           errln("Formatter constructed from the original rules should be semantically equivalent to the original!");
217         }
218 
219         // Jitterbug 4452, for coverage
220         RuleBasedNumberFormat nf(spelloutRules, (UnicodeString)"", Locale::getUS(), perror, status);
221         if(!(nf == *formatter)) {
222           errln("Formatter constructed from the original rules should be semantically equivalent to the original!");
223         }
224       }
225     }
226   }
227 
228   // test getRules
229   {
230     logln("Testing getRules function");
231     UnicodeString rules = formatter->getRules();
232     UParseError perror;
233     RuleBasedNumberFormat fromRulesResult(rules, Locale::getUS(), perror, status);
234 
235     if(!(fromRulesResult == *formatter)) {
236       errln("Formatter constructed from rules obtained by getRules should be semantically equivalent to the original!");
237     }
238   }
239 
240 
241   {
242     logln("Testing copy constructor");
243     RuleBasedNumberFormat copyCtorResult(*formatter);
244     if(!(copyCtorResult == *formatter)) {
245       errln("Copy constructor result result should be semantically equivalent to the original!");
246     }
247   }
248 
249 #if !UCONFIG_NO_COLLATION
250   // test ruleset names
251   {
252     logln("Testing getNumberOfRuleSetNames, getRuleSetName and format using rule set names");
253     int32_t noOfRuleSetNames = formatter->getNumberOfRuleSetNames();
254     if(noOfRuleSetNames == 0) {
255       errln("Number of rule set names should be more than zero");
256     }
257     UnicodeString ruleSetName;
258     int32_t i = 0;
259     int32_t intFormatNum = 34567;
260     double doubleFormatNum = 893411.234;
261     logln("number of rule set names is %i", noOfRuleSetNames);
262     for(i = 0; i < noOfRuleSetNames; i++) {
263       FieldPosition pos1, pos2;
264       UnicodeString intFormatResult, doubleFormatResult;
265       Formattable intParseResult, doubleParseResult;
266 
267       ruleSetName = formatter->getRuleSetName(i);
268       log("Rule set name %i is ", i);
269       log(ruleSetName);
270       logln(". Format results are: ");
271       intFormatResult = formatter->format(intFormatNum, ruleSetName, intFormatResult, pos1, status);
272       doubleFormatResult = formatter->format(doubleFormatNum, ruleSetName, doubleFormatResult, pos2, status);
273       if(U_FAILURE(status)) {
274         errln("Format using a rule set failed");
275         break;
276       }
277       logln(intFormatResult);
278       logln(doubleFormatResult);
279       formatter->setLenient(TRUE);
280       formatter->parse(intFormatResult, intParseResult, status);
281       formatter->parse(doubleFormatResult, doubleParseResult, status);
282 
283       logln("Parse results for lenient = TRUE, %i, %f", intParseResult.getLong(), doubleParseResult.getDouble());
284 
285       formatter->setLenient(FALSE);
286       formatter->parse(intFormatResult, intParseResult, status);
287       formatter->parse(doubleFormatResult, doubleParseResult, status);
288 
289       logln("Parse results for lenient = FALSE, %i, %f", intParseResult.getLong(), doubleParseResult.getDouble());
290 
291       if(U_FAILURE(status)) {
292         errln("Error during parsing");
293       }
294 
295       intFormatResult = formatter->format(intFormatNum, "BLABLA", intFormatResult, pos1, status);
296       if(U_SUCCESS(status)) {
297         errln("Using invalid rule set name should have failed");
298         break;
299       }
300       status = U_ZERO_ERROR;
301       doubleFormatResult = formatter->format(doubleFormatNum, "TRUC", doubleFormatResult, pos2, status);
302       if(U_SUCCESS(status)) {
303         errln("Using invalid rule set name should have failed");
304         break;
305       }
306       status = U_ZERO_ERROR;
307     }
308     status = U_ZERO_ERROR;
309   }
310 #endif
311 
312   // test API
313   UnicodeString expected("four point five","");
314   logln("Testing format(double)");
315   UnicodeString result;
316   formatter->format(4.5,result);
317   if(result != expected) {
318       errln("Formatted 4.5, expected " + expected + " got " + result);
319   } else {
320       logln("Formatted 4.5, expected " + expected + " got " + result);
321   }
322   result.remove();
323   expected = "four";
324   formatter->format((int32_t)4,result);
325   if(result != expected) {
326       errln("Formatted 4, expected " + expected + " got " + result);
327   } else {
328       logln("Formatted 4, expected " + expected + " got " + result);
329   }
330 
331   result.remove();
332   FieldPosition pos;
333   formatter->format((int64_t)4, result, pos, status = U_ZERO_ERROR);
334   if(result != expected) {
335       errln("Formatted 4 int64_t, expected " + expected + " got " + result);
336   } else {
337       logln("Formatted 4 int64_t, expected " + expected + " got " + result);
338   }
339 
340   //Jitterbug 4452, for coverage
341   result.remove();
342   FieldPosition pos2;
343   formatter->format((int64_t)4, formatter->getRuleSetName(0), result, pos2, status = U_ZERO_ERROR);
344   if(result != expected) {
345       errln("Formatted 4 int64_t, expected " + expected + " got " + result);
346   } else {
347       logln("Formatted 4 int64_t, expected " + expected + " got " + result);
348   }
349 
350   // clean up
351   logln("Cleaning up");
352   delete formatter;
353 }
354 
355 /**
356  * Perform a simple spot check on the parsing going into an infinite loop for alternate rules.
357  */
TestMultiplePluralRules()358 void IntlTestRBNF::TestMultiplePluralRules() {
359     // This is trying to model the feminine form, but don't worry about the details too much.
360     // We're trying to test the plural rules where there are different prefixes.
361     UnicodeString rules("%spellout-cardinal-feminine-genitive:"
362                 "0: zero;"
363                 "1: ono;"
364                 "2: two;"
365                 "1000: << $(cardinal,one{thousand}few{thousanF}other{thousanO})$[ >>];"
366                 "%spellout-cardinal-feminine:"
367                 "x.x: [<< $(cardinal,one{singleton}other{plurality})$ ]>%%fractions>;"
368                 "0: zero;"
369                 "1: one;"
370                 "2: two;"
371                 "1000: << $(cardinal,one{thousand}few{thousanF}other{thousanO})$[ >>];"
372                 "%%fractions:"
373                 "10: <%spellout-cardinal-feminine< $(cardinal,one{oneth}other{tenth})$;"
374                 "100: <%spellout-cardinal-feminine< $(cardinal,one{1hundredth}other{hundredth})$;");
375     UErrorCode status = U_ZERO_ERROR;
376     UParseError pError;
377     RuleBasedNumberFormat formatter(rules, Locale("ru"), pError, status);
378     Formattable result;
379     UnicodeString resultStr;
380     FieldPosition pos;
381 
382     if (U_FAILURE(status)) {
383         dataerrln("Unable to create formatter - %s", u_errorName(status));
384         return;
385     }
386 
387     formatter.parse(formatter.format(1000.0, resultStr, pos, status), result, status);
388     if (1000 != result.getLong() || resultStr != UNICODE_STRING_SIMPLE("one thousand")) {
389         errln("RuleBasedNumberFormat did not return the correct value. Got: %d", result.getLong());
390         errln(resultStr);
391     }
392     resultStr.remove();
393     formatter.parse(formatter.format(1000.0, UnicodeString("%spellout-cardinal-feminine-genitive"), resultStr, pos, status), result, status);
394     if (1000 != result.getLong() || resultStr != UNICODE_STRING_SIMPLE("ono thousand")) {
395         errln("RuleBasedNumberFormat(cardinal-feminine-genitive) did not return the correct value. Got: %d", result.getLong());
396         errln(resultStr);
397     }
398     resultStr.remove();
399     formatter.parse(formatter.format(1000.0, UnicodeString("%spellout-cardinal-feminine"), resultStr, pos, status), result, status);
400     if (1000 != result.getLong() || resultStr != UNICODE_STRING_SIMPLE("one thousand")) {
401         errln("RuleBasedNumberFormat(spellout-cardinal-feminine) did not return the correct value. Got: %d", result.getLong());
402         errln(resultStr);
403     }
404     static const char* const testData[][2] = {
405         { "0", "zero" },
406         { "1", "one" },
407         { "2", "two" },
408         { "0.1", "one oneth" },
409         { "0.2", "two tenth" },
410         { "1.1", "one singleton one oneth" },
411         { "1.2", "one singleton two tenth" },
412         { "2.1", "two plurality one oneth" },
413         { "2.2", "two plurality two tenth" },
414         { "0.01", "one 1hundredth" },
415         { "0.02", "two hundredth" },
416         { NULL, NULL }
417     };
418     doTest(&formatter, testData, TRUE);
419 }
420 
TestFractionalRuleSet()421 void IntlTestRBNF::TestFractionalRuleSet()
422 {
423     UnicodeString fracRules(
424         "%main:\n"
425                // this rule formats the number if it's 1 or more.  It formats
426                // the integral part using a DecimalFormat ("#,##0" puts
427                // thousands separators in the right places) and the fractional
428                // part using %%frac.  If there is no fractional part, it
429                // just shows the integral part.
430         "    x.0: <#,##0<[ >%%frac>];\n"
431                // this rule formats the number if it's between 0 and 1.  It
432                // shows only the fractional part (0.5 shows up as "1/2," not
433                // "0 1/2")
434         "    0.x: >%%frac>;\n"
435         // the fraction rule set.  This works the same way as the one in the
436         // preceding example: We multiply the fractional part of the number
437         // being formatted by each rule's base value and use the rule that
438         // produces the result closest to 0 (or the first rule that produces 0).
439         // Since we only provide rules for the numbers from 2 to 10, we know
440         // we'll get a fraction with a denominator between 2 and 10.
441         // "<0<" causes the numerator of the fraction to be formatted
442         // using numerals
443         "%%frac:\n"
444         "    2: 1/2;\n"
445         "    3: <0</3;\n"
446         "    4: <0</4;\n"
447         "    5: <0</5;\n"
448         "    6: <0</6;\n"
449         "    7: <0</7;\n"
450         "    8: <0</8;\n"
451         "    9: <0</9;\n"
452         "   10: <0</10;\n");
453 
454     // mondo hack
455     int len = fracRules.length();
456     int change = 2;
457     for (int i = 0; i < len; ++i) {
458         UChar ch = fracRules.charAt(i);
459         if (ch == '\n') {
460             change = 2; // change ok
461         } else if (ch == ':') {
462             change = 1; // change, but once we hit a non-space char, don't change
463         } else if (ch == ' ') {
464             if (change != 0) {
465                 fracRules.setCharAt(i, (UChar)0x200e);
466             }
467         } else {
468             if (change == 1) {
469                 change = 0;
470             }
471         }
472     }
473 
474     UErrorCode status = U_ZERO_ERROR;
475     UParseError perror;
476     RuleBasedNumberFormat formatter(fracRules, Locale::getEnglish(), perror, status);
477     if (U_FAILURE(status)) {
478         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
479     } else {
480         static const char* const testData[][2] = {
481             { "0", "0" },
482             { ".1", "1/10" },
483             { ".11", "1/9" },
484             { ".125", "1/8" },
485             { ".1428", "1/7" },
486             { ".1667", "1/6" },
487             { ".2", "1/5" },
488             { ".25", "1/4" },
489             { ".333", "1/3" },
490             { ".5", "1/2" },
491             { "1.1", "1 1/10" },
492             { "2.11", "2 1/9" },
493             { "3.125", "3 1/8" },
494             { "4.1428", "4 1/7" },
495             { "5.1667", "5 1/6" },
496             { "6.2", "6 1/5" },
497             { "7.25", "7 1/4" },
498             { "8.333", "8 1/3" },
499             { "9.5", "9 1/2" },
500             { ".2222", "2/9" },
501             { ".4444", "4/9" },
502             { ".5555", "5/9" },
503             { "1.2856", "1 2/7" },
504             { NULL, NULL }
505         };
506         doTest(&formatter, testData, FALSE); // exact values aren't parsable from fractions
507     }
508 }
509 
510 #if 0
511 #define LLAssert(a) \
512   if (!(a)) errln("FAIL: " #a)
513 
514 void IntlTestRBNF::TestLLongConstructors()
515 {
516     logln("Testing constructors");
517 
518     // constant (shouldn't really be public)
519     LLAssert(llong(llong::kD32).asDouble() == llong::kD32);
520 
521     // internal constructor (shouldn't really be public)
522     LLAssert(llong(0, 1).asDouble() == 1);
523     LLAssert(llong(1, 0).asDouble() == llong::kD32);
524     LLAssert(llong((uint32_t)-1, (uint32_t)-1).asDouble() == -1);
525 
526     // public empty constructor
527     LLAssert(llong().asDouble() == 0);
528 
529     // public int32_t constructor
530     LLAssert(llong((int32_t)0).asInt() == (int32_t)0);
531     LLAssert(llong((int32_t)1).asInt() == (int32_t)1);
532     LLAssert(llong((int32_t)-1).asInt() == (int32_t)-1);
533     LLAssert(llong((int32_t)0x7fffffff).asInt() == (int32_t)0x7fffffff);
534     LLAssert(llong((int32_t)0xffffffff).asInt() == (int32_t)-1);
535     LLAssert(llong((int32_t)0x80000000).asInt() == (int32_t)0x80000000);
536 
537     // public int16_t constructor
538     LLAssert(llong((int16_t)0).asInt() == (int16_t)0);
539     LLAssert(llong((int16_t)1).asInt() == (int16_t)1);
540     LLAssert(llong((int16_t)-1).asInt() == (int16_t)-1);
541     LLAssert(llong((int16_t)0x7fff).asInt() == (int16_t)0x7fff);
542     LLAssert(llong((int16_t)0xffff).asInt() == (int16_t)0xffff);
543     LLAssert(llong((int16_t)0x8000).asInt() == (int16_t)0x8000);
544 
545     // public int8_t constructor
546     LLAssert(llong((int8_t)0).asInt() == (int8_t)0);
547     LLAssert(llong((int8_t)1).asInt() == (int8_t)1);
548     LLAssert(llong((int8_t)-1).asInt() == (int8_t)-1);
549     LLAssert(llong((int8_t)0x7f).asInt() == (int8_t)0x7f);
550     LLAssert(llong((int8_t)0xff).asInt() == (int8_t)0xff);
551     LLAssert(llong((int8_t)0x80).asInt() == (int8_t)0x80);
552 
553     // public uint16_t constructor
554     LLAssert(llong((uint16_t)0).asUInt() == (uint16_t)0);
555     LLAssert(llong((uint16_t)1).asUInt() == (uint16_t)1);
556     LLAssert(llong((uint16_t)-1).asUInt() == (uint16_t)-1);
557     LLAssert(llong((uint16_t)0x7fff).asUInt() == (uint16_t)0x7fff);
558     LLAssert(llong((uint16_t)0xffff).asUInt() == (uint16_t)0xffff);
559     LLAssert(llong((uint16_t)0x8000).asUInt() == (uint16_t)0x8000);
560 
561     // public uint32_t constructor
562     LLAssert(llong((uint32_t)0).asUInt() == (uint32_t)0);
563     LLAssert(llong((uint32_t)1).asUInt() == (uint32_t)1);
564     LLAssert(llong((uint32_t)-1).asUInt() == (uint32_t)-1);
565     LLAssert(llong((uint32_t)0x7fffffff).asUInt() == (uint32_t)0x7fffffff);
566     LLAssert(llong((uint32_t)0xffffffff).asUInt() == (uint32_t)-1);
567     LLAssert(llong((uint32_t)0x80000000).asUInt() == (uint32_t)0x80000000);
568 
569     // public double constructor
570     LLAssert(llong((double)0).asDouble() == (double)0);
571     LLAssert(llong((double)1).asDouble() == (double)1);
572     LLAssert(llong((double)0x7fffffff).asDouble() == (double)0x7fffffff);
573     LLAssert(llong((double)0x80000000).asDouble() == (double)0x80000000);
574     LLAssert(llong((double)0x80000001).asDouble() == (double)0x80000001);
575 
576     // can't access uprv_maxmantissa, so fake it
577     double maxmantissa = (llong((int32_t)1) << 40).asDouble();
578     LLAssert(llong(maxmantissa).asDouble() == maxmantissa);
579     LLAssert(llong(-maxmantissa).asDouble() == -maxmantissa);
580 
581     // copy constructor
582     LLAssert(llong(llong(0, 1)).asDouble() == 1);
583     LLAssert(llong(llong(1, 0)).asDouble() == llong::kD32);
584     LLAssert(llong(llong(-1, (uint32_t)-1)).asDouble() == -1);
585 
586     // asInt - test unsigned to signed narrowing conversion
587     LLAssert(llong((uint32_t)-1).asInt() == (int32_t)0x7fffffff);
588     LLAssert(llong(-1, 0).asInt() == (int32_t)0x80000000);
589 
590     // asUInt - test signed to unsigned narrowing conversion
591     LLAssert(llong((int32_t)-1).asUInt() == (uint32_t)-1);
592     LLAssert(llong((int32_t)0x80000000).asUInt() == (uint32_t)0x80000000);
593 
594     // asDouble already tested
595 
596 }
597 
598 void IntlTestRBNF::TestLLongSimpleOperators()
599 {
600     logln("Testing simple operators");
601 
602     // operator==
603     LLAssert(llong() == llong(0, 0));
604     LLAssert(llong(1,0) == llong(1, 0));
605     LLAssert(llong(0,1) == llong(0, 1));
606 
607     // operator!=
608     LLAssert(llong(1,0) != llong(1,1));
609     LLAssert(llong(0,1) != llong(1,1));
610     LLAssert(llong(0xffffffff,0xffffffff) != llong(0x7fffffff, 0xffffffff));
611 
612     // unsigned >
613     LLAssert(llong((int32_t)-1).ugt(llong(0x7fffffff, 0xffffffff)));
614 
615     // unsigned <
616     LLAssert(llong(0x7fffffff, 0xffffffff).ult(llong((int32_t)-1)));
617 
618     // unsigned >=
619     LLAssert(llong((int32_t)-1).uge(llong(0x7fffffff, 0xffffffff)));
620     LLAssert(llong((int32_t)-1).uge(llong((int32_t)-1)));
621 
622     // unsigned <=
623     LLAssert(llong(0x7fffffff, 0xffffffff).ule(llong((int32_t)-1)));
624     LLAssert(llong((int32_t)-1).ule(llong((int32_t)-1)));
625 
626     // operator>
627     LLAssert(llong(1, 1) > llong(1, 0));
628     LLAssert(llong(0, 0x80000000) > llong(0, 0x7fffffff));
629     LLAssert(llong(0x80000000, 1) > llong(0x80000000, 0));
630     LLAssert(llong(1, 0) > llong(0, 0x7fffffff));
631     LLAssert(llong(1, 0) > llong(0, 0xffffffff));
632     LLAssert(llong(0, 0) > llong(0x80000000, 1));
633 
634     // operator<
635     LLAssert(llong(1, 0) < llong(1, 1));
636     LLAssert(llong(0, 0x7fffffff) < llong(0, 0x80000000));
637     LLAssert(llong(0x80000000, 0) < llong(0x80000000, 1));
638     LLAssert(llong(0, 0x7fffffff) < llong(1, 0));
639     LLAssert(llong(0, 0xffffffff) < llong(1, 0));
640     LLAssert(llong(0x80000000, 1) < llong(0, 0));
641 
642     // operator>=
643     LLAssert(llong(1, 1) >= llong(1, 0));
644     LLAssert(llong(0, 0x80000000) >= llong(0, 0x7fffffff));
645     LLAssert(llong(0x80000000, 1) >= llong(0x80000000, 0));
646     LLAssert(llong(1, 0) >= llong(0, 0x7fffffff));
647     LLAssert(llong(1, 0) >= llong(0, 0xffffffff));
648     LLAssert(llong(0, 0) >= llong(0x80000000, 1));
649     LLAssert(llong() >= llong(0, 0));
650     LLAssert(llong(1,0) >= llong(1, 0));
651     LLAssert(llong(0,1) >= llong(0, 1));
652 
653     // operator<=
654     LLAssert(llong(1, 0) <= llong(1, 1));
655     LLAssert(llong(0, 0x7fffffff) <= llong(0, 0x80000000));
656     LLAssert(llong(0x80000000, 0) <= llong(0x80000000, 1));
657     LLAssert(llong(0, 0x7fffffff) <= llong(1, 0));
658     LLAssert(llong(0, 0xffffffff) <= llong(1, 0));
659     LLAssert(llong(0x80000000, 1) <= llong(0, 0));
660     LLAssert(llong() <= llong(0, 0));
661     LLAssert(llong(1,0) <= llong(1, 0));
662     LLAssert(llong(0,1) <= llong(0, 1));
663 
664     // operator==(int32)
665     LLAssert(llong() == (int32_t)0);
666     LLAssert(llong(0,1) == (int32_t)1);
667 
668     // operator!=(int32)
669     LLAssert(llong(1,0) != (int32_t)0);
670     LLAssert(llong(0,1) != (int32_t)2);
671     LLAssert(llong(0,0xffffffff) != (int32_t)-1);
672 
673     llong negOne(0xffffffff, 0xffffffff);
674 
675     // operator>(int32)
676     LLAssert(llong(0, 0x80000000) > (int32_t)0x7fffffff);
677     LLAssert(negOne > (int32_t)-2);
678     LLAssert(llong(1, 0) > (int32_t)0x7fffffff);
679     LLAssert(llong(0, 0) > (int32_t)-1);
680 
681     // operator<(int32)
682     LLAssert(llong(0, 0x7ffffffe) < (int32_t)0x7fffffff);
683     LLAssert(llong(0xffffffff, 0xfffffffe) < (int32_t)-1);
684 
685     // operator>=(int32)
686     LLAssert(llong(0, 0x80000000) >= (int32_t)0x7fffffff);
687     LLAssert(negOne >= (int32_t)-2);
688     LLAssert(llong(1, 0) >= (int32_t)0x7fffffff);
689     LLAssert(llong(0, 0) >= (int32_t)-1);
690     LLAssert(llong() >= (int32_t)0);
691     LLAssert(llong(0,1) >= (int32_t)1);
692 
693     // operator<=(int32)
694     LLAssert(llong(0, 0x7ffffffe) <= (int32_t)0x7fffffff);
695     LLAssert(llong(0xffffffff, 0xfffffffe) <= (int32_t)-1);
696     LLAssert(llong() <= (int32_t)0);
697     LLAssert(llong(0,1) <= (int32_t)1);
698 
699     // operator=
700     LLAssert((llong(2,3) = llong((uint32_t)-1)).asUInt() == (uint32_t)-1);
701 
702     // operator <<=
703     LLAssert((llong(1, 1) <<= 0) ==  llong(1, 1));
704     LLAssert((llong(1, 1) <<= 31) == llong(0x80000000, 0x80000000));
705     LLAssert((llong(1, 1) <<= 32) == llong(1, 0));
706     LLAssert((llong(1, 1) <<= 63) == llong(0x80000000, 0));
707     LLAssert((llong(1, 1) <<= 64) == llong(1, 1)); // only lower 6 bits are used
708     LLAssert((llong(1, 1) <<= -1) == llong(0x80000000, 0)); // only lower 6 bits are used
709 
710     // operator <<
711     LLAssert((llong((int32_t)1) << 5).asUInt() == 32);
712 
713     // operator >>= (sign extended)
714     LLAssert((llong(0x7fffa0a0, 0xbcbcdfdf) >>= 16) == llong(0x7fff,0xa0a0bcbc));
715     LLAssert((llong(0x8000789a, 0xbcde0000) >>= 16) == llong(0xffff8000,0x789abcde));
716     LLAssert((llong(0x80000000, 0) >>= 63) == llong(0xffffffff, 0xffffffff));
717     LLAssert((llong(0x80000000, 0) >>= 47) == llong(0xffffffff, 0xffff0000));
718     LLAssert((llong(0x80000000, 0x80000000) >> 64) == llong(0x80000000, 0x80000000)); // only lower 6 bits are used
719     LLAssert((llong(0x80000000, 0) >>= -1) == llong(0xffffffff, 0xffffffff)); // only lower 6 bits are used
720 
721     // operator >> sign extended)
722     LLAssert((llong(0x8000789a, 0xbcde0000) >> 16) == llong(0xffff8000,0x789abcde));
723 
724     // ushr (right shift without sign extension)
725     LLAssert(llong(0x7fffa0a0, 0xbcbcdfdf).ushr(16) == llong(0x7fff,0xa0a0bcbc));
726     LLAssert(llong(0x8000789a, 0xbcde0000).ushr(16) == llong(0x00008000,0x789abcde));
727     LLAssert(llong(0x80000000, 0).ushr(63) == llong(0, 1));
728     LLAssert(llong(0x80000000, 0).ushr(47) == llong(0, 0x10000));
729     LLAssert(llong(0x80000000, 0x80000000).ushr(64) == llong(0x80000000, 0x80000000)); // only lower 6 bits are used
730     LLAssert(llong(0x80000000, 0).ushr(-1) == llong(0, 1)); // only lower 6 bits are used
731 
732     // operator&(llong)
733     LLAssert((llong(0x55555555, 0x55555555) & llong(0xaaaaffff, 0xffffaaaa)) == llong(0x00005555, 0x55550000));
734 
735     // operator|(llong)
736     LLAssert((llong(0x55555555, 0x55555555) | llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffffff, 0xffffffff));
737 
738     // operator^(llong)
739     LLAssert((llong(0x55555555, 0x55555555) ^ llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffaaaa, 0xaaaaffff));
740 
741     // operator&(uint32)
742     LLAssert((llong(0x55555555, 0x55555555) & (uint32_t)0xffffaaaa) == llong(0, 0x55550000));
743 
744     // operator|(uint32)
745     LLAssert((llong(0x55555555, 0x55555555) | (uint32_t)0xffffaaaa) == llong(0x55555555, 0xffffffff));
746 
747     // operator^(uint32)
748     LLAssert((llong(0x55555555, 0x55555555) ^ (uint32_t)0xffffaaaa) == llong(0x55555555, 0xaaaaffff));
749 
750     // operator~
751     LLAssert(~llong(0x55555555, 0x55555555) == llong(0xaaaaaaaa, 0xaaaaaaaa));
752 
753     // operator&=(llong)
754     LLAssert((llong(0x55555555, 0x55555555) &= llong(0xaaaaffff, 0xffffaaaa)) == llong(0x00005555, 0x55550000));
755 
756     // operator|=(llong)
757     LLAssert((llong(0x55555555, 0x55555555) |= llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffffff, 0xffffffff));
758 
759     // operator^=(llong)
760     LLAssert((llong(0x55555555, 0x55555555) ^= llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffaaaa, 0xaaaaffff));
761 
762     // operator&=(uint32)
763     LLAssert((llong(0x55555555, 0x55555555) &= (uint32_t)0xffffaaaa) == llong(0, 0x55550000));
764 
765     // operator|=(uint32)
766     LLAssert((llong(0x55555555, 0x55555555) |= (uint32_t)0xffffaaaa) == llong(0x55555555, 0xffffffff));
767 
768     // operator^=(uint32)
769     LLAssert((llong(0x55555555, 0x55555555) ^= (uint32_t)0xffffaaaa) == llong(0x55555555, 0xaaaaffff));
770 
771     // prefix inc
772     LLAssert(llong(1, 0) == ++llong(0,0xffffffff));
773 
774     // prefix dec
775     LLAssert(llong(0,0xffffffff) == --llong(1, 0));
776 
777     // postfix inc
778     {
779         llong n(0, 0xffffffff);
780         LLAssert(llong(0, 0xffffffff) == n++);
781         LLAssert(llong(1, 0) == n);
782     }
783 
784     // postfix dec
785     {
786         llong n(1, 0);
787         LLAssert(llong(1, 0) == n--);
788         LLAssert(llong(0, 0xffffffff) == n);
789     }
790 
791     // unary minus
792     LLAssert(llong(0, 0) == -llong(0, 0));
793     LLAssert(llong(0xffffffff, 0xffffffff) == -llong(0, 1));
794     LLAssert(llong(0, 1) == -llong(0xffffffff, 0xffffffff));
795     LLAssert(llong(0x7fffffff, 0xffffffff) == -llong(0x80000000, 1));
796     LLAssert(llong(0x80000000, 0) == -llong(0x80000000, 0)); // !!! we don't handle overflow
797 
798     // operator-=
799     {
800         llong n;
801         LLAssert((n -= llong(0, 1)) == llong(0xffffffff, 0xffffffff));
802         LLAssert(n == llong(0xffffffff, 0xffffffff));
803 
804         n = llong(1, 0);
805         LLAssert((n -= llong(0, 1)) == llong(0, 0xffffffff));
806         LLAssert(n == llong(0, 0xffffffff));
807     }
808 
809     // operator-
810     {
811         llong n;
812         LLAssert((n - llong(0, 1)) == llong(0xffffffff, 0xffffffff));
813         LLAssert(n == llong(0, 0));
814 
815         n = llong(1, 0);
816         LLAssert((n - llong(0, 1)) == llong(0, 0xffffffff));
817         LLAssert(n == llong(1, 0));
818     }
819 
820     // operator+=
821     {
822         llong n(0xffffffff, 0xffffffff);
823         LLAssert((n += llong(0, 1)) == llong(0, 0));
824         LLAssert(n == llong(0, 0));
825 
826         n = llong(0, 0xffffffff);
827         LLAssert((n += llong(0, 1)) == llong(1, 0));
828         LLAssert(n == llong(1, 0));
829     }
830 
831     // operator+
832     {
833         llong n(0xffffffff, 0xffffffff);
834         LLAssert((n + llong(0, 1)) == llong(0, 0));
835         LLAssert(n == llong(0xffffffff, 0xffffffff));
836 
837         n = llong(0, 0xffffffff);
838         LLAssert((n + llong(0, 1)) == llong(1, 0));
839         LLAssert(n == llong(0, 0xffffffff));
840     }
841 
842 }
843 
844 void IntlTestRBNF::TestLLong()
845 {
846     logln("Starting TestLLong");
847 
848     TestLLongConstructors();
849 
850     TestLLongSimpleOperators();
851 
852     logln("Testing operator*=, operator*");
853 
854     // operator*=, operator*
855     // small and large values, positive, &NEGative, zero
856     // also test commutivity
857     {
858         const llong ZERO;
859         const llong ONE(0, 1);
860         const llong NEG_ONE((int32_t)-1);
861         const llong THREE(0, 3);
862         const llong NEG_THREE((int32_t)-3);
863         const llong TWO_TO_16(0, 0x10000);
864         const llong NEG_TWO_TO_16 = -TWO_TO_16;
865         const llong TWO_TO_32(1, 0);
866         const llong NEG_TWO_TO_32 = -TWO_TO_32;
867 
868         const llong NINE(0, 9);
869         const llong NEG_NINE = -NINE;
870 
871         const llong TWO_TO_16X3(0, 0x00030000);
872         const llong NEG_TWO_TO_16X3 = -TWO_TO_16X3;
873 
874         const llong TWO_TO_32X3(3, 0);
875         const llong NEG_TWO_TO_32X3 = -TWO_TO_32X3;
876 
877         const llong TWO_TO_48(0x10000, 0);
878         const llong NEG_TWO_TO_48 = -TWO_TO_48;
879 
880         const int32_t VALUE_WIDTH = 9;
881         const llong* values[VALUE_WIDTH] = {
882             &ZERO, &ONE, &NEG_ONE, &THREE, &NEG_THREE, &TWO_TO_16, &NEG_TWO_TO_16, &TWO_TO_32, &NEG_TWO_TO_32
883         };
884 
885         const llong* answers[VALUE_WIDTH*VALUE_WIDTH] = {
886             &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO,
887             &ZERO, &ONE,  &NEG_ONE, &THREE, &NEG_THREE,  &TWO_TO_16, &NEG_TWO_TO_16, &TWO_TO_32, &NEG_TWO_TO_32,
888             &ZERO, &NEG_ONE, &ONE, &NEG_THREE, &THREE, &NEG_TWO_TO_16, &TWO_TO_16, &NEG_TWO_TO_32, &TWO_TO_32,
889             &ZERO, &THREE, &NEG_THREE, &NINE, &NEG_NINE, &TWO_TO_16X3, &NEG_TWO_TO_16X3, &TWO_TO_32X3, &NEG_TWO_TO_32X3,
890             &ZERO, &NEG_THREE, &THREE, &NEG_NINE, &NINE, &NEG_TWO_TO_16X3, &TWO_TO_16X3, &NEG_TWO_TO_32X3, &TWO_TO_32X3,
891             &ZERO, &TWO_TO_16, &NEG_TWO_TO_16, &TWO_TO_16X3, &NEG_TWO_TO_16X3, &TWO_TO_32, &NEG_TWO_TO_32, &TWO_TO_48, &NEG_TWO_TO_48,
892             &ZERO, &NEG_TWO_TO_16, &TWO_TO_16, &NEG_TWO_TO_16X3, &TWO_TO_16X3, &NEG_TWO_TO_32, &TWO_TO_32, &NEG_TWO_TO_48, &TWO_TO_48,
893             &ZERO, &TWO_TO_32, &NEG_TWO_TO_32, &TWO_TO_32X3, &NEG_TWO_TO_32X3, &TWO_TO_48, &NEG_TWO_TO_48, &ZERO, &ZERO,
894             &ZERO, &NEG_TWO_TO_32, &TWO_TO_32, &NEG_TWO_TO_32X3, &TWO_TO_32X3, &NEG_TWO_TO_48, &TWO_TO_48, &ZERO, &ZERO
895         };
896 
897         for (int i = 0; i < VALUE_WIDTH; ++i) {
898             for (int j = 0; j < VALUE_WIDTH; ++j) {
899                 llong lhs = *values[i];
900                 llong rhs = *values[j];
901                 llong ans = *answers[i*VALUE_WIDTH + j];
902 
903                 llong n = lhs;
904 
905                 LLAssert((n *= rhs) == ans);
906                 LLAssert(n == ans);
907 
908                 n = lhs;
909                 LLAssert((n * rhs) == ans);
910                 LLAssert(n == lhs);
911             }
912         }
913     }
914 
915     logln("Testing operator/=, operator/");
916     // operator/=, operator/
917     // test num = 0, div = 0, pos/neg, > 2^32, div > num
918     {
919         const llong ZERO;
920         const llong ONE(0, 1);
921         const llong NEG_ONE = -ONE;
922         const llong MAX(0x7fffffff, 0xffffffff);
923         const llong MIN(0x80000000, 0);
924         const llong TWO(0, 2);
925         const llong NEG_TWO = -TWO;
926         const llong FIVE(0, 5);
927         const llong NEG_FIVE = -FIVE;
928         const llong TWO_TO_32(1, 0);
929         const llong NEG_TWO_TO_32 = -TWO_TO_32;
930         const llong TWO_TO_32d5 = llong(TWO_TO_32.asDouble()/5.0);
931         const llong NEG_TWO_TO_32d5 = -TWO_TO_32d5;
932         const llong TWO_TO_32X5 = TWO_TO_32 * FIVE;
933         const llong NEG_TWO_TO_32X5 = -TWO_TO_32X5;
934 
935         const llong* tuples[] = { // lhs, rhs, ans
936             &ZERO, &ZERO, &ZERO,
937             &ONE, &ZERO,&MAX,
938             &NEG_ONE, &ZERO, &MIN,
939             &ONE, &ONE, &ONE,
940             &ONE, &NEG_ONE, &NEG_ONE,
941             &NEG_ONE, &ONE, &NEG_ONE,
942             &NEG_ONE, &NEG_ONE, &ONE,
943             &FIVE, &TWO, &TWO,
944             &FIVE, &NEG_TWO, &NEG_TWO,
945             &NEG_FIVE, &TWO, &NEG_TWO,
946             &NEG_FIVE, &NEG_TWO, &TWO,
947             &TWO, &FIVE, &ZERO,
948             &TWO, &NEG_FIVE, &ZERO,
949             &NEG_TWO, &FIVE, &ZERO,
950             &NEG_TWO, &NEG_FIVE, &ZERO,
951             &TWO_TO_32, &TWO_TO_32, &ONE,
952             &TWO_TO_32, &NEG_TWO_TO_32, &NEG_ONE,
953             &NEG_TWO_TO_32, &TWO_TO_32, &NEG_ONE,
954             &NEG_TWO_TO_32, &NEG_TWO_TO_32, &ONE,
955             &TWO_TO_32, &FIVE, &TWO_TO_32d5,
956             &TWO_TO_32, &NEG_FIVE, &NEG_TWO_TO_32d5,
957             &NEG_TWO_TO_32, &FIVE, &NEG_TWO_TO_32d5,
958             &NEG_TWO_TO_32, &NEG_FIVE, &TWO_TO_32d5,
959             &TWO_TO_32X5, &FIVE, &TWO_TO_32,
960             &TWO_TO_32X5, &NEG_FIVE, &NEG_TWO_TO_32,
961             &NEG_TWO_TO_32X5, &FIVE, &NEG_TWO_TO_32,
962             &NEG_TWO_TO_32X5, &NEG_FIVE, &TWO_TO_32,
963             &TWO_TO_32X5, &TWO_TO_32, &FIVE,
964             &TWO_TO_32X5, &NEG_TWO_TO_32, &NEG_FIVE,
965             &NEG_TWO_TO_32X5, &NEG_TWO_TO_32, &FIVE,
966             &NEG_TWO_TO_32X5, &TWO_TO_32, &NEG_FIVE
967         };
968         const int TUPLE_WIDTH = 3;
969         const int TUPLE_COUNT = UPRV_LENGTHOF(tuples)/TUPLE_WIDTH;
970         for (int i = 0; i < TUPLE_COUNT; ++i) {
971             const llong lhs = *tuples[i*TUPLE_WIDTH+0];
972             const llong rhs = *tuples[i*TUPLE_WIDTH+1];
973             const llong ans = *tuples[i*TUPLE_WIDTH+2];
974 
975             llong n = lhs;
976             if (!((n /= rhs) == ans)) {
977                 errln("fail: (n /= rhs) == ans");
978             }
979             LLAssert(n == ans);
980 
981             n = lhs;
982             LLAssert((n / rhs) == ans);
983             LLAssert(n == lhs);
984         }
985     }
986 
987     logln("Testing operator%%=, operator%%");
988     //operator%=, operator%
989     {
990         const llong ZERO;
991         const llong ONE(0, 1);
992         const llong TWO(0, 2);
993         const llong THREE(0,3);
994         const llong FOUR(0, 4);
995         const llong FIVE(0, 5);
996         const llong SIX(0, 6);
997 
998         const llong NEG_ONE = -ONE;
999         const llong NEG_TWO = -TWO;
1000         const llong NEG_THREE = -THREE;
1001         const llong NEG_FOUR = -FOUR;
1002         const llong NEG_FIVE = -FIVE;
1003         const llong NEG_SIX = -SIX;
1004 
1005         const llong NINETY_NINE(0, 99);
1006         const llong HUNDRED(0, 100);
1007         const llong HUNDRED_ONE(0, 101);
1008 
1009         const llong BIG(0x12345678, 0x9abcdef0);
1010         const llong BIG_FIVE(BIG * FIVE);
1011         const llong BIG_FIVEm1 = BIG_FIVE - ONE;
1012         const llong BIG_FIVEp1 = BIG_FIVE + ONE;
1013 
1014         const llong* tuples[] = {
1015             &ZERO, &FIVE, &ZERO,
1016             &ONE, &FIVE, &ONE,
1017             &TWO, &FIVE, &TWO,
1018             &THREE, &FIVE, &THREE,
1019             &FOUR, &FIVE, &FOUR,
1020             &FIVE, &FIVE, &ZERO,
1021             &SIX, &FIVE, &ONE,
1022             &ZERO, &NEG_FIVE, &ZERO,
1023             &ONE, &NEG_FIVE, &ONE,
1024             &TWO, &NEG_FIVE, &TWO,
1025             &THREE, &NEG_FIVE, &THREE,
1026             &FOUR, &NEG_FIVE, &FOUR,
1027             &FIVE, &NEG_FIVE, &ZERO,
1028             &SIX, &NEG_FIVE, &ONE,
1029             &NEG_ONE, &FIVE, &NEG_ONE,
1030             &NEG_TWO, &FIVE, &NEG_TWO,
1031             &NEG_THREE, &FIVE, &NEG_THREE,
1032             &NEG_FOUR, &FIVE, &NEG_FOUR,
1033             &NEG_FIVE, &FIVE, &ZERO,
1034             &NEG_SIX, &FIVE, &NEG_ONE,
1035             &NEG_ONE, &NEG_FIVE, &NEG_ONE,
1036             &NEG_TWO, &NEG_FIVE, &NEG_TWO,
1037             &NEG_THREE, &NEG_FIVE, &NEG_THREE,
1038             &NEG_FOUR, &NEG_FIVE, &NEG_FOUR,
1039             &NEG_FIVE, &NEG_FIVE, &ZERO,
1040             &NEG_SIX, &NEG_FIVE, &NEG_ONE,
1041             &NINETY_NINE, &FIVE, &FOUR,
1042             &HUNDRED, &FIVE, &ZERO,
1043             &HUNDRED_ONE, &FIVE, &ONE,
1044             &BIG_FIVEm1, &FIVE, &FOUR,
1045             &BIG_FIVE, &FIVE, &ZERO,
1046             &BIG_FIVEp1, &FIVE, &ONE
1047         };
1048         const int TUPLE_WIDTH = 3;
1049         const int TUPLE_COUNT = UPRV_LENGTHOF(tuples)/TUPLE_WIDTH;
1050         for (int i = 0; i < TUPLE_COUNT; ++i) {
1051             const llong lhs = *tuples[i*TUPLE_WIDTH+0];
1052             const llong rhs = *tuples[i*TUPLE_WIDTH+1];
1053             const llong ans = *tuples[i*TUPLE_WIDTH+2];
1054 
1055             llong n = lhs;
1056             if (!((n %= rhs) == ans)) {
1057                 errln("fail: (n %= rhs) == ans");
1058             }
1059             LLAssert(n == ans);
1060 
1061             n = lhs;
1062             LLAssert((n % rhs) == ans);
1063             LLAssert(n == lhs);
1064         }
1065     }
1066 
1067     logln("Testing pow");
1068     // pow
1069     LLAssert(llong(0, 0).pow(0) == llong(0, 0));
1070     LLAssert(llong(0, 0).pow(2) == llong(0, 0));
1071     LLAssert(llong(0, 2).pow(0) == llong(0, 1));
1072     LLAssert(llong(0, 2).pow(2) == llong(0, 4));
1073     LLAssert(llong(0, 2).pow(32) == llong(1, 0));
1074     LLAssert(llong(0, 5).pow(10) == llong((double)5.0 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5));
1075 
1076     // absolute value
1077     {
1078         const llong n(0xffffffff,0xffffffff);
1079         LLAssert(n.abs() == llong(0, 1));
1080     }
1081 
1082 #ifdef RBNF_DEBUG
1083     logln("Testing atoll");
1084     // atoll
1085     const char empty[] = "";
1086     const char zero[] = "0";
1087     const char neg_one[] = "-1";
1088     const char neg_12345[] = "-12345";
1089     const char big1[] = "123456789abcdef0";
1090     const char big2[] = "fFfFfFfFfFfFfFfF";
1091     LLAssert(llong::atoll(empty) == llong(0, 0));
1092     LLAssert(llong::atoll(zero) == llong(0, 0));
1093     LLAssert(llong::atoll(neg_one) == llong(0xffffffff, 0xffffffff));
1094     LLAssert(llong::atoll(neg_12345) == -llong(0, 12345));
1095     LLAssert(llong::atoll(big1, 16) == llong(0x12345678, 0x9abcdef0));
1096     LLAssert(llong::atoll(big2, 16) == llong(0xffffffff, 0xffffffff));
1097 #endif
1098 
1099     // u_atoll
1100     const UChar uempty[] = { 0 };
1101     const UChar uzero[] = { 0x30, 0 };
1102     const UChar uneg_one[] = { 0x2d, 0x31, 0 };
1103     const UChar uneg_12345[] = { 0x2d, 0x31, 0x32, 0x33, 0x34, 0x35, 0 };
1104     const UChar ubig1[] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0 };
1105     const UChar ubig2[] = { 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0 };
1106     LLAssert(llong::utoll(uempty) == llong(0, 0));
1107     LLAssert(llong::utoll(uzero) == llong(0, 0));
1108     LLAssert(llong::utoll(uneg_one) == llong(0xffffffff, 0xffffffff));
1109     LLAssert(llong::utoll(uneg_12345) == -llong(0, 12345));
1110     LLAssert(llong::utoll(ubig1, 16) == llong(0x12345678, 0x9abcdef0));
1111     LLAssert(llong::utoll(ubig2, 16) == llong(0xffffffff, 0xffffffff));
1112 
1113 #ifdef RBNF_DEBUG
1114     logln("Testing lltoa");
1115     // lltoa
1116     {
1117         char buf[64]; // ascii
1118         LLAssert((llong(0, 0).lltoa(buf, (uint32_t)sizeof(buf)) == 1) && (strcmp(buf, zero) == 0));
1119         LLAssert((llong(0xffffffff, 0xffffffff).lltoa(buf, (uint32_t)sizeof(buf)) == 2) && (strcmp(buf, neg_one) == 0));
1120         LLAssert(((-llong(0, 12345)).lltoa(buf, (uint32_t)sizeof(buf)) == 6) && (strcmp(buf, neg_12345) == 0));
1121         LLAssert((llong(0x12345678, 0x9abcdef0).lltoa(buf, (uint32_t)sizeof(buf), 16) == 16) && (strcmp(buf, big1) == 0));
1122     }
1123 #endif
1124 
1125     logln("Testing u_lltoa");
1126     // u_lltoa
1127     {
1128         UChar buf[64];
1129         LLAssert((llong(0, 0).lltou(buf, (uint32_t)sizeof(buf)) == 1) && (u_strcmp(buf, uzero) == 0));
1130         LLAssert((llong(0xffffffff, 0xffffffff).lltou(buf, (uint32_t)sizeof(buf)) == 2) && (u_strcmp(buf, uneg_one) == 0));
1131         LLAssert(((-llong(0, 12345)).lltou(buf, (uint32_t)sizeof(buf)) == 6) && (u_strcmp(buf, uneg_12345) == 0));
1132         LLAssert((llong(0x12345678, 0x9abcdef0).lltou(buf, (uint32_t)sizeof(buf), 16) == 16) && (u_strcmp(buf, ubig1) == 0));
1133     }
1134 }
1135 
1136 /* if 0 */
1137 #endif
1138 
1139 void
TestEnglishSpellout()1140 IntlTestRBNF::TestEnglishSpellout()
1141 {
1142     UErrorCode status = U_ZERO_ERROR;
1143     RuleBasedNumberFormat* formatter
1144         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getUS(), status);
1145     if (U_FAILURE(status)) {
1146         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1147     } else {
1148         static const char* const testData[][2] = {
1149             { "1", "one" },
1150             { "2", "two" },
1151             { "15", "fifteen" },
1152             { "20", "twenty" },
1153             { "23", "twenty-three" },
1154             { "73", "seventy-three" },
1155             { "88", "eighty-eight" },
1156             { "100", "one hundred" },
1157             { "106", "one hundred six" },
1158             { "127", "one hundred twenty-seven" },
1159             { "200", "two hundred" },
1160             { "579", "five hundred seventy-nine" },
1161             { "1,000", "one thousand" },
1162             { "2,000", "two thousand" },
1163             { "3,004", "three thousand four" },
1164             { "4,567", "four thousand five hundred sixty-seven" },
1165             { "15,943", "fifteen thousand nine hundred forty-three" },
1166             { "2,345,678", "two million three hundred forty-five thousand six hundred seventy-eight" },
1167             { "-36", "minus thirty-six" },
1168             { "234.567", "two hundred thirty-four point five six seven" },
1169             { NULL, NULL}
1170         };
1171 
1172         doTest(formatter, testData, TRUE);
1173 
1174 #if !UCONFIG_NO_COLLATION
1175         formatter->setLenient(TRUE);
1176         static const char* lpTestData[][2] = {
1177             { "fifty-7", "57" },
1178             { " fifty-7", "57" },
1179             { "  fifty-7", "57" },
1180             { "2 thousand six    HUNDRED fifty-7", "2,657" },
1181             { "fifteen hundred and zero", "1,500" },
1182             { "FOurhundred     thiRTY six", "436" },
1183             { NULL, NULL}
1184         };
1185         doLenientParseTest(formatter, lpTestData);
1186 #endif
1187     }
1188     delete formatter;
1189 }
1190 
1191 void
TestOrdinalAbbreviations()1192 IntlTestRBNF::TestOrdinalAbbreviations()
1193 {
1194     UErrorCode status = U_ZERO_ERROR;
1195     RuleBasedNumberFormat* formatter
1196         = new RuleBasedNumberFormat(URBNF_ORDINAL, Locale::getUS(), status);
1197 
1198     if (U_FAILURE(status)) {
1199         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1200     } else {
1201         static const char* const testData[][2] = {
1202             { "1", "1st" },
1203             { "2", "2nd" },
1204             { "3", "3rd" },
1205             { "4", "4th" },
1206             { "7", "7th" },
1207             { "10", "10th" },
1208             { "11", "11th" },
1209             { "13", "13th" },
1210             { "20", "20th" },
1211             { "21", "21st" },
1212             { "22", "22nd" },
1213             { "23", "23rd" },
1214             { "24", "24th" },
1215             { "33", "33rd" },
1216             { "102", "102nd" },
1217             { "312", "312th" },
1218             { "12,345", "12,345th" },
1219             { NULL, NULL}
1220         };
1221 
1222         doTest(formatter, testData, FALSE);
1223     }
1224     delete formatter;
1225 }
1226 
1227 void
TestDurations()1228 IntlTestRBNF::TestDurations()
1229 {
1230     UErrorCode status = U_ZERO_ERROR;
1231     RuleBasedNumberFormat* formatter
1232         = new RuleBasedNumberFormat(URBNF_DURATION, Locale::getUS(), status);
1233 
1234     if (U_FAILURE(status)) {
1235         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1236     } else {
1237         static const char* const testData[][2] = {
1238             { "3,600", "1:00:00" },     //move me and I fail
1239             { "0", "0 sec." },
1240             { "1", "1 sec." },
1241             { "24", "24 sec." },
1242             { "60", "1:00" },
1243             { "73", "1:13" },
1244             { "145", "2:25" },
1245             { "666", "11:06" },
1246             //            { "3,600", "1:00:00" },
1247             { "3,740", "1:02:20" },
1248             { "10,293", "2:51:33" },
1249             { NULL, NULL}
1250         };
1251 
1252         doTest(formatter, testData, TRUE);
1253 
1254 #if !UCONFIG_NO_COLLATION
1255         formatter->setLenient(TRUE);
1256         static const char* lpTestData[][2] = {
1257             { "2-51-33", "10,293" },
1258             { NULL, NULL}
1259         };
1260         doLenientParseTest(formatter, lpTestData);
1261 #endif
1262     }
1263     delete formatter;
1264 }
1265 
1266 void
TestSpanishSpellout()1267 IntlTestRBNF::TestSpanishSpellout()
1268 {
1269     UErrorCode status = U_ZERO_ERROR;
1270     RuleBasedNumberFormat* formatter
1271         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("es", "ES", ""), status);
1272 
1273     if (U_FAILURE(status)) {
1274         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1275     } else {
1276         static const char* const testData[][2] = {
1277             { "1", "uno" },
1278             { "6", "seis" },
1279             { "16", "diecis\\u00e9is" },
1280             { "20", "veinte" },
1281             { "24", "veinticuatro" },
1282             { "26", "veintis\\u00e9is" },
1283             { "73", "setenta y tres" },
1284             { "88", "ochenta y ocho" },
1285             { "100", "cien" },
1286             { "106", "ciento seis" },
1287             { "127", "ciento veintisiete" },
1288             { "200", "doscientos" },
1289             { "579", "quinientos setenta y nueve" },
1290             { "1,000", "mil" },
1291             { "2,000", "dos mil" },
1292             { "3,004", "tres mil cuatro" },
1293             { "4,567", "cuatro mil quinientos sesenta y siete" },
1294             { "15,943", "quince mil novecientos cuarenta y tres" },
1295             { "2,345,678", "dos millones trescientos cuarenta y cinco mil seiscientos setenta y ocho"},
1296             { "-36", "menos treinta y seis" },
1297             { "234.567", "doscientos treinta y cuatro coma cinco seis siete" },
1298             { NULL, NULL}
1299         };
1300 
1301         doTest(formatter, testData, TRUE);
1302     }
1303     delete formatter;
1304 }
1305 
1306 void
TestFrenchSpellout()1307 IntlTestRBNF::TestFrenchSpellout()
1308 {
1309     UErrorCode status = U_ZERO_ERROR;
1310     RuleBasedNumberFormat* formatter
1311         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getFrance(), status);
1312 
1313     if (U_FAILURE(status)) {
1314         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1315     } else {
1316         static const char* const testData[][2] = {
1317             { "1", "un" },
1318             { "15", "quinze" },
1319             { "20", "vingt" },
1320             { "21", "vingt-et-un" },
1321             { "23", "vingt-trois" },
1322             { "62", "soixante-deux" },
1323             { "70", "soixante-dix" },
1324             { "71", "soixante-et-onze" },
1325             { "73", "soixante-treize" },
1326             { "80", "quatre-vingts" },
1327             { "88", "quatre-vingt-huit" },
1328             { "100", "cent" },
1329             { "106", "cent six" },
1330             { "127", "cent vingt-sept" },
1331             { "200", "deux cents" },
1332             { "579", "cinq cent soixante-dix-neuf" },
1333             { "1,000", "mille" },
1334             { "1,123", "mille cent vingt-trois" },
1335             { "1,594", "mille cinq cent quatre-vingt-quatorze" },
1336             { "2,000", "deux mille" },
1337             { "3,004", "trois mille quatre" },
1338             { "4,567", "quatre mille cinq cent soixante-sept" },
1339             { "15,943", "quinze mille neuf cent quarante-trois" },
1340             { "2,345,678", "deux millions trois cent quarante-cinq mille six cent soixante-dix-huit" },
1341             { "-36", "moins trente-six" },
1342             { "234.567", "deux cent trente-quatre virgule cinq six sept" },
1343             { NULL, NULL}
1344         };
1345 
1346         doTest(formatter, testData, TRUE);
1347 
1348 #if !UCONFIG_NO_COLLATION
1349         formatter->setLenient(TRUE);
1350         static const char* lpTestData[][2] = {
1351             { "trente-et-un", "31" },
1352             { "un cent quatre vingt dix huit", "198" },
1353             { NULL, NULL}
1354         };
1355         doLenientParseTest(formatter, lpTestData);
1356 #endif
1357     }
1358     delete formatter;
1359 }
1360 
1361 static const char* const swissFrenchTestData[][2] = {
1362     { "1", "un" },
1363     { "15", "quinze" },
1364     { "20", "vingt" },
1365     { "21", "vingt-et-un" },
1366     { "23", "vingt-trois" },
1367     { "62", "soixante-deux" },
1368     { "70", "septante" },
1369     { "71", "septante-et-un" },
1370     { "73", "septante-trois" },
1371     { "80", "huitante" },
1372     { "88", "huitante-huit" },
1373     { "100", "cent" },
1374     { "106", "cent six" },
1375     { "127", "cent vingt-sept" },
1376     { "200", "deux cents" },
1377     { "579", "cinq cent septante-neuf" },
1378     { "1,000", "mille" },
1379     { "1,123", "mille cent vingt-trois" },
1380     { "1,594", "mille cinq cent nonante-quatre" },
1381     { "2,000", "deux mille" },
1382     { "3,004", "trois mille quatre" },
1383     { "4,567", "quatre mille cinq cent soixante-sept" },
1384     { "15,943", "quinze mille neuf cent quarante-trois" },
1385     { "2,345,678", "deux millions trois cent quarante-cinq mille six cent septante-huit" },
1386     { "-36", "moins trente-six" },
1387     { "234.567", "deux cent trente-quatre virgule cinq six sept" },
1388     { NULL, NULL}
1389 };
1390 
1391 void
TestSwissFrenchSpellout()1392 IntlTestRBNF::TestSwissFrenchSpellout()
1393 {
1394     UErrorCode status = U_ZERO_ERROR;
1395     RuleBasedNumberFormat* formatter
1396         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("fr", "CH", ""), status);
1397 
1398     if (U_FAILURE(status)) {
1399         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1400     } else {
1401         doTest(formatter, swissFrenchTestData, TRUE);
1402     }
1403     delete formatter;
1404 }
1405 
1406 static const char* const belgianFrenchTestData[][2] = {
1407     { "1", "un" },
1408     { "15", "quinze" },
1409     { "20", "vingt" },
1410     { "21", "vingt-et-un" },
1411     { "23", "vingt-trois" },
1412     { "62", "soixante-deux" },
1413     { "70", "septante" },
1414     { "71", "septante-et-un" },
1415     { "73", "septante-trois" },
1416     { "80", "quatre-vingts" },
1417     { "88", "quatre-vingt huit" },
1418     { "90", "nonante" },
1419     { "91", "nonante-et-un" },
1420     { "95", "nonante-cinq" },
1421     { "100", "cent" },
1422     { "106", "cent six" },
1423     { "127", "cent vingt-sept" },
1424     { "200", "deux cents" },
1425     { "579", "cinq cent septante-neuf" },
1426     { "1,000", "mille" },
1427     { "1,123", "mille cent vingt-trois" },
1428     { "1,594", "mille cinq cent nonante-quatre" },
1429     { "2,000", "deux mille" },
1430     { "3,004", "trois mille quatre" },
1431     { "4,567", "quatre mille cinq cent soixante-sept" },
1432     { "15,943", "quinze mille neuf cent quarante-trois" },
1433     { "2,345,678", "deux millions trois cent quarante-cinq mille six cent septante-huit" },
1434     { "-36", "moins trente-six" },
1435     { "234.567", "deux cent trente-quatre virgule cinq six sept" },
1436     { NULL, NULL}
1437 };
1438 
1439 
1440 void
TestBelgianFrenchSpellout()1441 IntlTestRBNF::TestBelgianFrenchSpellout()
1442 {
1443     UErrorCode status = U_ZERO_ERROR;
1444     RuleBasedNumberFormat* formatter
1445         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("fr", "BE", ""), status);
1446 
1447     if (U_FAILURE(status)) {
1448         errcheckln(status, "rbnf status: 0x%x (%s)\n", status, u_errorName(status));
1449         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1450     } else {
1451         // Belgian french should match Swiss french.
1452         doTest(formatter, belgianFrenchTestData, TRUE);
1453     }
1454     delete formatter;
1455 }
1456 
1457 void
TestItalianSpellout()1458 IntlTestRBNF::TestItalianSpellout()
1459 {
1460     UErrorCode status = U_ZERO_ERROR;
1461     RuleBasedNumberFormat* formatter
1462         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getItalian(), status);
1463 
1464     if (U_FAILURE(status)) {
1465         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1466     } else {
1467         static const char* const testData[][2] = {
1468             { "1", "uno" },
1469             { "15", "quindici" },
1470             { "20", "venti" },
1471             { "23", "venti\\u00ADtr\\u00E9" },
1472             { "73", "settanta\\u00ADtr\\u00E9" },
1473             { "88", "ottant\\u00ADotto" },
1474             { "100", "cento" },
1475             { "101", "cento\\u00ADuno" },
1476             { "103", "cento\\u00ADtr\\u00E9" },
1477             { "106", "cento\\u00ADsei" },
1478             { "108", "cent\\u00ADotto" },
1479             { "127", "cento\\u00ADventi\\u00ADsette" },
1480             { "181", "cent\\u00ADottant\\u00ADuno" },
1481             { "200", "due\\u00ADcento" },
1482             { "579", "cinque\\u00ADcento\\u00ADsettanta\\u00ADnove" },
1483             { "1,000", "mille" },
1484             { "2,000", "due\\u00ADmila" },
1485             { "3,004", "tre\\u00ADmila\\u00ADquattro" },
1486             { "4,567", "quattro\\u00ADmila\\u00ADcinque\\u00ADcento\\u00ADsessanta\\u00ADsette" },
1487             { "15,943", "quindici\\u00ADmila\\u00ADnove\\u00ADcento\\u00ADquaranta\\u00ADtr\\u00E9" },
1488             { "-36", "meno trenta\\u00ADsei" },
1489             { "234.567", "due\\u00ADcento\\u00ADtrenta\\u00ADquattro virgola cinque sei sette" },
1490             { NULL, NULL}
1491         };
1492 
1493         doTest(formatter, testData, TRUE);
1494     }
1495     delete formatter;
1496 }
1497 
1498 void
TestPortugueseSpellout()1499 IntlTestRBNF::TestPortugueseSpellout()
1500 {
1501     UErrorCode status = U_ZERO_ERROR;
1502     RuleBasedNumberFormat* formatter
1503         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("pt","BR",""), status);
1504 
1505     if (U_FAILURE(status)) {
1506         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1507     } else {
1508         static const char* const testData[][2] = {
1509             { "1", "um" },
1510             { "15", "quinze" },
1511             { "20", "vinte" },
1512             { "23", "vinte e tr\\u00EAs" },
1513             { "73", "setenta e tr\\u00EAs" },
1514             { "88", "oitenta e oito" },
1515             { "100", "cem" },
1516             { "106", "cento e seis" },
1517             { "108", "cento e oito" },
1518             { "127", "cento e vinte e sete" },
1519             { "181", "cento e oitenta e um" },
1520             { "200", "duzentos" },
1521             { "579", "quinhentos e setenta e nove" },
1522             { "1,000", "mil" },
1523             { "2,000", "dois mil" },
1524             { "3,004", "tr\\u00EAs mil e quatro" },
1525             { "4,567", "quatro mil e quinhentos e sessenta e sete" },
1526             { "15,943", "quinze mil e novecentos e quarenta e tr\\u00EAs" },
1527             { "-36", "menos trinta e seis" },
1528             { "234.567", "duzentos e trinta e quatro v\\u00EDrgula cinco seis sete" },
1529             { NULL, NULL}
1530         };
1531 
1532         doTest(formatter, testData, TRUE);
1533     }
1534     delete formatter;
1535 }
1536 void
TestGermanSpellout()1537 IntlTestRBNF::TestGermanSpellout()
1538 {
1539     UErrorCode status = U_ZERO_ERROR;
1540     RuleBasedNumberFormat* formatter
1541         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getGermany(), status);
1542 
1543     if (U_FAILURE(status)) {
1544         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1545     } else {
1546         static const char* const testData[][2] = {
1547             { "1", "eins" },
1548             { "15", "f\\u00fcnfzehn" },
1549             { "20", "zwanzig" },
1550             { "23", "drei\\u00ADund\\u00ADzwanzig" },
1551             { "73", "drei\\u00ADund\\u00ADsiebzig" },
1552             { "88", "acht\\u00ADund\\u00ADachtzig" },
1553             { "100", "ein\\u00ADhundert" },
1554             { "106", "ein\\u00ADhundert\\u00ADsechs" },
1555             { "127", "ein\\u00ADhundert\\u00ADsieben\\u00ADund\\u00ADzwanzig" },
1556             { "200", "zwei\\u00ADhundert" },
1557             { "579", "f\\u00fcnf\\u00ADhundert\\u00ADneun\\u00ADund\\u00ADsiebzig" },
1558             { "1,000", "ein\\u00ADtausend" },
1559             { "2,000", "zwei\\u00ADtausend" },
1560             { "3,004", "drei\\u00ADtausend\\u00ADvier" },
1561             { "4,567", "vier\\u00ADtausend\\u00ADf\\u00fcnf\\u00ADhundert\\u00ADsieben\\u00ADund\\u00ADsechzig" },
1562             { "15,943", "f\\u00fcnfzehn\\u00ADtausend\\u00ADneun\\u00ADhundert\\u00ADdrei\\u00ADund\\u00ADvierzig" },
1563             { "2,345,678", "zwei Millionen drei\\u00ADhundert\\u00ADf\\u00fcnf\\u00ADund\\u00ADvierzig\\u00ADtausend\\u00ADsechs\\u00ADhundert\\u00ADacht\\u00ADund\\u00ADsiebzig" },
1564             { NULL, NULL}
1565         };
1566 
1567         doTest(formatter, testData, TRUE);
1568 
1569 #if !UCONFIG_NO_COLLATION
1570         formatter->setLenient(TRUE);
1571         static const char* lpTestData[][2] = {
1572             { "ein Tausend sechs Hundert fuenfunddreissig", "1,635" },
1573             { NULL, NULL}
1574         };
1575         doLenientParseTest(formatter, lpTestData);
1576 #endif
1577     }
1578     delete formatter;
1579 }
1580 
1581 void
TestThaiSpellout()1582 IntlTestRBNF::TestThaiSpellout()
1583 {
1584     UErrorCode status = U_ZERO_ERROR;
1585     RuleBasedNumberFormat* formatter
1586         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("th"), status);
1587 
1588     if (U_FAILURE(status)) {
1589         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1590     } else {
1591         static const char* const testData[][2] = {
1592             { "0", "\\u0e28\\u0e39\\u0e19\\u0e22\\u0e4c" },
1593             { "1", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07" },
1594             { "10", "\\u0e2a\\u0e34\\u0e1a" },
1595             { "11", "\\u0e2a\\u0e34\\u0e1a\\u200b\\u0e40\\u0e2d\\u0e47\\u0e14" },
1596             { "21", "\\u0e22\\u0e35\\u0e48\\u200b\\u0e2a\\u0e34\\u0e1a\\u200b\\u0e40\\u0e2d\\u0e47\\u0e14" },
1597             { "101", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07\\u200b\\u0e23\\u0e49\\u0e2d\\u0e22\\u200b\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07" },
1598             { "1.234", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07\\u200b\\u0e08\\u0e38\\u0e14\\u200b\\u0e2a\\u0e2d\\u0e07\\u0e2a\\u0e32\\u0e21\\u0e2a\\u0e35\\u0e48" },
1599             { NULL, NULL}
1600         };
1601 
1602         doTest(formatter, testData, TRUE);
1603     }
1604     delete formatter;
1605 }
1606 
1607 void
TestSwedishSpellout()1608 IntlTestRBNF::TestSwedishSpellout()
1609 {
1610     UErrorCode status = U_ZERO_ERROR;
1611     RuleBasedNumberFormat* formatter
1612         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("sv"), status);
1613 
1614     if (U_FAILURE(status)) {
1615         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1616     } else {
1617         static const char* testDataDefault[][2] = {
1618             { "101", "ett\\u00adhundra\\u00adett" },
1619             { "123", "ett\\u00adhundra\\u00adtjugo\\u00adtre" },
1620             { "1,001", "et\\u00adtusen ett" },
1621             { "1,100", "et\\u00adtusen ett\\u00adhundra" },
1622             { "1,101", "et\\u00adtusen ett\\u00adhundra\\u00adett" },
1623             { "1,234", "et\\u00adtusen tv\\u00e5\\u00adhundra\\u00adtrettio\\u00adfyra" },
1624             { "10,001", "tio\\u00adtusen ett" },
1625             { "11,000", "elva\\u00adtusen" },
1626             { "12,000", "tolv\\u00adtusen" },
1627             { "20,000", "tjugo\\u00adtusen" },
1628             { "21,000", "tjugo\\u00adet\\u00adtusen" },
1629             { "21,001", "tjugo\\u00adet\\u00adtusen ett" },
1630             { "200,000", "tv\\u00e5\\u00adhundra\\u00adtusen" },
1631             { "201,000", "tv\\u00e5\\u00adhundra\\u00adet\\u00adtusen" },
1632             { "200,200", "tv\\u00e5\\u00adhundra\\u00adtusen tv\\u00e5\\u00adhundra" },
1633             { "2,002,000", "tv\\u00e5 miljoner tv\\u00e5\\u00adtusen" },
1634             { "12,345,678", "tolv miljoner tre\\u00adhundra\\u00adfyrtio\\u00adfem\\u00adtusen sex\\u00adhundra\\u00adsjuttio\\u00ad\\u00e5tta" },
1635             { "123,456.789", "ett\\u00adhundra\\u00adtjugo\\u00adtre\\u00adtusen fyra\\u00adhundra\\u00adfemtio\\u00adsex komma sju \\u00e5tta nio" },
1636             { "-12,345.678", "minus tolv\\u00adtusen tre\\u00adhundra\\u00adfyrtio\\u00adfem komma sex sju \\u00e5tta" },
1637             { NULL, NULL }
1638         };
1639         doTest(formatter, testDataDefault, TRUE);
1640 
1641           static const char* testDataNeutrum[][2] = {
1642               { "101", "ett\\u00adhundra\\u00adett" },
1643               { "1,001", "et\\u00adtusen ett" },
1644               { "1,101", "et\\u00adtusen ett\\u00adhundra\\u00adett" },
1645               { "10,001", "tio\\u00adtusen ett" },
1646               { "21,001", "tjugo\\u00adet\\u00adtusen ett" },
1647               { NULL, NULL }
1648           };
1649 
1650           formatter->setDefaultRuleSet("%spellout-cardinal-neuter", status);
1651           if (U_SUCCESS(status)) {
1652           logln("        testing spellout-cardinal-neuter rules");
1653           doTest(formatter, testDataNeutrum, TRUE);
1654           }
1655           else {
1656           errln("Can't test spellout-cardinal-neuter rules");
1657           }
1658 
1659         static const char* testDataYear[][2] = {
1660             { "101", "ett\\u00adhundra\\u00adett" },
1661             { "900", "nio\\u00adhundra" },
1662             { "1,001", "et\\u00adtusen ett" },
1663             { "1,100", "elva\\u00adhundra" },
1664             { "1,101", "elva\\u00adhundra\\u00adett" },
1665             { "1,234", "tolv\\u00adhundra\\u00adtrettio\\u00adfyra" },
1666             { "2,001", "tjugo\\u00adhundra\\u00adett" },
1667             { "10,001", "tio\\u00adtusen ett" },
1668             { NULL, NULL }
1669         };
1670 
1671         status = U_ZERO_ERROR;
1672         formatter->setDefaultRuleSet("%spellout-numbering-year", status);
1673         if (U_SUCCESS(status)) {
1674             logln("testing year rules");
1675             doTest(formatter, testDataYear, TRUE);
1676         }
1677         else {
1678             errln("Can't test year rules");
1679         }
1680 
1681     }
1682     delete formatter;
1683 }
1684 
1685 void
TestSmallValues()1686 IntlTestRBNF::TestSmallValues()
1687 {
1688     UErrorCode status = U_ZERO_ERROR;
1689     RuleBasedNumberFormat* formatter
1690         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("en_US"), status);
1691 
1692     if (U_FAILURE(status)) {
1693         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1694     } else {
1695         static const char* const testDataDefault[][2] = {
1696         { "0.001", "zero point zero zero one" },
1697         { "0.0001", "zero point zero zero zero one" },
1698         { "0.00001", "zero point zero zero zero zero one" },
1699         { "0.000001", "zero point zero zero zero zero zero one" },
1700         { "0.0000001", "zero point zero zero zero zero zero zero one" },
1701         { "0.00000001", "zero point zero zero zero zero zero zero zero one" },
1702         { "0.000000001", "zero point zero zero zero zero zero zero zero zero one" },
1703         { "0.0000000001", "zero point zero zero zero zero zero zero zero zero zero one" },
1704         { "0.00000000001", "zero point zero zero zero zero zero zero zero zero zero zero one" },
1705         { "0.000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero one" },
1706         { "0.0000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero one" },
1707         { "0.00000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
1708         { "0.000000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
1709         { "10,000,000.001", "ten million point zero zero one" },
1710         { "10,000,000.0001", "ten million point zero zero zero one" },
1711         { "10,000,000.00001", "ten million point zero zero zero zero one" },
1712         { "10,000,000.000001", "ten million point zero zero zero zero zero one" },
1713         { "10,000,000.0000001", "ten million point zero zero zero zero zero zero one" },
1714 //        { "10,000,000.00000001", "ten million point zero zero zero zero zero zero zero one" },
1715 //        { "10,000,000.000000002", "ten million point zero zero zero zero zero zero zero zero two" },
1716         { "10,000,000", "ten million" },
1717 //        { "1,234,567,890.0987654", "one billion, two hundred and thirty-four million, five hundred and sixty-seven thousand, eight hundred and ninety point zero nine eight seven six five four" },
1718 //        { "123,456,789.9876543", "one hundred and twenty-three million, four hundred and fifty-six thousand, seven hundred and eighty-nine point nine eight seven six five four three" },
1719 //        { "12,345,678.87654321", "twelve million, three hundred and forty-five thousand, six hundred and seventy-eight point eight seven six five four three two one" },
1720         { "1,234,567.7654321", "one million two hundred thirty-four thousand five hundred sixty-seven point seven six five four three two one" },
1721         { "123,456.654321", "one hundred twenty-three thousand four hundred fifty-six point six five four three two one" },
1722         { "12,345.54321", "twelve thousand three hundred forty-five point five four three two one" },
1723         { "1,234.4321", "one thousand two hundred thirty-four point four three two one" },
1724         { "123.321", "one hundred twenty-three point three two one" },
1725         { "0.0000000011754944", "zero point zero zero zero zero zero zero zero zero one one seven five four nine four four" },
1726         { "0.000001175494351", "zero point zero zero zero zero zero one one seven five four nine four three five one" },
1727         { NULL, NULL }
1728         };
1729 
1730         doTest(formatter, testDataDefault, TRUE);
1731 
1732         delete formatter;
1733     }
1734 }
1735 
1736 void
TestLocalizations(void)1737 IntlTestRBNF::TestLocalizations(void)
1738 {
1739     int i;
1740     UnicodeString rules("%main:0:no;1:some;100:a lot;1000:tons;\n"
1741         "%other:0:nada;1:yah, some;100:plenty;1000:more'n you'll ever need");
1742 
1743     UErrorCode status = U_ZERO_ERROR;
1744     UParseError perror;
1745     RuleBasedNumberFormat formatter(rules, perror, status);
1746     if (U_FAILURE(status)) {
1747         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1748     } else {
1749         {
1750             static const char* const testData[][2] = {
1751                 { "0", "nada" },
1752                 { "5", "yah, some" },
1753                 { "423", "plenty" },
1754                 { "12345", "more'n you'll ever need" },
1755                 { NULL, NULL }
1756             };
1757             doTest(&formatter, testData, FALSE);
1758         }
1759 
1760         {
1761             UnicodeString loc("<<%main, %other>,<en, Main, Other>,<fr, leMain, leOther>,<de, 'das Main', 'etwas anderes'>>");
1762             static const char* const testData[][2] = {
1763                 { "0", "no" },
1764                 { "5", "some" },
1765                 { "423", "a lot" },
1766                 { "12345", "tons" },
1767                 { NULL, NULL }
1768             };
1769             RuleBasedNumberFormat formatter0(rules, loc, perror, status);
1770             if (U_FAILURE(status)) {
1771                 errln("failed to build second formatter");
1772             } else {
1773                 doTest(&formatter0, testData, FALSE);
1774 
1775                 {
1776                 // exercise localization info
1777                     Locale locale0("en__VALLEY@turkey=gobblegobble");
1778                     Locale locale1("de_DE_FOO");
1779                     Locale locale2("ja_JP");
1780                     UnicodeString name = formatter0.getRuleSetName(0);
1781                     if ( formatter0.getRuleSetDisplayName(0, locale0) == "Main"
1782                       && formatter0.getRuleSetDisplayName(0, locale1) == "das Main"
1783                       && formatter0.getRuleSetDisplayName(0, locale2) == "%main"
1784                       && formatter0.getRuleSetDisplayName(name, locale0) == "Main"
1785                       && formatter0.getRuleSetDisplayName(name, locale1) == "das Main"
1786                       && formatter0.getRuleSetDisplayName(name, locale2) == "%main"){
1787                           logln("getRuleSetDisplayName tested");
1788                     }else {
1789                         errln("failed to getRuleSetDisplayName");
1790                     }
1791                 }
1792 
1793                 for (i = 0; i < formatter0.getNumberOfRuleSetDisplayNameLocales(); ++i) {
1794                     Locale locale = formatter0.getRuleSetDisplayNameLocale(i, status);
1795                     if (U_SUCCESS(status)) {
1796                         for (int j = 0; j < formatter0.getNumberOfRuleSetNames(); ++j) {
1797                             UnicodeString name = formatter0.getRuleSetName(j);
1798                             UnicodeString lname = formatter0.getRuleSetDisplayName(j, locale);
1799                             UnicodeString msg = locale.getName();
1800                             msg.append(": ");
1801                             msg.append(name);
1802                             msg.append(" = ");
1803                             msg.append(lname);
1804                             logln(msg);
1805                         }
1806                     }
1807                 }
1808             }
1809         }
1810 
1811         {
1812             static const char* goodLocs[] = {
1813                 "", // zero-length ok, same as providing no localization data
1814                 "<<>>", // no public rule sets ok
1815                 "<<%main>>", // no localizations ok
1816                 "<<%main,>,<en, Main,>>", // comma before close angle ok
1817                 "<<%main>,<en, ',<>\" '>>", // quotes everything until next quote
1818                 "<<%main>,<'en', \"it's ok\">>", // double quotes work too
1819                 "  \n <\n  <\n  %main\n  >\n  , \t <\t   en\t  ,  \tfoo \t\t > \n\n >  \n ", // Pattern_White_Space ok
1820            };
1821             int32_t goodLocsLen = UPRV_LENGTHOF(goodLocs);
1822 
1823             static const char* badLocs[] = {
1824                 " ", // non-zero length
1825                 "<>", // empty array
1826                 "<", // unclosed outer array
1827                 "<<", // unclosed inner array
1828                 "<<,>>", // unexpected comma
1829                 "<<''>>", // empty string
1830                 "  x<<%main>>", // first non space char not open angle bracket
1831                 "<%main>", // missing inner array
1832                 "<<%main %other>>", // elements missing separating commma (spaces must be quoted)
1833                 "<<%main><en, Main>>", // arrays missing separating comma
1834                 "<<%main>,<en, main, foo>>", // too many elements in locale data
1835                 "<<%main>,<en>>", // too few elements in locale data
1836                 "<<<%main>>>", // unexpected open angle
1837                 "<<%main<>>>", // unexpected open angle
1838                 "<<%main, %other>,<en,,>>", // implicit empty strings
1839                 "<<%main>,<en,''>>", // empty string
1840                 "<<%main>, < en, '>>", // unterminated quote
1841                 "<<%main>, < en, \"<>>", // unterminated quote
1842                 "<<%main\">>", // quote in string
1843                 "<<%main'>>", // quote in string
1844                 "<<%main<>>", // open angle in string
1845                 "<<%main>> x", // extra non-space text at end
1846 
1847             };
1848             int32_t badLocsLen = UPRV_LENGTHOF(badLocs);
1849 
1850             for (i = 0; i < goodLocsLen; ++i) {
1851                 logln("[%d] '%s'", i, goodLocs[i]);
1852                 UErrorCode status = U_ZERO_ERROR;
1853                 UnicodeString loc(goodLocs[i]);
1854                 RuleBasedNumberFormat fmt(rules, loc, perror, status);
1855                 if (U_FAILURE(status)) {
1856                     errln("Failed parse of good localization string: '%s'", goodLocs[i]);
1857                 }
1858             }
1859 
1860             for (i = 0; i < badLocsLen; ++i) {
1861                 logln("[%d] '%s'", i, badLocs[i]);
1862                 UErrorCode status = U_ZERO_ERROR;
1863                 UnicodeString loc(badLocs[i]);
1864                 RuleBasedNumberFormat fmt(rules, loc, perror, status);
1865                 if (U_SUCCESS(status)) {
1866                     errln("Successful parse of bad localization string: '%s'", badLocs[i]);
1867                 }
1868             }
1869         }
1870     }
1871 }
1872 
1873 void
TestAllLocales()1874 IntlTestRBNF::TestAllLocales()
1875 {
1876     const char* names[] = {
1877         " (spellout) ",
1878         " (ordinal)  "
1879         // " (duration) " // This is English only, and it's not really supported in CLDR anymore.
1880     };
1881     double numbers[] = {45.678, 1, 2, 10, 11, 100, 110, 200, 1000, 1111, -1111};
1882 
1883     int32_t count = 0;
1884     const Locale* locales = Locale::getAvailableLocales(count);
1885     for (int i = 0; i < count; ++i) {
1886         const Locale* loc = &locales[i];
1887 
1888         for (int j = 0; j < 2; ++j) {
1889             UErrorCode status = U_ZERO_ERROR;
1890             RuleBasedNumberFormat* f = new RuleBasedNumberFormat((URBNFRuleSetTag)j, *loc, status);
1891 
1892             if (status == U_USING_DEFAULT_WARNING || status == U_USING_FALLBACK_WARNING) {
1893                 // Skip it.
1894                 delete f;
1895                 break;
1896             }
1897             if (U_FAILURE(status)) {
1898                 errln(UnicodeString(loc->getName()) + names[j]
1899                     + "ERROR could not instantiate -> " + u_errorName(status));
1900                 continue;
1901             }
1902 #if !UCONFIG_NO_COLLATION
1903             for (unsigned int numidx = 0; numidx < UPRV_LENGTHOF(numbers); numidx++) {
1904                 double n = numbers[numidx];
1905                 UnicodeString str;
1906                 f->format(n, str);
1907 
1908                 if (verbose) {
1909                     logln(UnicodeString(loc->getName()) + names[j]
1910                         + "success: " + n + " -> " + str);
1911                 }
1912 
1913                 // We do not validate the result in this test case,
1914                 // because there are cases which do not round trip by design.
1915                 Formattable num;
1916 
1917                 // regular parse
1918                 status = U_ZERO_ERROR;
1919                 f->setLenient(FALSE);
1920                 f->parse(str, num, status);
1921                 if (U_FAILURE(status)) {
1922                     errln(UnicodeString(loc->getName()) + names[j]
1923                         + "ERROR could not parse '" + str + "' -> " + u_errorName(status));
1924                 }
1925                 // We only check the spellout. The behavior is undefined for numbers < 1 and fractional numbers.
1926                 if (j == 0) {
1927                     if (num.getType() == Formattable::kLong && num.getLong() != n) {
1928                         errln(UnicodeString(loc->getName()) + names[j]
1929                             + UnicodeString("ERROR could not roundtrip ") + n
1930                             + UnicodeString(" -> ") + str + UnicodeString(" -> ") + num.getLong());
1931                     }
1932                     else if (num.getType() == Formattable::kDouble && (int64_t)(num.getDouble() * 1000) != (int64_t)(n*1000)) {
1933                         // The epsilon difference is too high.
1934                         errln(UnicodeString(loc->getName()) + names[j]
1935                             + UnicodeString("ERROR could not roundtrip ") + n
1936                             + UnicodeString(" -> ") + str + UnicodeString(" -> ") + num.getDouble());
1937                     }
1938                 }
1939                 if (!quick && !logKnownIssue("9503") ) {
1940                     // lenient parse
1941                     status = U_ZERO_ERROR;
1942                     f->setLenient(TRUE);
1943                     f->parse(str, num, status);
1944                     if (U_FAILURE(status)) {
1945                         errln(UnicodeString(loc->getName()) + names[j]
1946                             + "ERROR could not parse(lenient) '" + str + "' -> " + u_errorName(status));
1947                     }
1948                     // We only check the spellout. The behavior is undefined for numbers < 1 and fractional numbers.
1949                     if (j == 0) {
1950                         if (num.getType() == Formattable::kLong && num.getLong() != n) {
1951                             errln(UnicodeString(loc->getName()) + names[j]
1952                                 + UnicodeString("ERROR could not roundtrip ") + n
1953                                 + UnicodeString(" -> ") + str + UnicodeString(" -> ") + num.getLong());
1954                         }
1955                         else if (num.getType() == Formattable::kDouble && (int64_t)(num.getDouble() * 1000) != (int64_t)(n*1000)) {
1956                             // The epsilon difference is too high.
1957                             errln(UnicodeString(loc->getName()) + names[j]
1958                                 + UnicodeString("ERROR could not roundtrip ") + n
1959                                 + UnicodeString(" -> ") + str + UnicodeString(" -> ") + num.getDouble());
1960                         }
1961                     }
1962                 }
1963             }
1964 #endif
1965             delete f;
1966         }
1967     }
1968 }
1969 
1970 void
TestMultiplierSubstitution(void)1971 IntlTestRBNF::TestMultiplierSubstitution(void) {
1972     UnicodeString rules("=#,##0=;1,000,000: <##0.###< million;");
1973     UErrorCode status = U_ZERO_ERROR;
1974     UParseError parse_error;
1975     RuleBasedNumberFormat *rbnf =
1976         new RuleBasedNumberFormat(rules, Locale::getUS(), parse_error, status);
1977     if (U_SUCCESS(status)) {
1978         UnicodeString res;
1979         FieldPosition pos;
1980         double n = 1234000.0;
1981         rbnf->format(n, res, pos);
1982         delete rbnf;
1983 
1984         UnicodeString expected(UNICODE_STRING_SIMPLE("1.234 million"));
1985         if (expected != res) {
1986             UnicodeString msg = "Expected: ";
1987             msg.append(expected);
1988             msg.append(" but got ");
1989             msg.append(res);
1990             errln(msg);
1991         }
1992     }
1993 }
1994 
1995 void
TestSetDecimalFormatSymbols()1996 IntlTestRBNF::TestSetDecimalFormatSymbols() {
1997     UErrorCode status = U_ZERO_ERROR;
1998 
1999     RuleBasedNumberFormat rbnf(URBNF_ORDINAL, Locale::getEnglish(), status);
2000     if (U_FAILURE(status)) {
2001         dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status)));
2002         return;
2003     }
2004 
2005     DecimalFormatSymbols dfs(Locale::getEnglish(), status);
2006     if (U_FAILURE(status)) {
2007         errln("Unable to create DecimalFormatSymbols - " + UnicodeString(u_errorName(status)));
2008         return;
2009     }
2010 
2011     UnicodeString expected[] = {
2012             UnicodeString("1,001st"),
2013             UnicodeString("1&001st")
2014     };
2015 
2016     double number = 1001;
2017 
2018     UnicodeString result;
2019 
2020     rbnf.format(number, result);
2021     if (result != expected[0]) {
2022         errln("Format Error - Got: " + result + " Expected: " + expected[0]);
2023     }
2024 
2025     result.remove();
2026 
2027     /* Set new symbol for testing */
2028     dfs.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, UnicodeString("&"), TRUE);
2029     rbnf.setDecimalFormatSymbols(dfs);
2030 
2031     rbnf.format(number, result);
2032     if (result != expected[1]) {
2033         errln("Format Error - Got: " + result + " Expected: " + expected[1]);
2034     }
2035 }
2036 
TestPluralRules()2037 void IntlTestRBNF::TestPluralRules() {
2038     UErrorCode status = U_ZERO_ERROR;
2039     UnicodeString enRules("%digits-ordinal:-x: ->>;0: =#,##0=$(ordinal,one{st}two{nd}few{rd}other{th})$;");
2040     UParseError parseError;
2041     RuleBasedNumberFormat enFormatter(enRules, Locale::getEnglish(), parseError, status);
2042     if (U_FAILURE(status)) {
2043         dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status)));
2044         return;
2045     }
2046     const char* const enTestData[][2] = {
2047             { "1", "1st" },
2048             { "2", "2nd" },
2049             { "3", "3rd" },
2050             { "4", "4th" },
2051             { "11", "11th" },
2052             { "12", "12th" },
2053             { "13", "13th" },
2054             { "14", "14th" },
2055             { "21", "21st" },
2056             { "22", "22nd" },
2057             { "23", "23rd" },
2058             { "24", "24th" },
2059             { NULL, NULL }
2060     };
2061 
2062     doTest(&enFormatter, enTestData, TRUE);
2063 
2064     // This is trying to model the feminine form, but don't worry about the details too much.
2065     // We're trying to test the plural rules.
2066     UnicodeString ruRules("%spellout-numbering:"
2067             "-x: minus >>;"
2068             "x.x: << point >>;"
2069             "0: zero;"
2070             "1: one;"
2071             "2: two;"
2072             "3: three;"
2073             "4: four;"
2074             "5: five;"
2075             "6: six;"
2076             "7: seven;"
2077             "8: eight;"
2078             "9: nine;"
2079             "10: ten;"
2080             "11: eleven;"
2081             "12: twelve;"
2082             "13: thirteen;"
2083             "14: fourteen;"
2084             "15: fifteen;"
2085             "16: sixteen;"
2086             "17: seventeen;"
2087             "18: eighteen;"
2088             "19: nineteen;"
2089             "20: twenty[->>];"
2090             "30: thirty[->>];"
2091             "40: forty[->>];"
2092             "50: fifty[->>];"
2093             "60: sixty[->>];"
2094             "70: seventy[->>];"
2095             "80: eighty[->>];"
2096             "90: ninety[->>];"
2097             "100: hundred[ >>];"
2098             "200: << hundred[ >>];"
2099             "300: << hundreds[ >>];"
2100             "500: << hundredss[ >>];"
2101             "1000: << $(cardinal,one{thousand}few{thousands}other{thousandss})$[ >>];"
2102             "1000000: << $(cardinal,one{million}few{millions}other{millionss})$[ >>];");
2103     RuleBasedNumberFormat ruFormatter(ruRules, Locale("ru"), parseError, status);
2104     const char* const ruTestData[][2] = {
2105             { "1", "one" },
2106             { "100", "hundred" },
2107             { "125", "hundred twenty-five" },
2108             { "399", "three hundreds ninety-nine" },
2109             { "1,000", "one thousand" },
2110             { "1,001", "one thousand one" },
2111             { "2,000", "two thousands" },
2112             { "2,001", "two thousands one" },
2113             { "2,002", "two thousands two" },
2114             { "3,333", "three thousands three hundreds thirty-three" },
2115             { "5,000", "five thousandss" },
2116             { "11,000", "eleven thousandss" },
2117             { "21,000", "twenty-one thousand" },
2118             { "22,000", "twenty-two thousands" },
2119             { "25,001", "twenty-five thousandss one" },
2120             { NULL, NULL }
2121     };
2122 
2123     if (U_FAILURE(status)) {
2124         errln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status)));
2125         return;
2126     }
2127     doTest(&ruFormatter, ruTestData, TRUE);
2128 
2129     // Make sure there are no divide by 0 errors.
2130     UnicodeString result;
2131     RuleBasedNumberFormat(ruRules, Locale("ru"), parseError, status).format((int32_t)21000, result);
2132     if (result.compare(UNICODE_STRING_SIMPLE("twenty-one thousand")) != 0) {
2133         errln("Got " + result + " for 21000");
2134     }
2135 
2136 }
2137 
TestInfinityNaN()2138 void IntlTestRBNF::TestInfinityNaN() {
2139     UErrorCode status = U_ZERO_ERROR;
2140     UParseError parseError;
2141     UnicodeString enRules("%default:"
2142             "-x: minus >>;"
2143             "Inf: infinite;"
2144             "NaN: not a number;"
2145             "0: =#,##0=;");
2146     RuleBasedNumberFormat enFormatter(enRules, Locale::getEnglish(), parseError, status);
2147     const char * const enTestData[][2] = {
2148             {"1", "1"},
2149             {"\\u221E", "infinite"},
2150             {"-\\u221E", "minus infinite"},
2151             {"NaN", "not a number"},
2152             { NULL, NULL }
2153     };
2154     if (U_FAILURE(status)) {
2155         dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status)));
2156         return;
2157     }
2158 
2159     doTest(&enFormatter, enTestData, true);
2160 
2161     // Test the default behavior when the rules are undefined.
2162     UnicodeString enRules2("%default:"
2163             "-x: ->>;"
2164             "0: =#,##0=;");
2165     RuleBasedNumberFormat enFormatter2(enRules2, Locale::getEnglish(), parseError, status);
2166     if (U_FAILURE(status)) {
2167         errln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status)));
2168         return;
2169     }
2170     const char * const enDefaultTestData[][2] = {
2171             {"1", "1"},
2172             {"\\u221E", "\\u221E"},
2173             {"-\\u221E", "-\\u221E"},
2174             {"NaN", "NaN"},
2175             { NULL, NULL }
2176     };
2177 
2178     doTest(&enFormatter2, enDefaultTestData, true);
2179 }
2180 
TestVariableDecimalPoint()2181 void IntlTestRBNF::TestVariableDecimalPoint() {
2182     UErrorCode status = U_ZERO_ERROR;
2183     UParseError parseError;
2184     UnicodeString enRules("%spellout-numbering:"
2185             "-x: minus >>;"
2186             "x.x: << point >>;"
2187             "x,x: << comma >>;"
2188             "0.x: xpoint >>;"
2189             "0,x: xcomma >>;"
2190             "0: zero;"
2191             "1: one;"
2192             "2: two;"
2193             "3: three;"
2194             "4: four;"
2195             "5: five;"
2196             "6: six;"
2197             "7: seven;"
2198             "8: eight;"
2199             "9: nine;");
2200     RuleBasedNumberFormat enFormatter(enRules, Locale::getEnglish(), parseError, status);
2201     const char * const enTestPointData[][2] = {
2202             {"1.1", "one point one"},
2203             {"1.23", "one point two three"},
2204             {"0.4", "xpoint four"},
2205             { NULL, NULL }
2206     };
2207     if (U_FAILURE(status)) {
2208         dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status)));
2209         return;
2210     }
2211     doTest(&enFormatter, enTestPointData, true);
2212 
2213     DecimalFormatSymbols decimalFormatSymbols(Locale::getEnglish(), status);
2214     decimalFormatSymbols.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, UNICODE_STRING_SIMPLE(","));
2215     enFormatter.setDecimalFormatSymbols(decimalFormatSymbols);
2216     const char * const enTestCommaData[][2] = {
2217             {"1.1", "one comma one"},
2218             {"1.23", "one comma two three"},
2219             {"0.4", "xcomma four"},
2220             { NULL, NULL }
2221     };
2222     doTest(&enFormatter, enTestCommaData, true);
2223 }
2224 
TestLargeNumbers()2225 void IntlTestRBNF::TestLargeNumbers() {
2226     UErrorCode status = U_ZERO_ERROR;
2227     RuleBasedNumberFormat rbnf(URBNF_SPELLOUT, Locale::getEnglish(), status);
2228 
2229     const char * const enTestFullData[][2] = {
2230             {"-9007199254740991", "minus nine quadrillion seven trillion one hundred ninety-nine billion two hundred fifty-four million seven hundred forty thousand nine hundred ninety-one"}, // Maximum precision in both a double and a long
2231             {"9007199254740991", "nine quadrillion seven trillion one hundred ninety-nine billion two hundred fifty-four million seven hundred forty thousand nine hundred ninety-one"}, // Maximum precision in both a double and a long
2232             {"-9007199254740992", "minus nine quadrillion seven trillion one hundred ninety-nine billion two hundred fifty-four million seven hundred forty thousand nine hundred ninety-two"}, // Only precisely contained in a long
2233             {"9007199254740992", "nine quadrillion seven trillion one hundred ninety-nine billion two hundred fifty-four million seven hundred forty thousand nine hundred ninety-two"}, // Only precisely contained in a long
2234             {"9999999999999998", "nine quadrillion nine hundred ninety-nine trillion nine hundred ninety-nine billion nine hundred ninety-nine million nine hundred ninety-nine thousand nine hundred ninety-eight"},
2235             {"9999999999999999", "nine quadrillion nine hundred ninety-nine trillion nine hundred ninety-nine billion nine hundred ninety-nine million nine hundred ninety-nine thousand nine hundred ninety-nine"},
2236             {"999999999999999999", "nine hundred ninety-nine quadrillion nine hundred ninety-nine trillion nine hundred ninety-nine billion nine hundred ninety-nine million nine hundred ninety-nine thousand nine hundred ninety-nine"},
2237             {"1000000000000000000", "1,000,000,000,000,000,000"}, // The rules don't go to 1 quintillion yet
2238             {"-9223372036854775809", "-9,223,372,036,854,775,809"}, // We've gone beyond 64-bit precision
2239             {"-9223372036854775808", "-9,223,372,036,854,775,808"}, // We've gone beyond +64-bit precision
2240             {"-9223372036854775807", "minus 9,223,372,036,854,775,807"}, // Minimum 64-bit precision
2241             {"-9223372036854775806", "minus 9,223,372,036,854,775,806"}, // Minimum 64-bit precision + 1
2242             {"9223372036854774111", "9,223,372,036,854,774,111"}, // Below 64-bit precision
2243             {"9223372036854774999", "9,223,372,036,854,774,999"}, // Below 64-bit precision
2244             {"9223372036854775000", "9,223,372,036,854,775,000"}, // Below 64-bit precision
2245             {"9223372036854775806", "9,223,372,036,854,775,806"}, // Maximum 64-bit precision - 1
2246             {"9223372036854775807", "9,223,372,036,854,775,807"}, // Maximum 64-bit precision
2247             {"9223372036854775808", "9,223,372,036,854,775,808"}, // We've gone beyond 64-bit precision. This can only be represented with BigDecimal.
2248             { NULL, NULL }
2249     };
2250     doTest(&rbnf, enTestFullData, false);
2251 }
2252 
TestCompactDecimalFormatStyle()2253 void IntlTestRBNF::TestCompactDecimalFormatStyle() {
2254     UErrorCode status = U_ZERO_ERROR;
2255     UParseError parseError;
2256     // This is not a common use case, but we're testing it anyway.
2257     UnicodeString numberPattern("=###0.#####=;"
2258             "1000: <###0.00< K;"
2259             "1000000: <###0.00< M;"
2260             "1000000000: <###0.00< B;"
2261             "1000000000000: <###0.00< T;"
2262             "1000000000000000: <###0.00< Q;");
2263     RuleBasedNumberFormat rbnf(numberPattern, UnicodeString(), Locale::getEnglish(), parseError, status);
2264 
2265     const char * const enTestFullData[][2] = {
2266             {"1000", "1.00 K"},
2267             {"1234", "1.23 K"},
2268             {"999994", "999.99 K"},
2269             {"999995", "1000.00 K"},
2270             {"1000000", "1.00 M"},
2271             {"1200000", "1.20 M"},
2272             {"1200000000", "1.20 B"},
2273             {"1200000000000", "1.20 T"},
2274             {"1200000000000000", "1.20 Q"},
2275             {"4503599627370495", "4.50 Q"},
2276             {"4503599627370496", "4.50 Q"},
2277             {"8990000000000000", "8.99 Q"},
2278             {"9008000000000000", "9.00 Q"}, // Number doesn't precisely fit into a double
2279             {"9456000000000000", "9.00 Q"},  // Number doesn't precisely fit into a double
2280             {"10000000000000000", "10.00 Q"},  // Number doesn't precisely fit into a double
2281             {"9223372036854775807", "9223.00 Q"}, // Maximum 64-bit precision
2282             {"9223372036854775808", "9,223,372,036,854,775,808"}, // We've gone beyond 64-bit precision. This can only be represented with BigDecimal.
2283             { NULL, NULL }
2284     };
2285     doTest(&rbnf, enTestFullData, false);
2286 }
2287 
TestParseFailure()2288 void IntlTestRBNF::TestParseFailure() {
2289     UErrorCode status = U_ZERO_ERROR;
2290     RuleBasedNumberFormat rbnf(URBNF_SPELLOUT, Locale::getJapanese(), status);
2291     static const UChar* testData[] = {
2292         u"・・・・・・・・・・・・・・・・・・・・・・・・"
2293     };
2294     if (assertSuccess("", status, true, __FILE__, __LINE__)) {
2295         for (int i = 0; i < UPRV_LENGTHOF(testData); ++i) {
2296             UnicodeString spelledNumberString(testData[i]);
2297             Formattable actualNumber;
2298             rbnf.parse(spelledNumberString, actualNumber, status);
2299             if (status != U_INVALID_FORMAT_ERROR) { // I would have expected U_PARSE_ERROR, but NumberFormat::parse gives U_INVALID_FORMAT_ERROR
2300                 errln("FAIL: string should be unparseable index=%d %s", i, u_errorName(status));
2301             }
2302         }
2303     }
2304 }
2305 
TestMinMaxIntegerDigitsIgnored()2306 void IntlTestRBNF::TestMinMaxIntegerDigitsIgnored() {
2307     IcuTestErrorCode status(*this, "TestMinMaxIntegerDigitsIgnored");
2308 
2309     // NOTE: SimpleDateFormat has an optimization that depends on the fact that min/max integer digits
2310     // do not affect RBNF (see SimpleDateFormat#zeroPaddingNumber).
2311     RuleBasedNumberFormat rbnf(URBNF_SPELLOUT, "en", status);
2312     if (status.isSuccess()) {
2313         rbnf.setMinimumIntegerDigits(2);
2314         rbnf.setMaximumIntegerDigits(3);
2315         UnicodeString result;
2316         rbnf.format(3, result.remove(), status);
2317         assertEquals("Min integer digits are ignored", u"three", result);
2318         rbnf.format(1012, result.remove(), status);
2319         assertEquals("Max integer digits are ignored", u"one thousand twelve", result);
2320     }
2321 }
2322 
2323 void
doTest(RuleBasedNumberFormat * formatter,const char * const testData[][2],UBool testParsing)2324 IntlTestRBNF::doTest(RuleBasedNumberFormat* formatter, const char* const testData[][2], UBool testParsing)
2325 {
2326   // man, error reporting would be easier with printf-style syntax for unicode string and formattable
2327 
2328     UErrorCode status = U_ZERO_ERROR;
2329     DecimalFormatSymbols dfs("en", status);
2330     // NumberFormat* decFmt = NumberFormat::createInstance(Locale::getUS(), status);
2331     DecimalFormat decFmt("#,###.################", dfs, status);
2332     if (U_FAILURE(status)) {
2333         errcheckln(status, "FAIL: could not create NumberFormat - %s", u_errorName(status));
2334     } else {
2335         for (int i = 0; testData[i][0]; ++i) {
2336             const char* numString = testData[i][0];
2337             const char* expectedWords = testData[i][1];
2338 
2339             log("[%i] %s = ", i, numString);
2340             Formattable expectedNumber;
2341             UnicodeString escapedNumString = UnicodeString(numString, -1, US_INV).unescape();
2342             decFmt.parse(escapedNumString, expectedNumber, status);
2343             if (U_FAILURE(status)) {
2344                 errln("FAIL: decFmt could not parse %s", numString);
2345                 break;
2346             } else {
2347                 UnicodeString actualString;
2348                 FieldPosition pos;
2349                 formatter->format(expectedNumber, actualString/* , pos*/, status);
2350                 if (U_FAILURE(status)) {
2351                     UnicodeString msg = "Fail: formatter could not format ";
2352                     decFmt.format(expectedNumber, msg, status);
2353                     errln(msg);
2354                     break;
2355                 } else {
2356                     UnicodeString expectedString = UnicodeString(expectedWords, -1, US_INV).unescape();
2357                     if (actualString != expectedString) {
2358                         UnicodeString msg = "FAIL: check failed for ";
2359                         decFmt.format(expectedNumber, msg, status);
2360                         msg.append(", expected ");
2361                         msg.append(expectedString);
2362                         msg.append(" but got ");
2363                         msg.append(actualString);
2364                         errln(msg);
2365                         break;
2366                     } else {
2367                         logln(actualString);
2368                         if (testParsing) {
2369                             Formattable parsedNumber;
2370                             formatter->parse(actualString, parsedNumber, status);
2371                             if (U_FAILURE(status)) {
2372                                 UnicodeString msg = "FAIL: formatter could not parse ";
2373                                 msg.append(actualString);
2374                                 msg.append(" status code: " );
2375                                 msg.append(u_errorName(status));
2376                                 errln(msg);
2377                                 break;
2378                             } else {
2379                                 if (parsedNumber != expectedNumber
2380                                     && (!uprv_isNaN(parsedNumber.getDouble()) || !uprv_isNaN(expectedNumber.getDouble())))
2381                                 {
2382                                     UnicodeString msg = "FAIL: parse failed for ";
2383                                     msg.append(actualString);
2384                                     msg.append(", expected ");
2385                                     decFmt.format(expectedNumber, msg, status);
2386                                     msg.append(", but got ");
2387                                     decFmt.format(parsedNumber, msg, status);
2388                                     errln(msg);
2389                                     break;
2390                                 }
2391                             }
2392                         }
2393                     }
2394                 }
2395             }
2396         }
2397     }
2398 }
2399 
2400 void
doLenientParseTest(RuleBasedNumberFormat * formatter,const char * testData[][2])2401 IntlTestRBNF::doLenientParseTest(RuleBasedNumberFormat* formatter, const char* testData[][2])
2402 {
2403     UErrorCode status = U_ZERO_ERROR;
2404     NumberFormat* decFmt = NumberFormat::createInstance(Locale::getUS(), status);
2405     if (U_FAILURE(status)) {
2406         errcheckln(status, "FAIL: could not create NumberFormat - %s", u_errorName(status));
2407     } else {
2408         for (int i = 0; testData[i][0]; ++i) {
2409             const char* spelledNumber = testData[i][0]; // spelled-out number
2410             const char* asciiUSNumber = testData[i][1]; // number as ascii digits formatted for US locale
2411 
2412             UnicodeString spelledNumberString = UnicodeString(spelledNumber).unescape();
2413             Formattable actualNumber;
2414             formatter->parse(spelledNumberString, actualNumber, status);
2415             if (U_FAILURE(status)) {
2416                 UnicodeString msg = "FAIL: formatter could not parse ";
2417                 msg.append(spelledNumberString);
2418                 errln(msg);
2419                 break;
2420             } else {
2421                 // I changed the logic of this test somewhat from Java-- instead of comparing the
2422                 // strings, I compare the Formattables.  Hmmm, but the Formattables don't compare,
2423                 // so change it back.
2424 
2425                 UnicodeString asciiUSNumberString = asciiUSNumber;
2426                 Formattable expectedNumber;
2427                 decFmt->parse(asciiUSNumberString, expectedNumber, status);
2428                 if (U_FAILURE(status)) {
2429                     UnicodeString msg = "FAIL: decFmt could not parse ";
2430                     msg.append(asciiUSNumberString);
2431                     errln(msg);
2432                     break;
2433                 } else {
2434                     UnicodeString actualNumberString;
2435                     UnicodeString expectedNumberString;
2436                     decFmt->format(actualNumber, actualNumberString, status);
2437                     decFmt->format(expectedNumber, expectedNumberString, status);
2438                     if (actualNumberString != expectedNumberString) {
2439                         UnicodeString msg = "FAIL: parsing";
2440                         msg.append(asciiUSNumberString);
2441                         msg.append("\n");
2442                         msg.append("  lenient parse failed for ");
2443                         msg.append(spelledNumberString);
2444                         msg.append(", expected ");
2445                         msg.append(expectedNumberString);
2446                         msg.append(", but got ");
2447                         msg.append(actualNumberString);
2448                         errln(msg);
2449                         break;
2450                     }
2451                 }
2452             }
2453         }
2454         delete decFmt;
2455     }
2456 }
2457 
2458 /* U_HAVE_RBNF */
2459 #else
2460 
2461 void
TestRBNFDisabled()2462 IntlTestRBNF::TestRBNFDisabled() {
2463     errln("*** RBNF currently disabled on this platform ***\n");
2464 }
2465 
2466 /* U_HAVE_RBNF */
2467 #endif
2468 
2469 #endif /* #if !UCONFIG_NO_FORMATTING */
2470