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