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