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