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