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