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