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