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