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