]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/intltest/itrbnf.cpp
ICU-8.11.2.tar.gz
[apple/icu.git] / icuSources / test / intltest / itrbnf.cpp
1 /*
2 *******************************************************************************
3 * Copyright (C) 1996-2005, 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 "testutil.h"
23
24 //#include "llong.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((UnicodeString)""); \
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 #else
68 TESTCASE(0, TestRBNFDisabled);
69 #endif
70 default:
71 name = "";
72 break;
73 }
74 }
75
76 #if U_HAVE_RBNF
77
78 void IntlTestRBNF::TestHebrewFraction() {
79 // this is the expected output for 123.45, with no '<' in it.
80 UChar text1[] = {
81 0x05de, 0x05d0, 0x05d4, 0x0020,
82 0x05e2, 0x05e9, 0x05e8, 0x05d9, 0x05dd, 0x0020,
83 0x05d5, 0x05e9, 0x05dc, 0x05d5, 0x05e9, 0x0020,
84 0x05e0, 0x05e7, 0x05d5, 0x05d3, 0x05d4, 0x0020,
85 0x05d0, 0x05e8, 0x05d1, 0x05e2, 0x05d9, 0x05dd, 0x0020,
86 0x05d5, 0x05d7, 0x05de, 0x05e9, 0x0000,
87 };
88 UChar text2[] = {
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, 0x05E4, 0x05E1, 0x0020,
94 0x05D0, 0x05E4, 0x05E1, 0x0020,
95 0x05D0, 0x05E8, 0x05D1, 0x05E2, 0x05D9, 0x05DD, 0x0020,
96 0x05D5, 0x05D7, 0x05DE, 0x05E9, 0x0000,
97 };
98 UErrorCode status = U_ZERO_ERROR;
99 RuleBasedNumberFormat* formatter = new RuleBasedNumberFormat(URBNF_SPELLOUT, "he_IL", status);
100 UnicodeString result;
101 Formattable parseResult;
102 ParsePosition pp(0);
103 {
104 UnicodeString expected(text1);
105 formatter->format(123.45, result);
106 if (result != expected) {
107 errln((UnicodeString)"expected '" + TestUtility::hex(expected) + "'\nbut got: '" + TestUtility::hex(result) + "'");
108 } else {
109 formatter->parse(result, parseResult, pp);
110 if (parseResult.getDouble() != 123.45) {
111 errln("expected 123.45 but got: %g", parseResult.getDouble());
112 }
113 }
114 }
115 {
116 UnicodeString expected(text2);
117 result.remove();
118 formatter->format(123.0045, result);
119 if (result != expected) {
120 errln((UnicodeString)"expected '" + TestUtility::hex(expected) + "'\nbut got: '" + TestUtility::hex(result) + "'");
121 } else {
122 pp.setIndex(0);
123 formatter->parse(result, parseResult, pp);
124 if (parseResult.getDouble() != 123.0045) {
125 errln("expected 123.0045 but got: %g", parseResult.getDouble());
126 }
127 }
128 }
129 delete formatter;
130 }
131
132 void
133 IntlTestRBNF::TestAPI() {
134 // This test goes through the APIs that were not tested before.
135 // These tests are too small to have separate test classes/functions
136
137 UErrorCode status = U_ZERO_ERROR;
138 RuleBasedNumberFormat* formatter
139 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getUS(), status);
140
141 logln("RBNF API test starting");
142 // test clone
143 {
144 logln("Testing Clone");
145 RuleBasedNumberFormat* rbnfClone = (RuleBasedNumberFormat *)formatter->clone();
146 if(rbnfClone != NULL) {
147 if(!(*rbnfClone == *formatter)) {
148 errln("Clone should be semantically equivalent to the original!");
149 }
150 delete rbnfClone;
151 } else {
152 errln("Cloning failed!");
153 }
154 }
155
156 // test assignment
157 {
158 logln("Testing assignment operator");
159 RuleBasedNumberFormat assignResult(URBNF_SPELLOUT, Locale("es", "ES", ""), status);
160 assignResult = *formatter;
161 if(!(assignResult == *formatter)) {
162 errln("Assignment result should be semantically equivalent to the original!");
163 }
164 }
165
166 // test rule constructor
167 {
168 logln("Testing rule constructor");
169 UResourceBundle *en = ures_open(U_ICUDATA_NAME U_TREE_SEPARATOR_STRING "rbnf", "en", &status);
170 if(U_FAILURE(status)) {
171 errln("Unable to access resource bundle with data!");
172 } else {
173 int32_t ruleLen = 0;
174 const UChar *spelloutRules = ures_getStringByKey(en, "SpelloutRules", &ruleLen, &status);
175 if(U_FAILURE(status) || ruleLen == 0 || spelloutRules == NULL) {
176 errln("Unable to access the rules string!");
177 } else {
178 UParseError perror;
179 RuleBasedNumberFormat ruleCtorResult(spelloutRules, Locale::getUS(), perror, status);
180 if(!(ruleCtorResult == *formatter)) {
181 errln("Formatter constructed from the original rules should be semantically equivalent to the original!");
182 }
183
184 // Jitterbug 4452, for coverage
185 RuleBasedNumberFormat nf(spelloutRules, (UnicodeString)"", Locale::getUS(), perror, status);
186 if(!(nf == *formatter)) {
187 errln("Formatter constructed from the original rules should be semantically equivalent to the original!");
188 }
189 }
190 ures_close(en);
191 }
192 }
193
194 // test getRules
195 {
196 logln("Testing getRules function");
197 UnicodeString rules = formatter->getRules();
198 UParseError perror;
199 RuleBasedNumberFormat fromRulesResult(rules, Locale::getUS(), perror, status);
200
201 if(!(fromRulesResult == *formatter)) {
202 errln("Formatter constructed from rules obtained by getRules should be semantically equivalent to the original!");
203 }
204 }
205
206
207 {
208 logln("Testing copy constructor");
209 RuleBasedNumberFormat copyCtorResult(*formatter);
210 if(!(copyCtorResult == *formatter)) {
211 errln("Copy constructor result result should be semantically equivalent to the original!");
212 }
213 }
214
215 #if !UCONFIG_NO_COLLATION
216 // test ruleset names
217 {
218 logln("Testing getNumberOfRuleSetNames, getRuleSetName and format using rule set names");
219 int32_t noOfRuleSetNames = formatter->getNumberOfRuleSetNames();
220 if(noOfRuleSetNames == 0) {
221 errln("Number of rule set names should be more than zero");
222 }
223 UnicodeString ruleSetName;
224 int32_t i = 0;
225 int32_t intFormatNum = 34567;
226 double doubleFormatNum = 893411.234;
227 logln("number of rule set names is %i", noOfRuleSetNames);
228 for(i = 0; i < noOfRuleSetNames; i++) {
229 FieldPosition pos1, pos2;
230 UnicodeString intFormatResult, doubleFormatResult;
231 Formattable intParseResult, doubleParseResult;
232
233 ruleSetName = formatter->getRuleSetName(i);
234 log("Rule set name %i is ", i);
235 log(ruleSetName);
236 logln(". Format results are: ");
237 intFormatResult = formatter->format(intFormatNum, ruleSetName, intFormatResult, pos1, status);
238 doubleFormatResult = formatter->format(doubleFormatNum, ruleSetName, doubleFormatResult, pos2, status);
239 if(U_FAILURE(status)) {
240 errln("Format using a rule set failed");
241 break;
242 }
243 logln(intFormatResult);
244 logln(doubleFormatResult);
245 formatter->setLenient(TRUE);
246 formatter->parse(intFormatResult, intParseResult, status);
247 formatter->parse(doubleFormatResult, doubleParseResult, status);
248
249 logln("Parse results for lenient = TRUE, %i, %f", intParseResult.getLong(), doubleParseResult.getDouble());
250
251 formatter->setLenient(FALSE);
252 formatter->parse(intFormatResult, intParseResult, status);
253 formatter->parse(doubleFormatResult, doubleParseResult, status);
254
255 logln("Parse results for lenient = FALSE, %i, %f", intParseResult.getLong(), doubleParseResult.getDouble());
256
257 if(U_FAILURE(status)) {
258 errln("Error during parsing");
259 }
260
261 intFormatResult = formatter->format(intFormatNum, "BLABLA", intFormatResult, pos1, status);
262 if(U_SUCCESS(status)) {
263 errln("Using invalid rule set name should have failed");
264 break;
265 }
266 status = U_ZERO_ERROR;
267 doubleFormatResult = formatter->format(doubleFormatNum, "TRUC", doubleFormatResult, pos2, status);
268 if(U_SUCCESS(status)) {
269 errln("Using invalid rule set name should have failed");
270 break;
271 }
272 status = U_ZERO_ERROR;
273 }
274 status = U_ZERO_ERROR;
275 }
276 #endif
277
278 // test API
279 UnicodeString expected("four point five","");
280 logln("Testing format(double)");
281 UnicodeString result;
282 formatter->format(4.5,result);
283 if(result != expected) {
284 errln("Formatted 4.5, expected " + expected + " got " + result);
285 } else {
286 logln("Formatted 4.5, expected " + expected + " got " + result);
287 }
288 result.remove();
289 expected = "four";
290 formatter->format((int32_t)4,result);
291 if(result != expected) {
292 errln("Formatted 4, expected " + expected + " got " + result);
293 } else {
294 logln("Formatted 4, expected " + expected + " got " + result);
295 }
296
297 result.remove();
298 FieldPosition pos;
299 formatter->format((int64_t)4, result, pos, status = U_ZERO_ERROR);
300 if(result != expected) {
301 errln("Formatted 4 int64_t, expected " + expected + " got " + result);
302 } else {
303 logln("Formatted 4 int64_t, expected " + expected + " got " + result);
304 }
305
306 //Jitterbug 4452, for coverage
307 result.remove();
308 FieldPosition pos2;
309 formatter->format((int64_t)4, formatter->getRuleSetName(0), result, pos2, status = U_ZERO_ERROR);
310 if(result != expected) {
311 errln("Formatted 4 int64_t, expected " + expected + " got " + result);
312 } else {
313 logln("Formatted 4 int64_t, expected " + expected + " got " + result);
314 }
315
316 // clean up
317 logln("Cleaning up");
318 delete formatter;
319 }
320
321 void IntlTestRBNF::TestFractionalRuleSet()
322 {
323 UnicodeString fracRules(
324 "%main:\n"
325 // this rule formats the number if it's 1 or more. It formats
326 // the integral part using a DecimalFormat ("#,##0" puts
327 // thousands separators in the right places) and the fractional
328 // part using %%frac. If there is no fractional part, it
329 // just shows the integral part.
330 " x.0: <#,##0<[ >%%frac>];\n"
331 // this rule formats the number if it's between 0 and 1. It
332 // shows only the fractional part (0.5 shows up as "1/2," not
333 // "0 1/2")
334 " 0.x: >%%frac>;\n"
335 // the fraction rule set. This works the same way as the one in the
336 // preceding example: We multiply the fractional part of the number
337 // being formatted by each rule's base value and use the rule that
338 // produces the result closest to 0 (or the first rule that produces 0).
339 // Since we only provide rules for the numbers from 2 to 10, we know
340 // we'll get a fraction with a denominator between 2 and 10.
341 // "<0<" causes the numerator of the fraction to be formatted
342 // using numerals
343 "%%frac:\n"
344 " 2: 1/2;\n"
345 " 3: <0</3;\n"
346 " 4: <0</4;\n"
347 " 5: <0</5;\n"
348 " 6: <0</6;\n"
349 " 7: <0</7;\n"
350 " 8: <0</8;\n"
351 " 9: <0</9;\n"
352 " 10: <0</10;\n");
353
354 // mondo hack
355 int len = fracRules.length();
356 int change = 2;
357 for (int i = 0; i < len; ++i) {
358 UChar ch = fracRules.charAt(i);
359 if (ch == '\n') {
360 change = 2; // change ok
361 } else if (ch == ':') {
362 change = 1; // change, but once we hit a non-space char, don't change
363 } else if (ch == ' ') {
364 if (change != 0) {
365 fracRules.setCharAt(i, (UChar)0x200e);
366 }
367 } else {
368 if (change == 1) {
369 change = 0;
370 }
371 }
372 }
373
374 UErrorCode status = U_ZERO_ERROR;
375 UParseError perror;
376 RuleBasedNumberFormat formatter(fracRules, Locale::getEnglish(), perror, status);
377 if (U_FAILURE(status)) {
378 errln("FAIL: could not construct formatter");
379 } else {
380 static const char* testData[][2] = {
381 { "0", "0" },
382 { ".1", "1/10" },
383 { ".11", "1/9" },
384 { ".125", "1/8" },
385 { ".1428", "1/7" },
386 { ".1667", "1/6" },
387 { ".2", "1/5" },
388 { ".25", "1/4" },
389 { ".333", "1/3" },
390 { ".5", "1/2" },
391 { "1.1", "1 1/10" },
392 { "2.11", "2 1/9" },
393 { "3.125", "3 1/8" },
394 { "4.1428", "4 1/7" },
395 { "5.1667", "5 1/6" },
396 { "6.2", "6 1/5" },
397 { "7.25", "7 1/4" },
398 { "8.333", "8 1/3" },
399 { "9.5", "9 1/2" },
400 { ".2222", "2/9" },
401 { ".4444", "4/9" },
402 { ".5555", "5/9" },
403 { "1.2856", "1 2/7" },
404 { NULL, NULL }
405 };
406 doTest(&formatter, testData, FALSE); // exact values aren't parsable from fractions
407 }
408 }
409
410 #if 0
411 #define LLAssert(a) \
412 if (!(a)) errln("FAIL: " #a)
413
414 void IntlTestRBNF::TestLLongConstructors()
415 {
416 logln("Testing constructors");
417
418 // constant (shouldn't really be public)
419 LLAssert(llong(llong::kD32).asDouble() == llong::kD32);
420
421 // internal constructor (shouldn't really be public)
422 LLAssert(llong(0, 1).asDouble() == 1);
423 LLAssert(llong(1, 0).asDouble() == llong::kD32);
424 LLAssert(llong((uint32_t)-1, (uint32_t)-1).asDouble() == -1);
425
426 // public empty constructor
427 LLAssert(llong().asDouble() == 0);
428
429 // public int32_t constructor
430 LLAssert(llong((int32_t)0).asInt() == (int32_t)0);
431 LLAssert(llong((int32_t)1).asInt() == (int32_t)1);
432 LLAssert(llong((int32_t)-1).asInt() == (int32_t)-1);
433 LLAssert(llong((int32_t)0x7fffffff).asInt() == (int32_t)0x7fffffff);
434 LLAssert(llong((int32_t)0xffffffff).asInt() == (int32_t)-1);
435 LLAssert(llong((int32_t)0x80000000).asInt() == (int32_t)0x80000000);
436
437 // public int16_t constructor
438 LLAssert(llong((int16_t)0).asInt() == (int16_t)0);
439 LLAssert(llong((int16_t)1).asInt() == (int16_t)1);
440 LLAssert(llong((int16_t)-1).asInt() == (int16_t)-1);
441 LLAssert(llong((int16_t)0x7fff).asInt() == (int16_t)0x7fff);
442 LLAssert(llong((int16_t)0xffff).asInt() == (int16_t)0xffff);
443 LLAssert(llong((int16_t)0x8000).asInt() == (int16_t)0x8000);
444
445 // public int8_t constructor
446 LLAssert(llong((int8_t)0).asInt() == (int8_t)0);
447 LLAssert(llong((int8_t)1).asInt() == (int8_t)1);
448 LLAssert(llong((int8_t)-1).asInt() == (int8_t)-1);
449 LLAssert(llong((int8_t)0x7f).asInt() == (int8_t)0x7f);
450 LLAssert(llong((int8_t)0xff).asInt() == (int8_t)0xff);
451 LLAssert(llong((int8_t)0x80).asInt() == (int8_t)0x80);
452
453 // public uint16_t constructor
454 LLAssert(llong((uint16_t)0).asUInt() == (uint16_t)0);
455 LLAssert(llong((uint16_t)1).asUInt() == (uint16_t)1);
456 LLAssert(llong((uint16_t)-1).asUInt() == (uint16_t)-1);
457 LLAssert(llong((uint16_t)0x7fff).asUInt() == (uint16_t)0x7fff);
458 LLAssert(llong((uint16_t)0xffff).asUInt() == (uint16_t)0xffff);
459 LLAssert(llong((uint16_t)0x8000).asUInt() == (uint16_t)0x8000);
460
461 // public uint32_t constructor
462 LLAssert(llong((uint32_t)0).asUInt() == (uint32_t)0);
463 LLAssert(llong((uint32_t)1).asUInt() == (uint32_t)1);
464 LLAssert(llong((uint32_t)-1).asUInt() == (uint32_t)-1);
465 LLAssert(llong((uint32_t)0x7fffffff).asUInt() == (uint32_t)0x7fffffff);
466 LLAssert(llong((uint32_t)0xffffffff).asUInt() == (uint32_t)-1);
467 LLAssert(llong((uint32_t)0x80000000).asUInt() == (uint32_t)0x80000000);
468
469 // public double constructor
470 LLAssert(llong((double)0).asDouble() == (double)0);
471 LLAssert(llong((double)1).asDouble() == (double)1);
472 LLAssert(llong((double)0x7fffffff).asDouble() == (double)0x7fffffff);
473 LLAssert(llong((double)0x80000000).asDouble() == (double)0x80000000);
474 LLAssert(llong((double)0x80000001).asDouble() == (double)0x80000001);
475
476 // can't access uprv_maxmantissa, so fake it
477 double maxmantissa = (llong((int32_t)1) << 40).asDouble();
478 LLAssert(llong(maxmantissa).asDouble() == maxmantissa);
479 LLAssert(llong(-maxmantissa).asDouble() == -maxmantissa);
480
481 // copy constructor
482 LLAssert(llong(llong(0, 1)).asDouble() == 1);
483 LLAssert(llong(llong(1, 0)).asDouble() == llong::kD32);
484 LLAssert(llong(llong(-1, (uint32_t)-1)).asDouble() == -1);
485
486 // asInt - test unsigned to signed narrowing conversion
487 LLAssert(llong((uint32_t)-1).asInt() == (int32_t)0x7fffffff);
488 LLAssert(llong(-1, 0).asInt() == (int32_t)0x80000000);
489
490 // asUInt - test signed to unsigned narrowing conversion
491 LLAssert(llong((int32_t)-1).asUInt() == (uint32_t)-1);
492 LLAssert(llong((int32_t)0x80000000).asUInt() == (uint32_t)0x80000000);
493
494 // asDouble already tested
495
496 }
497
498 void IntlTestRBNF::TestLLongSimpleOperators()
499 {
500 logln("Testing simple operators");
501
502 // operator==
503 LLAssert(llong() == llong(0, 0));
504 LLAssert(llong(1,0) == llong(1, 0));
505 LLAssert(llong(0,1) == llong(0, 1));
506
507 // operator!=
508 LLAssert(llong(1,0) != llong(1,1));
509 LLAssert(llong(0,1) != llong(1,1));
510 LLAssert(llong(0xffffffff,0xffffffff) != llong(0x7fffffff, 0xffffffff));
511
512 // unsigned >
513 LLAssert(llong((int32_t)-1).ugt(llong(0x7fffffff, 0xffffffff)));
514
515 // unsigned <
516 LLAssert(llong(0x7fffffff, 0xffffffff).ult(llong((int32_t)-1)));
517
518 // unsigned >=
519 LLAssert(llong((int32_t)-1).uge(llong(0x7fffffff, 0xffffffff)));
520 LLAssert(llong((int32_t)-1).uge(llong((int32_t)-1)));
521
522 // unsigned <=
523 LLAssert(llong(0x7fffffff, 0xffffffff).ule(llong((int32_t)-1)));
524 LLAssert(llong((int32_t)-1).ule(llong((int32_t)-1)));
525
526 // operator>
527 LLAssert(llong(1, 1) > llong(1, 0));
528 LLAssert(llong(0, 0x80000000) > llong(0, 0x7fffffff));
529 LLAssert(llong(0x80000000, 1) > llong(0x80000000, 0));
530 LLAssert(llong(1, 0) > llong(0, 0x7fffffff));
531 LLAssert(llong(1, 0) > llong(0, 0xffffffff));
532 LLAssert(llong(0, 0) > llong(0x80000000, 1));
533
534 // operator<
535 LLAssert(llong(1, 0) < llong(1, 1));
536 LLAssert(llong(0, 0x7fffffff) < llong(0, 0x80000000));
537 LLAssert(llong(0x80000000, 0) < llong(0x80000000, 1));
538 LLAssert(llong(0, 0x7fffffff) < llong(1, 0));
539 LLAssert(llong(0, 0xffffffff) < llong(1, 0));
540 LLAssert(llong(0x80000000, 1) < llong(0, 0));
541
542 // operator>=
543 LLAssert(llong(1, 1) >= llong(1, 0));
544 LLAssert(llong(0, 0x80000000) >= llong(0, 0x7fffffff));
545 LLAssert(llong(0x80000000, 1) >= llong(0x80000000, 0));
546 LLAssert(llong(1, 0) >= llong(0, 0x7fffffff));
547 LLAssert(llong(1, 0) >= llong(0, 0xffffffff));
548 LLAssert(llong(0, 0) >= llong(0x80000000, 1));
549 LLAssert(llong() >= llong(0, 0));
550 LLAssert(llong(1,0) >= llong(1, 0));
551 LLAssert(llong(0,1) >= llong(0, 1));
552
553 // operator<=
554 LLAssert(llong(1, 0) <= llong(1, 1));
555 LLAssert(llong(0, 0x7fffffff) <= llong(0, 0x80000000));
556 LLAssert(llong(0x80000000, 0) <= llong(0x80000000, 1));
557 LLAssert(llong(0, 0x7fffffff) <= llong(1, 0));
558 LLAssert(llong(0, 0xffffffff) <= llong(1, 0));
559 LLAssert(llong(0x80000000, 1) <= llong(0, 0));
560 LLAssert(llong() <= llong(0, 0));
561 LLAssert(llong(1,0) <= llong(1, 0));
562 LLAssert(llong(0,1) <= llong(0, 1));
563
564 // operator==(int32)
565 LLAssert(llong() == (int32_t)0);
566 LLAssert(llong(0,1) == (int32_t)1);
567
568 // operator!=(int32)
569 LLAssert(llong(1,0) != (int32_t)0);
570 LLAssert(llong(0,1) != (int32_t)2);
571 LLAssert(llong(0,0xffffffff) != (int32_t)-1);
572
573 llong negOne(0xffffffff, 0xffffffff);
574
575 // operator>(int32)
576 LLAssert(llong(0, 0x80000000) > (int32_t)0x7fffffff);
577 LLAssert(negOne > (int32_t)-2);
578 LLAssert(llong(1, 0) > (int32_t)0x7fffffff);
579 LLAssert(llong(0, 0) > (int32_t)-1);
580
581 // operator<(int32)
582 LLAssert(llong(0, 0x7ffffffe) < (int32_t)0x7fffffff);
583 LLAssert(llong(0xffffffff, 0xfffffffe) < (int32_t)-1);
584
585 // operator>=(int32)
586 LLAssert(llong(0, 0x80000000) >= (int32_t)0x7fffffff);
587 LLAssert(negOne >= (int32_t)-2);
588 LLAssert(llong(1, 0) >= (int32_t)0x7fffffff);
589 LLAssert(llong(0, 0) >= (int32_t)-1);
590 LLAssert(llong() >= (int32_t)0);
591 LLAssert(llong(0,1) >= (int32_t)1);
592
593 // operator<=(int32)
594 LLAssert(llong(0, 0x7ffffffe) <= (int32_t)0x7fffffff);
595 LLAssert(llong(0xffffffff, 0xfffffffe) <= (int32_t)-1);
596 LLAssert(llong() <= (int32_t)0);
597 LLAssert(llong(0,1) <= (int32_t)1);
598
599 // operator=
600 LLAssert((llong(2,3) = llong((uint32_t)-1)).asUInt() == (uint32_t)-1);
601
602 // operator <<=
603 LLAssert((llong(1, 1) <<= 0) == llong(1, 1));
604 LLAssert((llong(1, 1) <<= 31) == llong(0x80000000, 0x80000000));
605 LLAssert((llong(1, 1) <<= 32) == llong(1, 0));
606 LLAssert((llong(1, 1) <<= 63) == llong(0x80000000, 0));
607 LLAssert((llong(1, 1) <<= 64) == llong(1, 1)); // only lower 6 bits are used
608 LLAssert((llong(1, 1) <<= -1) == llong(0x80000000, 0)); // only lower 6 bits are used
609
610 // operator <<
611 LLAssert((llong((int32_t)1) << 5).asUInt() == 32);
612
613 // operator >>= (sign extended)
614 LLAssert((llong(0x7fffa0a0, 0xbcbcdfdf) >>= 16) == llong(0x7fff,0xa0a0bcbc));
615 LLAssert((llong(0x8000789a, 0xbcde0000) >>= 16) == llong(0xffff8000,0x789abcde));
616 LLAssert((llong(0x80000000, 0) >>= 63) == llong(0xffffffff, 0xffffffff));
617 LLAssert((llong(0x80000000, 0) >>= 47) == llong(0xffffffff, 0xffff0000));
618 LLAssert((llong(0x80000000, 0x80000000) >> 64) == llong(0x80000000, 0x80000000)); // only lower 6 bits are used
619 LLAssert((llong(0x80000000, 0) >>= -1) == llong(0xffffffff, 0xffffffff)); // only lower 6 bits are used
620
621 // operator >> sign extended)
622 LLAssert((llong(0x8000789a, 0xbcde0000) >> 16) == llong(0xffff8000,0x789abcde));
623
624 // ushr (right shift without sign extension)
625 LLAssert(llong(0x7fffa0a0, 0xbcbcdfdf).ushr(16) == llong(0x7fff,0xa0a0bcbc));
626 LLAssert(llong(0x8000789a, 0xbcde0000).ushr(16) == llong(0x00008000,0x789abcde));
627 LLAssert(llong(0x80000000, 0).ushr(63) == llong(0, 1));
628 LLAssert(llong(0x80000000, 0).ushr(47) == llong(0, 0x10000));
629 LLAssert(llong(0x80000000, 0x80000000).ushr(64) == llong(0x80000000, 0x80000000)); // only lower 6 bits are used
630 LLAssert(llong(0x80000000, 0).ushr(-1) == llong(0, 1)); // only lower 6 bits are used
631
632 // operator&(llong)
633 LLAssert((llong(0x55555555, 0x55555555) & llong(0xaaaaffff, 0xffffaaaa)) == llong(0x00005555, 0x55550000));
634
635 // operator|(llong)
636 LLAssert((llong(0x55555555, 0x55555555) | llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffffff, 0xffffffff));
637
638 // operator^(llong)
639 LLAssert((llong(0x55555555, 0x55555555) ^ llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffaaaa, 0xaaaaffff));
640
641 // operator&(uint32)
642 LLAssert((llong(0x55555555, 0x55555555) & (uint32_t)0xffffaaaa) == llong(0, 0x55550000));
643
644 // operator|(uint32)
645 LLAssert((llong(0x55555555, 0x55555555) | (uint32_t)0xffffaaaa) == llong(0x55555555, 0xffffffff));
646
647 // operator^(uint32)
648 LLAssert((llong(0x55555555, 0x55555555) ^ (uint32_t)0xffffaaaa) == llong(0x55555555, 0xaaaaffff));
649
650 // operator~
651 LLAssert(~llong(0x55555555, 0x55555555) == llong(0xaaaaaaaa, 0xaaaaaaaa));
652
653 // operator&=(llong)
654 LLAssert((llong(0x55555555, 0x55555555) &= llong(0xaaaaffff, 0xffffaaaa)) == llong(0x00005555, 0x55550000));
655
656 // operator|=(llong)
657 LLAssert((llong(0x55555555, 0x55555555) |= llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffffff, 0xffffffff));
658
659 // operator^=(llong)
660 LLAssert((llong(0x55555555, 0x55555555) ^= llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffaaaa, 0xaaaaffff));
661
662 // operator&=(uint32)
663 LLAssert((llong(0x55555555, 0x55555555) &= (uint32_t)0xffffaaaa) == llong(0, 0x55550000));
664
665 // operator|=(uint32)
666 LLAssert((llong(0x55555555, 0x55555555) |= (uint32_t)0xffffaaaa) == llong(0x55555555, 0xffffffff));
667
668 // operator^=(uint32)
669 LLAssert((llong(0x55555555, 0x55555555) ^= (uint32_t)0xffffaaaa) == llong(0x55555555, 0xaaaaffff));
670
671 // prefix inc
672 LLAssert(llong(1, 0) == ++llong(0,0xffffffff));
673
674 // prefix dec
675 LLAssert(llong(0,0xffffffff) == --llong(1, 0));
676
677 // postfix inc
678 {
679 llong n(0, 0xffffffff);
680 LLAssert(llong(0, 0xffffffff) == n++);
681 LLAssert(llong(1, 0) == n);
682 }
683
684 // postfix dec
685 {
686 llong n(1, 0);
687 LLAssert(llong(1, 0) == n--);
688 LLAssert(llong(0, 0xffffffff) == n);
689 }
690
691 // unary minus
692 LLAssert(llong(0, 0) == -llong(0, 0));
693 LLAssert(llong(0xffffffff, 0xffffffff) == -llong(0, 1));
694 LLAssert(llong(0, 1) == -llong(0xffffffff, 0xffffffff));
695 LLAssert(llong(0x7fffffff, 0xffffffff) == -llong(0x80000000, 1));
696 LLAssert(llong(0x80000000, 0) == -llong(0x80000000, 0)); // !!! we don't handle overflow
697
698 // operator-=
699 {
700 llong n;
701 LLAssert((n -= llong(0, 1)) == llong(0xffffffff, 0xffffffff));
702 LLAssert(n == llong(0xffffffff, 0xffffffff));
703
704 n = llong(1, 0);
705 LLAssert((n -= llong(0, 1)) == llong(0, 0xffffffff));
706 LLAssert(n == llong(0, 0xffffffff));
707 }
708
709 // operator-
710 {
711 llong n;
712 LLAssert((n - llong(0, 1)) == llong(0xffffffff, 0xffffffff));
713 LLAssert(n == llong(0, 0));
714
715 n = llong(1, 0);
716 LLAssert((n - llong(0, 1)) == llong(0, 0xffffffff));
717 LLAssert(n == llong(1, 0));
718 }
719
720 // operator+=
721 {
722 llong n(0xffffffff, 0xffffffff);
723 LLAssert((n += llong(0, 1)) == llong(0, 0));
724 LLAssert(n == llong(0, 0));
725
726 n = llong(0, 0xffffffff);
727 LLAssert((n += llong(0, 1)) == llong(1, 0));
728 LLAssert(n == llong(1, 0));
729 }
730
731 // operator+
732 {
733 llong n(0xffffffff, 0xffffffff);
734 LLAssert((n + llong(0, 1)) == llong(0, 0));
735 LLAssert(n == llong(0xffffffff, 0xffffffff));
736
737 n = llong(0, 0xffffffff);
738 LLAssert((n + llong(0, 1)) == llong(1, 0));
739 LLAssert(n == llong(0, 0xffffffff));
740 }
741
742 }
743
744 void IntlTestRBNF::TestLLong()
745 {
746 logln("Starting TestLLong");
747
748 TestLLongConstructors();
749
750 TestLLongSimpleOperators();
751
752 logln("Testing operator*=, operator*");
753
754 // operator*=, operator*
755 // small and large values, positive, &NEGative, zero
756 // also test commutivity
757 {
758 const llong ZERO;
759 const llong ONE(0, 1);
760 const llong NEG_ONE((int32_t)-1);
761 const llong THREE(0, 3);
762 const llong NEG_THREE((int32_t)-3);
763 const llong TWO_TO_16(0, 0x10000);
764 const llong NEG_TWO_TO_16 = -TWO_TO_16;
765 const llong TWO_TO_32(1, 0);
766 const llong NEG_TWO_TO_32 = -TWO_TO_32;
767
768 const llong NINE(0, 9);
769 const llong NEG_NINE = -NINE;
770
771 const llong TWO_TO_16X3(0, 0x00030000);
772 const llong NEG_TWO_TO_16X3 = -TWO_TO_16X3;
773
774 const llong TWO_TO_32X3(3, 0);
775 const llong NEG_TWO_TO_32X3 = -TWO_TO_32X3;
776
777 const llong TWO_TO_48(0x10000, 0);
778 const llong NEG_TWO_TO_48 = -TWO_TO_48;
779
780 const int32_t VALUE_WIDTH = 9;
781 const llong* values[VALUE_WIDTH] = {
782 &ZERO, &ONE, &NEG_ONE, &THREE, &NEG_THREE, &TWO_TO_16, &NEG_TWO_TO_16, &TWO_TO_32, &NEG_TWO_TO_32
783 };
784
785 const llong* answers[VALUE_WIDTH*VALUE_WIDTH] = {
786 &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO,
787 &ZERO, &ONE, &NEG_ONE, &THREE, &NEG_THREE, &TWO_TO_16, &NEG_TWO_TO_16, &TWO_TO_32, &NEG_TWO_TO_32,
788 &ZERO, &NEG_ONE, &ONE, &NEG_THREE, &THREE, &NEG_TWO_TO_16, &TWO_TO_16, &NEG_TWO_TO_32, &TWO_TO_32,
789 &ZERO, &THREE, &NEG_THREE, &NINE, &NEG_NINE, &TWO_TO_16X3, &NEG_TWO_TO_16X3, &TWO_TO_32X3, &NEG_TWO_TO_32X3,
790 &ZERO, &NEG_THREE, &THREE, &NEG_NINE, &NINE, &NEG_TWO_TO_16X3, &TWO_TO_16X3, &NEG_TWO_TO_32X3, &TWO_TO_32X3,
791 &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,
792 &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,
793 &ZERO, &TWO_TO_32, &NEG_TWO_TO_32, &TWO_TO_32X3, &NEG_TWO_TO_32X3, &TWO_TO_48, &NEG_TWO_TO_48, &ZERO, &ZERO,
794 &ZERO, &NEG_TWO_TO_32, &TWO_TO_32, &NEG_TWO_TO_32X3, &TWO_TO_32X3, &NEG_TWO_TO_48, &TWO_TO_48, &ZERO, &ZERO
795 };
796
797 for (int i = 0; i < VALUE_WIDTH; ++i) {
798 for (int j = 0; j < VALUE_WIDTH; ++j) {
799 llong lhs = *values[i];
800 llong rhs = *values[j];
801 llong ans = *answers[i*VALUE_WIDTH + j];
802
803 llong n = lhs;
804
805 LLAssert((n *= rhs) == ans);
806 LLAssert(n == ans);
807
808 n = lhs;
809 LLAssert((n * rhs) == ans);
810 LLAssert(n == lhs);
811 }
812 }
813 }
814
815 logln("Testing operator/=, operator/");
816 // operator/=, operator/
817 // test num = 0, div = 0, pos/neg, > 2^32, div > num
818 {
819 const llong ZERO;
820 const llong ONE(0, 1);
821 const llong NEG_ONE = -ONE;
822 const llong MAX(0x7fffffff, 0xffffffff);
823 const llong MIN(0x80000000, 0);
824 const llong TWO(0, 2);
825 const llong NEG_TWO = -TWO;
826 const llong FIVE(0, 5);
827 const llong NEG_FIVE = -FIVE;
828 const llong TWO_TO_32(1, 0);
829 const llong NEG_TWO_TO_32 = -TWO_TO_32;
830 const llong TWO_TO_32d5 = llong(TWO_TO_32.asDouble()/5.0);
831 const llong NEG_TWO_TO_32d5 = -TWO_TO_32d5;
832 const llong TWO_TO_32X5 = TWO_TO_32 * FIVE;
833 const llong NEG_TWO_TO_32X5 = -TWO_TO_32X5;
834
835 const llong* tuples[] = { // lhs, rhs, ans
836 &ZERO, &ZERO, &ZERO,
837 &ONE, &ZERO,&MAX,
838 &NEG_ONE, &ZERO, &MIN,
839 &ONE, &ONE, &ONE,
840 &ONE, &NEG_ONE, &NEG_ONE,
841 &NEG_ONE, &ONE, &NEG_ONE,
842 &NEG_ONE, &NEG_ONE, &ONE,
843 &FIVE, &TWO, &TWO,
844 &FIVE, &NEG_TWO, &NEG_TWO,
845 &NEG_FIVE, &TWO, &NEG_TWO,
846 &NEG_FIVE, &NEG_TWO, &TWO,
847 &TWO, &FIVE, &ZERO,
848 &TWO, &NEG_FIVE, &ZERO,
849 &NEG_TWO, &FIVE, &ZERO,
850 &NEG_TWO, &NEG_FIVE, &ZERO,
851 &TWO_TO_32, &TWO_TO_32, &ONE,
852 &TWO_TO_32, &NEG_TWO_TO_32, &NEG_ONE,
853 &NEG_TWO_TO_32, &TWO_TO_32, &NEG_ONE,
854 &NEG_TWO_TO_32, &NEG_TWO_TO_32, &ONE,
855 &TWO_TO_32, &FIVE, &TWO_TO_32d5,
856 &TWO_TO_32, &NEG_FIVE, &NEG_TWO_TO_32d5,
857 &NEG_TWO_TO_32, &FIVE, &NEG_TWO_TO_32d5,
858 &NEG_TWO_TO_32, &NEG_FIVE, &TWO_TO_32d5,
859 &TWO_TO_32X5, &FIVE, &TWO_TO_32,
860 &TWO_TO_32X5, &NEG_FIVE, &NEG_TWO_TO_32,
861 &NEG_TWO_TO_32X5, &FIVE, &NEG_TWO_TO_32,
862 &NEG_TWO_TO_32X5, &NEG_FIVE, &TWO_TO_32,
863 &TWO_TO_32X5, &TWO_TO_32, &FIVE,
864 &TWO_TO_32X5, &NEG_TWO_TO_32, &NEG_FIVE,
865 &NEG_TWO_TO_32X5, &NEG_TWO_TO_32, &FIVE,
866 &NEG_TWO_TO_32X5, &TWO_TO_32, &NEG_FIVE
867 };
868 const int TUPLE_WIDTH = 3;
869 const int TUPLE_COUNT = (int)(sizeof(tuples)/sizeof(tuples[0]))/TUPLE_WIDTH;
870 for (int i = 0; i < TUPLE_COUNT; ++i) {
871 const llong lhs = *tuples[i*TUPLE_WIDTH+0];
872 const llong rhs = *tuples[i*TUPLE_WIDTH+1];
873 const llong ans = *tuples[i*TUPLE_WIDTH+2];
874
875 llong n = lhs;
876 if (!((n /= rhs) == ans)) {
877 errln("fail: (n /= rhs) == ans");
878 }
879 LLAssert(n == ans);
880
881 n = lhs;
882 LLAssert((n / rhs) == ans);
883 LLAssert(n == lhs);
884 }
885 }
886
887 logln("Testing operator%%=, operator%%");
888 //operator%=, operator%
889 {
890 const llong ZERO;
891 const llong ONE(0, 1);
892 const llong TWO(0, 2);
893 const llong THREE(0,3);
894 const llong FOUR(0, 4);
895 const llong FIVE(0, 5);
896 const llong SIX(0, 6);
897
898 const llong NEG_ONE = -ONE;
899 const llong NEG_TWO = -TWO;
900 const llong NEG_THREE = -THREE;
901 const llong NEG_FOUR = -FOUR;
902 const llong NEG_FIVE = -FIVE;
903 const llong NEG_SIX = -SIX;
904
905 const llong NINETY_NINE(0, 99);
906 const llong HUNDRED(0, 100);
907 const llong HUNDRED_ONE(0, 101);
908
909 const llong BIG(0x12345678, 0x9abcdef0);
910 const llong BIG_FIVE(BIG * FIVE);
911 const llong BIG_FIVEm1 = BIG_FIVE - ONE;
912 const llong BIG_FIVEp1 = BIG_FIVE + ONE;
913
914 const llong* tuples[] = {
915 &ZERO, &FIVE, &ZERO,
916 &ONE, &FIVE, &ONE,
917 &TWO, &FIVE, &TWO,
918 &THREE, &FIVE, &THREE,
919 &FOUR, &FIVE, &FOUR,
920 &FIVE, &FIVE, &ZERO,
921 &SIX, &FIVE, &ONE,
922 &ZERO, &NEG_FIVE, &ZERO,
923 &ONE, &NEG_FIVE, &ONE,
924 &TWO, &NEG_FIVE, &TWO,
925 &THREE, &NEG_FIVE, &THREE,
926 &FOUR, &NEG_FIVE, &FOUR,
927 &FIVE, &NEG_FIVE, &ZERO,
928 &SIX, &NEG_FIVE, &ONE,
929 &NEG_ONE, &FIVE, &NEG_ONE,
930 &NEG_TWO, &FIVE, &NEG_TWO,
931 &NEG_THREE, &FIVE, &NEG_THREE,
932 &NEG_FOUR, &FIVE, &NEG_FOUR,
933 &NEG_FIVE, &FIVE, &ZERO,
934 &NEG_SIX, &FIVE, &NEG_ONE,
935 &NEG_ONE, &NEG_FIVE, &NEG_ONE,
936 &NEG_TWO, &NEG_FIVE, &NEG_TWO,
937 &NEG_THREE, &NEG_FIVE, &NEG_THREE,
938 &NEG_FOUR, &NEG_FIVE, &NEG_FOUR,
939 &NEG_FIVE, &NEG_FIVE, &ZERO,
940 &NEG_SIX, &NEG_FIVE, &NEG_ONE,
941 &NINETY_NINE, &FIVE, &FOUR,
942 &HUNDRED, &FIVE, &ZERO,
943 &HUNDRED_ONE, &FIVE, &ONE,
944 &BIG_FIVEm1, &FIVE, &FOUR,
945 &BIG_FIVE, &FIVE, &ZERO,
946 &BIG_FIVEp1, &FIVE, &ONE
947 };
948 const int TUPLE_WIDTH = 3;
949 const int TUPLE_COUNT = (int)(sizeof(tuples)/sizeof(tuples[0]))/TUPLE_WIDTH;
950 for (int i = 0; i < TUPLE_COUNT; ++i) {
951 const llong lhs = *tuples[i*TUPLE_WIDTH+0];
952 const llong rhs = *tuples[i*TUPLE_WIDTH+1];
953 const llong ans = *tuples[i*TUPLE_WIDTH+2];
954
955 llong n = lhs;
956 if (!((n %= rhs) == ans)) {
957 errln("fail: (n %= rhs) == ans");
958 }
959 LLAssert(n == ans);
960
961 n = lhs;
962 LLAssert((n % rhs) == ans);
963 LLAssert(n == lhs);
964 }
965 }
966
967 logln("Testing pow");
968 // pow
969 LLAssert(llong(0, 0).pow(0) == llong(0, 0));
970 LLAssert(llong(0, 0).pow(2) == llong(0, 0));
971 LLAssert(llong(0, 2).pow(0) == llong(0, 1));
972 LLAssert(llong(0, 2).pow(2) == llong(0, 4));
973 LLAssert(llong(0, 2).pow(32) == llong(1, 0));
974 LLAssert(llong(0, 5).pow(10) == llong((double)5.0 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5));
975
976 // absolute value
977 {
978 const llong n(0xffffffff,0xffffffff);
979 LLAssert(n.abs() == llong(0, 1));
980 }
981
982 #ifdef RBNF_DEBUG
983 logln("Testing atoll");
984 // atoll
985 const char empty[] = "";
986 const char zero[] = "0";
987 const char neg_one[] = "-1";
988 const char neg_12345[] = "-12345";
989 const char big1[] = "123456789abcdef0";
990 const char big2[] = "fFfFfFfFfFfFfFfF";
991 LLAssert(llong::atoll(empty) == llong(0, 0));
992 LLAssert(llong::atoll(zero) == llong(0, 0));
993 LLAssert(llong::atoll(neg_one) == llong(0xffffffff, 0xffffffff));
994 LLAssert(llong::atoll(neg_12345) == -llong(0, 12345));
995 LLAssert(llong::atoll(big1, 16) == llong(0x12345678, 0x9abcdef0));
996 LLAssert(llong::atoll(big2, 16) == llong(0xffffffff, 0xffffffff));
997 #endif
998
999 // u_atoll
1000 const UChar uempty[] = { 0 };
1001 const UChar uzero[] = { 0x30, 0 };
1002 const UChar uneg_one[] = { 0x2d, 0x31, 0 };
1003 const UChar uneg_12345[] = { 0x2d, 0x31, 0x32, 0x33, 0x34, 0x35, 0 };
1004 const UChar ubig1[] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0 };
1005 const UChar ubig2[] = { 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0 };
1006 LLAssert(llong::utoll(uempty) == llong(0, 0));
1007 LLAssert(llong::utoll(uzero) == llong(0, 0));
1008 LLAssert(llong::utoll(uneg_one) == llong(0xffffffff, 0xffffffff));
1009 LLAssert(llong::utoll(uneg_12345) == -llong(0, 12345));
1010 LLAssert(llong::utoll(ubig1, 16) == llong(0x12345678, 0x9abcdef0));
1011 LLAssert(llong::utoll(ubig2, 16) == llong(0xffffffff, 0xffffffff));
1012
1013 #ifdef RBNF_DEBUG
1014 logln("Testing lltoa");
1015 // lltoa
1016 {
1017 char buf[64]; // ascii
1018 LLAssert((llong(0, 0).lltoa(buf, (uint32_t)sizeof(buf)) == 1) && (strcmp(buf, zero) == 0));
1019 LLAssert((llong(0xffffffff, 0xffffffff).lltoa(buf, (uint32_t)sizeof(buf)) == 2) && (strcmp(buf, neg_one) == 0));
1020 LLAssert(((-llong(0, 12345)).lltoa(buf, (uint32_t)sizeof(buf)) == 6) && (strcmp(buf, neg_12345) == 0));
1021 LLAssert((llong(0x12345678, 0x9abcdef0).lltoa(buf, (uint32_t)sizeof(buf), 16) == 16) && (strcmp(buf, big1) == 0));
1022 }
1023 #endif
1024
1025 logln("Testing u_lltoa");
1026 // u_lltoa
1027 {
1028 UChar buf[64];
1029 LLAssert((llong(0, 0).lltou(buf, (uint32_t)sizeof(buf)) == 1) && (u_strcmp(buf, uzero) == 0));
1030 LLAssert((llong(0xffffffff, 0xffffffff).lltou(buf, (uint32_t)sizeof(buf)) == 2) && (u_strcmp(buf, uneg_one) == 0));
1031 LLAssert(((-llong(0, 12345)).lltou(buf, (uint32_t)sizeof(buf)) == 6) && (u_strcmp(buf, uneg_12345) == 0));
1032 LLAssert((llong(0x12345678, 0x9abcdef0).lltou(buf, (uint32_t)sizeof(buf), 16) == 16) && (u_strcmp(buf, ubig1) == 0));
1033 }
1034 }
1035
1036 /* if 0 */
1037 #endif
1038
1039 void
1040 IntlTestRBNF::TestEnglishSpellout()
1041 {
1042 UErrorCode status = U_ZERO_ERROR;
1043 RuleBasedNumberFormat* formatter
1044 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getUS(), status);
1045
1046 if (U_FAILURE(status)) {
1047 errln("FAIL: could not construct formatter");
1048 } else {
1049 static const char* testData[][2] = {
1050 { "1", "one" },
1051 { "2", "two" },
1052 { "15", "fifteen" },
1053 { "20", "twenty" },
1054 { "23", "twenty-three" },
1055 { "73", "seventy-three" },
1056 { "88", "eighty-eight" },
1057 { "100", "one hundred" },
1058 { "106", "one hundred and six" },
1059 { "127", "one hundred and twenty-seven" },
1060 { "200", "two hundred" },
1061 { "579", "five hundred and seventy-nine" },
1062 { "1,000", "one thousand" },
1063 { "2,000", "two thousand" },
1064 { "3,004", "three thousand and four" },
1065 { "4,567", "four thousand five hundred and sixty-seven" },
1066 { "15,943", "fifteen thousand nine hundred and forty-three" },
1067 { "2,345,678", "two million, three hundred and forty-five thousand, six hundred and seventy-eight" },
1068 { "-36", "minus thirty-six" },
1069 { "234.567", "two hundred and thirty-four point five six seven" },
1070 { NULL, NULL}
1071 };
1072
1073 doTest(formatter, testData, TRUE);
1074
1075 #if !UCONFIG_NO_COLLATION
1076 formatter->setLenient(TRUE);
1077 static const char* lpTestData[][2] = {
1078 { "fifty-7", "57" },
1079 { " fifty-7", "57" },
1080 { " fifty-7", "57" },
1081 { "2 thousand six HUNDRED fifty-7", "2,657" },
1082 { "fifteen hundred and zero", "1,500" },
1083 { "FOurhundred thiRTY six", "436" },
1084 { NULL, NULL}
1085 };
1086 doLenientParseTest(formatter, lpTestData);
1087 #endif
1088 }
1089 delete formatter;
1090 }
1091
1092 void
1093 IntlTestRBNF::TestOrdinalAbbreviations()
1094 {
1095 UErrorCode status = U_ZERO_ERROR;
1096 RuleBasedNumberFormat* formatter
1097 = new RuleBasedNumberFormat(URBNF_ORDINAL, Locale::getUS(), status);
1098
1099 if (U_FAILURE(status)) {
1100 errln("FAIL: could not construct formatter");
1101 } else {
1102 static const char* testData[][2] = {
1103 { "1", "1st" },
1104 { "2", "2nd" },
1105 { "3", "3rd" },
1106 { "4", "4th" },
1107 { "7", "7th" },
1108 { "10", "10th" },
1109 { "11", "11th" },
1110 { "13", "13th" },
1111 { "20", "20th" },
1112 { "21", "21st" },
1113 { "22", "22nd" },
1114 { "23", "23rd" },
1115 { "24", "24th" },
1116 { "33", "33rd" },
1117 { "102", "102nd" },
1118 { "312", "312th" },
1119 { "12,345", "12,345th" },
1120 { NULL, NULL}
1121 };
1122
1123 doTest(formatter, testData, FALSE);
1124 }
1125 delete formatter;
1126 }
1127
1128 void
1129 IntlTestRBNF::TestDurations()
1130 {
1131 UErrorCode status = U_ZERO_ERROR;
1132 RuleBasedNumberFormat* formatter
1133 = new RuleBasedNumberFormat(URBNF_DURATION, Locale::getUS(), status);
1134
1135 if (U_FAILURE(status)) {
1136 errln("FAIL: could not construct formatter");
1137 } else {
1138 static const char* testData[][2] = {
1139 { "3,600", "1:00:00" }, //move me and I fail
1140 { "0", "0 sec." },
1141 { "1", "1 sec." },
1142 { "24", "24 sec." },
1143 { "60", "1:00" },
1144 { "73", "1:13" },
1145 { "145", "2:25" },
1146 { "666", "11:06" },
1147 // { "3,600", "1:00:00" },
1148 { "3,740", "1:02:20" },
1149 { "10,293", "2:51:33" },
1150 { NULL, NULL}
1151 };
1152
1153 doTest(formatter, testData, TRUE);
1154
1155 #if !UCONFIG_NO_COLLATION
1156 formatter->setLenient(TRUE);
1157 static const char* lpTestData[][2] = {
1158 { "2-51-33", "10,293" },
1159 { NULL, NULL}
1160 };
1161 doLenientParseTest(formatter, lpTestData);
1162 #endif
1163 }
1164 delete formatter;
1165 }
1166
1167 void
1168 IntlTestRBNF::TestSpanishSpellout()
1169 {
1170 UErrorCode status = U_ZERO_ERROR;
1171 RuleBasedNumberFormat* formatter
1172 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("es", "ES", ""), status);
1173
1174 if (U_FAILURE(status)) {
1175 errln("FAIL: could not construct formatter");
1176 } else {
1177 static const char* testData[][2] = {
1178 { "1", "uno" },
1179 { "6", "seis" },
1180 { "16", "diecis\\u00e9is" },
1181 { "20", "veinte" },
1182 { "24", "veinticuatro" },
1183 { "26", "veintis\\u00e9is" },
1184 { "73", "setenta y tres" },
1185 { "88", "ochenta y ocho" },
1186 { "100", "cien" },
1187 { "106", "ciento seis" },
1188 { "127", "ciento veintisiete" },
1189 { "200", "doscientos" },
1190 { "579", "quinientos setenta y nueve" },
1191 { "1,000", "mil" },
1192 { "2,000", "dos mil" },
1193 { "3,004", "tres mil cuatro" },
1194 { "4,567", "cuatro mil quinientos sesenta y siete" },
1195 { "15,943", "quince mil novecientos cuarenta y tres" },
1196 { "2,345,678", "dos mill\\u00f3n trescientos cuarenta y cinco mil seiscientos setenta y ocho"},
1197 { "-36", "menos treinta y seis" },
1198 { "234.567", "doscientos treinta y cuatro punto cinco seis siete" },
1199 { NULL, NULL}
1200 };
1201
1202 doTest(formatter, testData, TRUE);
1203 }
1204 delete formatter;
1205 }
1206
1207 void
1208 IntlTestRBNF::TestFrenchSpellout()
1209 {
1210 UErrorCode status = U_ZERO_ERROR;
1211 RuleBasedNumberFormat* formatter
1212 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getFrance(), status);
1213
1214 if (U_FAILURE(status)) {
1215 errln("FAIL: could not construct formatter");
1216 } else {
1217 static const char* testData[][2] = {
1218 { "1", "un" },
1219 { "15", "quinze" },
1220 { "20", "vingt" },
1221 { "21", "vingt-et-un" },
1222 { "23", "vingt-trois" },
1223 { "62", "soixante-deux" },
1224 { "70", "soixante-dix" },
1225 { "71", "soixante et onze" },
1226 { "73", "soixante-treize" },
1227 { "80", "quatre-vingts" },
1228 { "88", "quatre-vingt-huit" },
1229 { "100", "cent" },
1230 { "106", "cent six" },
1231 { "127", "cent vingt-sept" },
1232 { "200", "deux cents" },
1233 { "579", "cinq cents soixante-dix-neuf" },
1234 { "1,000", "mille" },
1235 { "1,123", "onze cents vingt-trois" },
1236 { "1,594", "mille cinq cents quatre-vingt-quatorze" },
1237 { "2,000", "deux mille" },
1238 { "3,004", "trois mille quatre" },
1239 { "4,567", "quatre mille cinq cents soixante-sept" },
1240 { "15,943", "quinze mille neuf cents quarante-trois" },
1241 { "2,345,678", "deux million trois cents quarante-cinq mille six cents soixante-dix-huit" },
1242 { "-36", "moins trente-six" },
1243 { "234.567", "deux cents trente-quatre virgule cinq six sept" },
1244 { NULL, NULL}
1245 };
1246
1247 doTest(formatter, testData, TRUE);
1248
1249 #if !UCONFIG_NO_COLLATION
1250 formatter->setLenient(TRUE);
1251 static const char* lpTestData[][2] = {
1252 { "trente-un", "31" },
1253 { "un cents quatre vingt dix huit", "198" },
1254 { NULL, NULL}
1255 };
1256 doLenientParseTest(formatter, lpTestData);
1257 #endif
1258 }
1259 delete formatter;
1260 }
1261
1262 static const char* swissFrenchTestData[][2] = {
1263 { "1", "un" },
1264 { "15", "quinze" },
1265 { "20", "vingt" },
1266 { "21", "vingt-et-un" },
1267 { "23", "vingt-trois" },
1268 { "62", "soixante-deux" },
1269 { "70", "septante" },
1270 { "71", "septante-et-un" },
1271 { "73", "septante-trois" },
1272 { "80", "huitante" },
1273 { "88", "huitante-huit" },
1274 { "100", "cent" },
1275 { "106", "cent six" },
1276 { "127", "cent vingt-sept" },
1277 { "200", "deux cents" },
1278 { "579", "cinq cents septante-neuf" },
1279 { "1,000", "mille" },
1280 { "1,123", "onze cents vingt-trois" },
1281 { "1,594", "mille cinq cents nonante-quatre" },
1282 { "2,000", "deux mille" },
1283 { "3,004", "trois mille quatre" },
1284 { "4,567", "quatre mille cinq cents soixante-sept" },
1285 { "15,943", "quinze mille neuf cents quarante-trois" },
1286 { "2,345,678", "deux million trois cents quarante-cinq mille six cents septante-huit" },
1287 { "-36", "moins trente-six" },
1288 { "234.567", "deux cents trente-quatre virgule cinq six sept" },
1289 { NULL, NULL}
1290 };
1291
1292 void
1293 IntlTestRBNF::TestSwissFrenchSpellout()
1294 {
1295 UErrorCode status = U_ZERO_ERROR;
1296 RuleBasedNumberFormat* formatter
1297 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("fr", "CH", ""), status);
1298
1299 if (U_FAILURE(status)) {
1300 errln("FAIL: could not construct formatter");
1301 } else {
1302 doTest(formatter, swissFrenchTestData, TRUE);
1303 }
1304 delete formatter;
1305 }
1306
1307 void
1308 IntlTestRBNF::TestBelgianFrenchSpellout()
1309 {
1310 UErrorCode status = U_ZERO_ERROR;
1311 RuleBasedNumberFormat* formatter
1312 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("fr", "BE", ""), status);
1313
1314 if (U_FAILURE(status)) {
1315 errln("rbnf status: 0x%x (%s)\n", status, u_errorName(status));
1316 errln("FAIL: could not construct formatter");
1317 } else {
1318 // Belgian french should match Swiss french.
1319 doTest(formatter, swissFrenchTestData, TRUE);
1320 }
1321 delete formatter;
1322 }
1323
1324 void
1325 IntlTestRBNF::TestItalianSpellout()
1326 {
1327 UErrorCode status = U_ZERO_ERROR;
1328 RuleBasedNumberFormat* formatter
1329 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getItalian(), status);
1330
1331 if (U_FAILURE(status)) {
1332 errln("FAIL: could not construct formatter");
1333 } else {
1334 static const char* testData[][2] = {
1335 { "1", "uno" },
1336 { "15", "quindici" },
1337 { "20", "venti" },
1338 { "23", "ventitre" },
1339 { "73", "settantatre" },
1340 { "88", "ottantotto" },
1341 { "100", "cento" },
1342 { "106", "centosei" },
1343 { "108", "centotto" },
1344 { "127", "centoventisette" },
1345 { "181", "centottantuno" },
1346 { "200", "duecento" },
1347 { "579", "cinquecentosettantanove" },
1348 { "1,000", "mille" },
1349 { "2,000", "duemila" },
1350 { "3,004", "tremilaquattro" },
1351 { "4,567", "quattromilacinquecentosessantasette" },
1352 { "15,943", "quindicimilanovecentoquarantatre" },
1353 { "-36", "meno trentisei" },
1354 { "234.567", "duecentotrentiquattro virgola cinque sei sette" },
1355 { NULL, NULL}
1356 };
1357
1358 doTest(formatter, testData, TRUE);
1359 }
1360 delete formatter;
1361 }
1362
1363 void
1364 IntlTestRBNF::TestGermanSpellout()
1365 {
1366 UErrorCode status = U_ZERO_ERROR;
1367 RuleBasedNumberFormat* formatter
1368 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getGermany(), status);
1369
1370 if (U_FAILURE(status)) {
1371 errln("FAIL: could not construct formatter");
1372 } else {
1373 static const char* testData[][2] = {
1374 { "1", "eins" },
1375 { "15", "f\\u00fcnfzehn" },
1376 { "20", "zwanzig" },
1377 { "23", "dreiundzwanzig" },
1378 { "73", "dreiundsiebzig" },
1379 { "88", "achtundachtzig" },
1380 { "100", "hundert" },
1381 { "106", "hundertsechs" },
1382 { "127", "hundertsiebenundzwanzig" },
1383 { "200", "zweihundert" },
1384 { "579", "f\\u00fcnfhundertneunundsiebzig" },
1385 { "1,000", "tausend" },
1386 { "2,000", "zweitausend" },
1387 { "3,004", "dreitausendvier" },
1388 { "4,567", "viertausendf\\u00fcnfhundertsiebenundsechzig" },
1389 { "15,943", "f\\u00fcnfzehntausendneunhundertdreiundvierzig" },
1390 { "2,345,678", "zwei Millionen dreihundertf\\u00fcnfundvierzigtausendsechshundertachtundsiebzig" },
1391 { NULL, NULL}
1392 };
1393
1394 doTest(formatter, testData, TRUE);
1395
1396 #if !UCONFIG_NO_COLLATION
1397 formatter->setLenient(TRUE);
1398 static const char* lpTestData[][2] = {
1399 { "ein Tausend sechs Hundert fuenfunddreissig", "1,635" },
1400 { NULL, NULL}
1401 };
1402 doLenientParseTest(formatter, lpTestData);
1403 #endif
1404 }
1405 delete formatter;
1406 }
1407
1408 void
1409 IntlTestRBNF::TestThaiSpellout()
1410 {
1411 UErrorCode status = U_ZERO_ERROR;
1412 RuleBasedNumberFormat* formatter
1413 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("th"), status);
1414
1415 if (U_FAILURE(status)) {
1416 errln("FAIL: could not construct formatter");
1417 } else {
1418 static const char* testData[][2] = {
1419 { "0", "\\u0e28\\u0e39\\u0e19\\u0e22\\u0e4c" },
1420 { "1", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07" },
1421 { "10", "\\u0e2a\\u0e34\\u0e1a" },
1422 { "11", "\\u0e2a\\u0e34\\u0e1a\\u0e40\\u0e2d\\u0e47\\u0e14" },
1423 { "21", "\\u0e22\\u0e35\\u0e48\\u0e2a\\u0e34\\u0e1a\\u0e40\\u0e2d\\u0e47\\u0e14" },
1424 { "101", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07\\u0e23\\u0e49\\u0e2d\\u0e22\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07" },
1425 { "1.234", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07\\u0e08\\u0e38\\u0e14\\u0e2a\\u0e2d\\u0e07\\u0e2a\\u0e32\\u0e21\\u0e2a\\u0e35\\u0e48" },
1426 { NULL, NULL}
1427 };
1428
1429 doTest(formatter, testData, TRUE);
1430 }
1431 delete formatter;
1432 }
1433
1434 void
1435 IntlTestRBNF::TestSwedishSpellout()
1436 {
1437 UErrorCode status = U_ZERO_ERROR;
1438 RuleBasedNumberFormat* formatter
1439 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("sv"), status);
1440
1441 if (U_FAILURE(status)) {
1442 errln("FAIL: could not construct formatter");
1443 } else {
1444 static const char* testDataDefault[][2] = {
1445 { "101", "etthundra\\u00aden" },
1446 { "123", "etthundra\\u00adtjugotre" },
1447 { "1,001", "ettusen en" },
1448 { "1,100", "ettusen etthundra" },
1449 { "1,101", "ettusen etthundra\\u00aden" },
1450 { "1,234", "ettusen tv\\u00e5hundra\\u00adtrettiofyra" },
1451 { "10,001", "tio\\u00adtusen en" },
1452 { "11,000", "elva\\u00adtusen" },
1453 { "12,000", "tolv\\u00adtusen" },
1454 { "20,000", "tjugo\\u00adtusen" },
1455 { "21,000", "tjugoen\\u00adtusen" },
1456 { "21,001", "tjugoen\\u00adtusen en" },
1457 { "200,000", "tv\\u00e5hundra\\u00adtusen" },
1458 { "201,000", "tv\\u00e5hundra\\u00aden\\u00adtusen" },
1459 { "200,200", "tv\\u00e5hundra\\u00adtusen tv\\u00e5hundra" },
1460 { "2,002,000", "tv\\u00e5 miljoner tv\\u00e5\\u00adtusen" },
1461 { "12,345,678", "tolv miljoner trehundra\\u00adfyrtiofem\\u00adtusen sexhundra\\u00adsjuttio\\u00e5tta" },
1462 { "123,456.789", "etthundra\\u00adtjugotre\\u00adtusen fyrahundra\\u00adfemtiosex komma sju \\u00e5tta nio" },
1463 { "-12,345.678", "minus tolv\\u00adtusen trehundra\\u00adfyrtiofem komma sex sju \\u00e5tta" },
1464 { NULL, NULL }
1465 };
1466 doTest(formatter, testDataDefault, TRUE);
1467
1468 static const char* testDataNeutrum[][2] = {
1469 { "101", "etthundra\\u00adett" },
1470 { "1,001", "ettusen ett" },
1471 { "1,101", "ettusen etthundra\\u00adett" },
1472 { "10,001", "tio\\u00adtusen ett" },
1473 { "21,001", "tjugoen\\u00adtusen ett" },
1474 { NULL, NULL }
1475 };
1476
1477 formatter->setDefaultRuleSet("%neutrum", status);
1478 if (U_SUCCESS(status)) {
1479 logln("testing neutrum rules");
1480 doTest(formatter, testDataNeutrum, TRUE);
1481 }
1482 else {
1483 errln("Can't test neutrum rules");
1484 }
1485
1486 static const char* testDataYear[][2] = {
1487 { "101", "etthundra\\u00adett" },
1488 { "900", "niohundra" },
1489 { "1,001", "tiohundra\\u00adett" },
1490 { "1,100", "elvahundra" },
1491 { "1,101", "elvahundra\\u00adett" },
1492 { "1,234", "tolvhundra\\u00adtrettiofyra" },
1493 { "2,001", "tjugohundra\\u00adett" },
1494 { "10,001", "tio\\u00adtusen ett" },
1495 { NULL, NULL }
1496 };
1497
1498 formatter->setDefaultRuleSet("%year", status);
1499 if (U_SUCCESS(status)) {
1500 logln("testing year rules");
1501 doTest(formatter, testDataYear, TRUE);
1502 }
1503 else {
1504 errln("Can't test year rules");
1505 }
1506
1507 }
1508 delete formatter;
1509 }
1510
1511 void
1512 IntlTestRBNF::TestSmallValues()
1513 {
1514 UErrorCode status = U_ZERO_ERROR;
1515 RuleBasedNumberFormat* formatter
1516 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("en_US"), status);
1517
1518 if (U_FAILURE(status)) {
1519 errln("FAIL: could not construct formatter");
1520 } else {
1521 static const char* testDataDefault[][2] = {
1522 { "0.001", "zero point zero zero one" },
1523 { "0.0001", "zero point zero zero zero one" },
1524 { "0.00001", "zero point zero zero zero zero one" },
1525 { "0.000001", "zero point zero zero zero zero zero one" },
1526 { "0.0000001", "zero point zero zero zero zero zero zero one" },
1527 { "0.00000001", "zero point zero zero zero zero zero zero zero one" },
1528 { "0.000000001", "zero point zero zero zero zero zero zero zero zero one" },
1529 { "0.0000000001", "zero point zero zero zero zero zero zero zero zero zero one" },
1530 { "0.00000000001", "zero point zero zero zero zero zero zero zero zero zero zero one" },
1531 { "0.000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero one" },
1532 { "0.0000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero one" },
1533 { "0.00000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
1534 { "0.000000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
1535 { "10,000,000.001", "ten million point zero zero one" },
1536 { "10,000,000.0001", "ten million point zero zero zero one" },
1537 { "10,000,000.00001", "ten million point zero zero zero zero one" },
1538 { "10,000,000.000001", "ten million point zero zero zero zero zero one" },
1539 { "10,000,000.0000001", "ten million point zero zero zero zero zero zero one" },
1540 // { "10,000,000.00000001", "ten million point zero zero zero zero zero zero zero one" },
1541 // { "10,000,000.000000002", "ten million point zero zero zero zero zero zero zero zero two" },
1542 { "10,000,000", "ten million" },
1543 // { "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" },
1544 // { "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" },
1545 // { "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" },
1546 { "1,234,567.7654321", "one million, two hundred and thirty-four thousand, five hundred and sixty-seven point seven six five four three two one" },
1547 { "123,456.654321", "one hundred and twenty-three thousand, four hundred and fifty-six point six five four three two one" },
1548 { "12,345.54321", "twelve thousand three hundred and forty-five point five four three two one" },
1549 { "1,234.4321", "one thousand two hundred and thirty-four point four three two one" },
1550 { "123.321", "one hundred and twenty-three point three two one" },
1551 { "0.0000000011754944", "zero point zero zero zero zero zero zero zero zero one one seven five four nine four four" },
1552 { "0.000001175494351", "zero point zero zero zero zero zero one one seven five four nine four three five one" },
1553 { NULL, NULL }
1554 };
1555
1556 doTest(formatter, testDataDefault, TRUE);
1557
1558 delete formatter;
1559 }
1560 }
1561
1562 void
1563 IntlTestRBNF::TestLocalizations(void)
1564 {
1565 int i;
1566 UnicodeString rules("%main:0:no;1:some;100:a lot;1000:tons;\n"
1567 "%other:0:nada;1:yah, some;100:plenty;1000:more'n you'll ever need");
1568
1569 UErrorCode status = U_ZERO_ERROR;
1570 UParseError perror;
1571 RuleBasedNumberFormat formatter(rules, perror, status);
1572 if (U_FAILURE(status)) {
1573 errln("FAIL: could not construct formatter");
1574 } else {
1575 {
1576 static const char* testData[][2] = {
1577 { "0", "nada" },
1578 { "5", "yah, some" },
1579 { "423", "plenty" },
1580 { "12345", "more'n you'll ever need" },
1581 { NULL, NULL }
1582 };
1583 doTest(&formatter, testData, FALSE);
1584 }
1585
1586 {
1587 UnicodeString loc("<<%main, %other>,<en, Main, Other>,<fr, leMain, leOther>,<de, 'das Main', 'etwas anderes'>>");
1588 static const char* testData[][2] = {
1589 { "0", "no" },
1590 { "5", "some" },
1591 { "423", "a lot" },
1592 { "12345", "tons" },
1593 { NULL, NULL }
1594 };
1595 RuleBasedNumberFormat formatter0(rules, loc, perror, status);
1596 if (U_FAILURE(status)) {
1597 errln("failed to build second formatter");
1598 } else {
1599 doTest(&formatter0, testData, FALSE);
1600
1601 {
1602 // exercise localization info
1603 Locale locale0("en__VALLEY@turkey=gobblegobble");
1604 Locale locale1("de_DE_FOO");
1605 Locale locale2("ja_JP");
1606 UnicodeString name = formatter0.getRuleSetName(0);
1607 if ( formatter0.getRuleSetDisplayName(0, locale0) == "Main"
1608 && formatter0.getRuleSetDisplayName(0, locale1) == "das Main"
1609 && formatter0.getRuleSetDisplayName(0, locale2) == "%main"
1610 && formatter0.getRuleSetDisplayName(name, locale0) == "Main"
1611 && formatter0.getRuleSetDisplayName(name, locale1) == "das Main"
1612 && formatter0.getRuleSetDisplayName(name, locale2) == "%main"){
1613 logln("getRuleSetDisplayName tested");
1614 }else {
1615 errln("failed to getRuleSetDisplayName");
1616 }
1617 }
1618
1619 for (i = 0; i < formatter0.getNumberOfRuleSetDisplayNameLocales(); ++i) {
1620 Locale locale = formatter0.getRuleSetDisplayNameLocale(i, status);
1621 if (U_SUCCESS(status)) {
1622 for (int j = 0; j < formatter0.getNumberOfRuleSetNames(); ++j) {
1623 UnicodeString name = formatter0.getRuleSetName(j);
1624 UnicodeString lname = formatter0.getRuleSetDisplayName(j, locale);
1625 UnicodeString msg = locale.getName();
1626 msg.append(": ");
1627 msg.append(name);
1628 msg.append(" = ");
1629 msg.append(lname);
1630 logln(msg);
1631 }
1632 }
1633 }
1634 }
1635 }
1636
1637 {
1638 static const char* goodLocs[] = {
1639 "", // zero-length ok, same as providing no localization data
1640 "<<>>", // no public rule sets ok
1641 "<<%main>>", // no localizations ok
1642 "<<%main,>,<en, Main,>>", // comma before close angle ok
1643 "<<%main>,<en, ',<>\" '>>", // quotes everything until next quote
1644 "<<%main>,<'en', \"it's ok\">>", // double quotes work too
1645 " \n <\n <\n %main\n >\n , \t <\t en\t , \tfoo \t\t > \n\n > \n ", // rule whitespace ok
1646 };
1647 int32_t goodLocsLen = sizeof(goodLocs)/sizeof(goodLocs[0]);
1648
1649 static const char* badLocs[] = {
1650 " ", // non-zero length
1651 "<>", // empty array
1652 "<", // unclosed outer array
1653 "<<", // unclosed inner array
1654 "<<,>>", // unexpected comma
1655 "<<''>>", // empty string
1656 " x<<%main>>", // first non space char not open angle bracket
1657 "<%main>", // missing inner array
1658 "<<%main %other>>", // elements missing separating commma (spaces must be quoted)
1659 "<<%main><en, Main>>", // arrays missing separating comma
1660 "<<%main>,<en, main, foo>>", // too many elements in locale data
1661 "<<%main>,<en>>", // too few elements in locale data
1662 "<<<%main>>>", // unexpected open angle
1663 "<<%main<>>>", // unexpected open angle
1664 "<<%main, %other>,<en,,>>", // implicit empty strings
1665 "<<%main>,<en,''>>", // empty string
1666 "<<%main>, < en, '>>", // unterminated quote
1667 "<<%main>, < en, \"<>>", // unterminated quote
1668 "<<%main\">>", // quote in string
1669 "<<%main'>>", // quote in string
1670 "<<%main<>>", // open angle in string
1671 "<<%main>> x", // extra non-space text at end
1672
1673 };
1674 int32_t badLocsLen = sizeof(badLocs)/sizeof(badLocs[0]);
1675
1676 for (i = 0; i < goodLocsLen; ++i) {
1677 logln("[%d] '%s'", i, goodLocs[i]);
1678 UErrorCode status = U_ZERO_ERROR;
1679 UnicodeString loc(goodLocs[i]);
1680 RuleBasedNumberFormat fmt(rules, loc, perror, status);
1681 if (U_FAILURE(status)) {
1682 errln("Failed parse of good localization string: '%s'", goodLocs[i]);
1683 }
1684 }
1685
1686 for (i = 0; i < badLocsLen; ++i) {
1687 logln("[%d] '%s'", i, badLocs[i]);
1688 UErrorCode status = U_ZERO_ERROR;
1689 UnicodeString loc(badLocs[i]);
1690 RuleBasedNumberFormat fmt(rules, loc, perror, status);
1691 if (U_SUCCESS(status)) {
1692 errln("Successful parse of bad localization string: '%s'", badLocs[i]);
1693 }
1694 }
1695 }
1696 }
1697 }
1698
1699 void
1700 IntlTestRBNF::TestAllLocales()
1701 {
1702 const char* names[] = {
1703 " (spellout) ",
1704 " (ordinal) ",
1705 " (duration) "
1706 };
1707 int32_t count = 0;
1708 const Locale* locales = Locale::getAvailableLocales(count);
1709 for (int i = 0; i < count; ++i) {
1710 const Locale* loc = &locales[i];
1711 for (int j = 0; j < 3; ++j) {
1712 UErrorCode status = U_ZERO_ERROR;
1713 RuleBasedNumberFormat* f = new RuleBasedNumberFormat((URBNFRuleSetTag)j, *loc, status);
1714 if (U_SUCCESS(status)) {
1715 double n = 45.678;
1716 UnicodeString str;
1717 f->format(n, str);
1718 delete f;
1719
1720 logln(UnicodeString(loc->getName()) + UnicodeString(names[j])
1721 + UnicodeString("success: 45.678 -> ") + str);
1722 } else {
1723 errln(UnicodeString(loc->getName()) + UnicodeString(names[j])
1724 + UnicodeString("ERROR could not instantiate -> ") + UnicodeString(u_errorName(status)));
1725 }
1726 }
1727 }
1728 }
1729
1730 void
1731 IntlTestRBNF::doTest(RuleBasedNumberFormat* formatter, const char* testData[][2], UBool testParsing)
1732 {
1733 // man, error reporting would be easier with printf-style syntax for unicode string and formattable
1734
1735 UErrorCode status = U_ZERO_ERROR;
1736 DecimalFormatSymbols dfs("en", status);
1737 // NumberFormat* decFmt = NumberFormat::createInstance(Locale::getUS(), status);
1738 DecimalFormat decFmt("#,###.################", dfs, status);
1739 if (U_FAILURE(status)) {
1740 errln("FAIL: could not create NumberFormat");
1741 } else {
1742 for (int i = 0; testData[i][0]; ++i) {
1743 const char* numString = testData[i][0];
1744 const char* expectedWords = testData[i][1];
1745
1746 log("[%i] %s = ", i, numString);
1747 Formattable expectedNumber;
1748 decFmt.parse(numString, expectedNumber, status);
1749 if (U_FAILURE(status)) {
1750 errln("FAIL: decFmt could not parse %s", numString);
1751 break;
1752 } else {
1753 UnicodeString actualString;
1754 FieldPosition pos;
1755 formatter->format(expectedNumber, actualString/* , pos*/, status);
1756 if (U_FAILURE(status)) {
1757 UnicodeString msg = "Fail: formatter could not format ";
1758 decFmt.format(expectedNumber, msg, status);
1759 errln(msg);
1760 break;
1761 } else {
1762 UnicodeString expectedString = UnicodeString(expectedWords).unescape();
1763 if (actualString != expectedString) {
1764 UnicodeString msg = "FAIL: check failed for ";
1765 decFmt.format(expectedNumber, msg, status);
1766 msg.append(", expected ");
1767 msg.append(expectedString);
1768 msg.append(" but got ");
1769 msg.append(actualString);
1770 errln(msg);
1771 break;
1772 } else {
1773 logln(actualString);
1774 if (testParsing) {
1775 Formattable parsedNumber;
1776 formatter->parse(actualString, parsedNumber, status);
1777 if (U_FAILURE(status)) {
1778 UnicodeString msg = "FAIL: formatter could not parse ";
1779 msg.append(actualString);
1780 msg.append(" status code: " );
1781 msg.append(u_errorName(status));
1782 errln(msg);
1783 break;
1784 } else {
1785 if (parsedNumber != expectedNumber) {
1786 UnicodeString msg = "FAIL: parse failed for ";
1787 msg.append(actualString);
1788 msg.append(", expected ");
1789 decFmt.format(expectedNumber, msg, status);
1790 msg.append(", but got ");
1791 decFmt.format(parsedNumber, msg, status);
1792 errln(msg);
1793 break;
1794 }
1795 }
1796 }
1797 }
1798 }
1799 }
1800 }
1801 }
1802 }
1803
1804 void
1805 IntlTestRBNF::doLenientParseTest(RuleBasedNumberFormat* formatter, const char* testData[][2])
1806 {
1807 UErrorCode status = U_ZERO_ERROR;
1808 NumberFormat* decFmt = NumberFormat::createInstance(Locale::getUS(), status);
1809 if (U_FAILURE(status)) {
1810 errln("FAIL: could not create NumberFormat");
1811 } else {
1812 for (int i = 0; testData[i][0]; ++i) {
1813 const char* spelledNumber = testData[i][0]; // spelled-out number
1814 const char* asciiUSNumber = testData[i][1]; // number as ascii digits formatted for US locale
1815
1816 UnicodeString spelledNumberString = UnicodeString(spelledNumber).unescape();
1817 Formattable actualNumber;
1818 formatter->parse(spelledNumberString, actualNumber, status);
1819 if (U_FAILURE(status)) {
1820 UnicodeString msg = "FAIL: formatter could not parse ";
1821 msg.append(spelledNumberString);
1822 errln(msg);
1823 break;
1824 } else {
1825 // I changed the logic of this test somewhat from Java-- instead of comparing the
1826 // strings, I compare the Formattables. Hmmm, but the Formattables don't compare,
1827 // so change it back.
1828
1829 UnicodeString asciiUSNumberString = asciiUSNumber;
1830 Formattable expectedNumber;
1831 decFmt->parse(asciiUSNumberString, expectedNumber, status);
1832 if (U_FAILURE(status)) {
1833 UnicodeString msg = "FAIL: decFmt could not parse ";
1834 msg.append(asciiUSNumberString);
1835 errln(msg);
1836 break;
1837 } else {
1838 UnicodeString actualNumberString;
1839 UnicodeString expectedNumberString;
1840 decFmt->format(actualNumber, actualNumberString, status);
1841 decFmt->format(expectedNumber, expectedNumberString, status);
1842 if (actualNumberString != expectedNumberString) {
1843 UnicodeString msg = "FAIL: parsing";
1844 msg.append(asciiUSNumberString);
1845 msg.append("\n");
1846 msg.append(" lenient parse failed for ");
1847 msg.append(spelledNumberString);
1848 msg.append(", expected ");
1849 msg.append(expectedNumberString);
1850 msg.append(", but got ");
1851 msg.append(actualNumberString);
1852 errln(msg);
1853 break;
1854 }
1855 }
1856 }
1857 }
1858 delete decFmt;
1859 }
1860 }
1861
1862 /* U_HAVE_RBNF */
1863 #else
1864
1865 void
1866 IntlTestRBNF::TestRBNFDisabled() {
1867 errln("*** RBNF currently disabled on this platform ***\n");
1868 }
1869
1870 /* U_HAVE_RBNF */
1871 #endif
1872
1873 #endif /* #if !UCONFIG_NO_FORMATTING */