]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/intltest/dcfmapts.cpp
ICU-551.51.4.tar.gz
[apple/icu.git] / icuSources / test / intltest / dcfmapts.cpp
CommitLineData
b75a7d8f 1/********************************************************************
57a6839d
A
2 * COPYRIGHT:
3 * Copyright (c) 1997-2014, International Business Machines Corporation and
b75a7d8f
A
4 * others. All Rights Reserved.
5 ********************************************************************/
6
7#include "unicode/utypes.h"
8
9#if !UCONFIG_NO_FORMATTING
10
11#include "dcfmapts.h"
12
57a6839d 13#include "unicode/currpinf.h"
b75a7d8f 14#include "unicode/dcfmtsym.h"
57a6839d
A
15#include "unicode/decimfmt.h"
16#include "unicode/fmtable.h"
17#include "unicode/localpointer.h"
b75a7d8f 18#include "unicode/parseerr.h"
57a6839d
A
19#include "unicode/stringpiece.h"
20
21#include "putilimp.h"
22#include "plurrule_impl.h"
23#include <stdio.h>
24
b75a7d8f
A
25// This is an API test, not a unit test. It doesn't test very many cases, and doesn't
26// try to test the full functionality. It just calls each function in the class and
27// verifies that it works on a basic level.
28
29void IntlTestDecimalFormatAPI::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
30{
31 if (exec) logln((UnicodeString)"TestSuite DecimalFormatAPI");
32 switch (index) {
57a6839d 33 case 0: name = "DecimalFormat API test";
b75a7d8f
A
34 if (exec) {
35 logln((UnicodeString)"DecimalFormat API test---"); logln((UnicodeString)"");
36 UErrorCode status = U_ZERO_ERROR;
73c04bcf 37 Locale saveLocale;
b75a7d8f
A
38 Locale::setDefault(Locale::getEnglish(), status);
39 if(U_FAILURE(status)) {
40 errln((UnicodeString)"ERROR: Could not set default locale, test may not give correct results");
41 }
42 testAPI(/*par*/);
73c04bcf 43 Locale::setDefault(saveLocale, status);
b75a7d8f
A
44 }
45 break;
46 case 1: name = "Rounding test";
47 if(exec) {
48 logln((UnicodeString)"DecimalFormat Rounding test---");
49 testRounding(/*par*/);
50 }
51 break;
729e4ab9
A
52 case 2: name = "Test6354";
53 if(exec) {
54 logln((UnicodeString)"DecimalFormat Rounding Increment test---");
55 testRoundingInc(/*par*/);
56 }
57 break;
58 case 3: name = "TestCurrencyPluralInfo";
59 if(exec) {
60 logln((UnicodeString)"CurrencyPluralInfo API test---");
61 TestCurrencyPluralInfo();
62 }
63 break;
51004dcb
A
64 case 4: name = "TestScale";
65 if(exec) {
66 logln((UnicodeString)"Scale test---");
67 TestScale();
68 }
69 break;
57a6839d
A
70 case 5: name = "TestFixedDecimal";
71 if(exec) {
72 logln((UnicodeString)"TestFixedDecimal ---");
73 TestFixedDecimal();
74 }
75 break;
76 case 6: name = "TestBadFastpath";
77 if(exec) {
78 logln((UnicodeString)"TestBadFastpath ---");
79 TestBadFastpath();
80 }
81 break;
b331163b
A
82 case 7: name = "TestRequiredDecimalPoint";
83 if(exec) {
84 logln((UnicodeString)"TestRequiredDecimalPoint ---");
85 TestRequiredDecimalPoint();
86 }
87 break;
57a6839d 88 default: name = ""; break;
b75a7d8f
A
89 }
90}
91
92/**
93 * This test checks various generic API methods in DecimalFormat to achieve 100%
94 * API coverage.
95 */
96void IntlTestDecimalFormatAPI::testAPI(/*char *par*/)
97{
98 UErrorCode status = U_ZERO_ERROR;
99
100// ======= Test constructors
101
102 logln((UnicodeString)"Testing DecimalFormat constructors");
103
104 DecimalFormat def(status);
105 if(U_FAILURE(status)) {
729e4ab9 106 errcheckln(status, "ERROR: Could not create DecimalFormat (default) - %s", u_errorName(status));
b75a7d8f
A
107 return;
108 }
109
08b89b0a
A
110 // bug 10864
111 status = U_ZERO_ERROR;
112 DecimalFormat noGrouping("###0.##", status);
113 if (noGrouping.getGroupingSize() != 0) {
114 errln("Grouping size should be 0 for no grouping.");
115 }
116 // end bug 10864
117
b75a7d8f
A
118 status = U_ZERO_ERROR;
119 const UnicodeString pattern("#,##0.# FF");
120 DecimalFormat pat(pattern, status);
121 if(U_FAILURE(status)) {
122 errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern)");
123 return;
124 }
125
126 status = U_ZERO_ERROR;
127 DecimalFormatSymbols *symbols = new DecimalFormatSymbols(Locale::getFrench(), status);
128 if(U_FAILURE(status)) {
129 errln((UnicodeString)"ERROR: Could not create DecimalFormatSymbols (French)");
130 return;
131 }
132
133 status = U_ZERO_ERROR;
134 DecimalFormat cust1(pattern, symbols, status);
135 if(U_FAILURE(status)) {
136 errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols*)");
137 }
138
139 status = U_ZERO_ERROR;
140 DecimalFormat cust2(pattern, *symbols, status);
141 if(U_FAILURE(status)) {
142 errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols)");
143 }
144
145 DecimalFormat copy(pat);
146
147// ======= Test clone(), assignment, and equality
148
149 logln((UnicodeString)"Testing clone(), assignment and equality operators");
150
151 if( ! (copy == pat) || copy != pat) {
152 errln((UnicodeString)"ERROR: Copy constructor or == failed");
153 }
154
155 copy = cust1;
156 if(copy != cust1) {
157 errln((UnicodeString)"ERROR: Assignment (or !=) failed");
158 }
159
160 Format *clone = def.clone();
161 if( ! (*clone == def) ) {
162 errln((UnicodeString)"ERROR: Clone() failed");
163 }
164 delete clone;
165
166// ======= Test various format() methods
167
168 logln((UnicodeString)"Testing various format() methods");
169
170 double d = -10456.0037;
171 int32_t l = 100000000;
172 Formattable fD(d);
173 Formattable fL(l);
174
175 UnicodeString res1, res2, res3, res4;
176 FieldPosition pos1(0), pos2(0), pos3(0), pos4(0);
57a6839d 177
b75a7d8f
A
178 res1 = def.format(d, res1, pos1);
179 logln( (UnicodeString) "" + (int32_t) d + " formatted to " + res1);
180
181 res2 = pat.format(l, res2, pos2);
182 logln((UnicodeString) "" + (int32_t) l + " formatted to " + res2);
183
184 status = U_ZERO_ERROR;
185 res3 = cust1.format(fD, res3, pos3, status);
186 if(U_FAILURE(status)) {
187 errln((UnicodeString)"ERROR: format(Formattable [double]) failed");
188 }
189 logln((UnicodeString) "" + (int32_t) fD.getDouble() + " formatted to " + res3);
190
191 status = U_ZERO_ERROR;
192 res4 = cust2.format(fL, res4, pos4, status);
193 if(U_FAILURE(status)) {
194 errln((UnicodeString)"ERROR: format(Formattable [long]) failed");
195 }
196 logln((UnicodeString) "" + fL.getLong() + " formatted to " + res4);
197
198// ======= Test parse()
199
200 logln((UnicodeString)"Testing parse()");
201
202 UnicodeString text("-10,456.0037");
203 Formattable result1, result2;
204 ParsePosition pos(0);
205 UnicodeString patt("#,##0.#");
206 status = U_ZERO_ERROR;
207 pat.applyPattern(patt, status);
208 if(U_FAILURE(status)) {
209 errln((UnicodeString)"ERROR: applyPattern() failed");
210 }
211 pat.parse(text, result1, pos);
212 if(result1.getType() != Formattable::kDouble && result1.getDouble() != d) {
213 errln((UnicodeString)"ERROR: Roundtrip failed (via parse()) for " + text);
214 }
215 logln(text + " parsed into " + (int32_t) result1.getDouble());
216
217 status = U_ZERO_ERROR;
218 pat.parse(text, result2, status);
219 if(U_FAILURE(status)) {
220 errln((UnicodeString)"ERROR: parse() failed");
221 }
222 if(result2.getType() != Formattable::kDouble && result2.getDouble() != d) {
223 errln((UnicodeString)"ERROR: Roundtrip failed (via parse()) for " + text);
224 }
225 logln(text + " parsed into " + (int32_t) result2.getDouble());
226
227// ======= Test getters and setters
228
229 logln((UnicodeString)"Testing getters and setters");
230
231 const DecimalFormatSymbols *syms = pat.getDecimalFormatSymbols();
232 DecimalFormatSymbols *newSyms = new DecimalFormatSymbols(*syms);
233 def.setDecimalFormatSymbols(*newSyms);
234 def.adoptDecimalFormatSymbols(newSyms); // don't use newSyms after this
235 if( *(pat.getDecimalFormatSymbols()) != *(def.getDecimalFormatSymbols())) {
236 errln((UnicodeString)"ERROR: adopt or set DecimalFormatSymbols() failed");
237 }
238
239 UnicodeString posPrefix;
240 pat.setPositivePrefix("+");
241 posPrefix = pat.getPositivePrefix(posPrefix);
242 logln((UnicodeString)"Positive prefix (should be +): " + posPrefix);
243 if(posPrefix != "+") {
244 errln((UnicodeString)"ERROR: setPositivePrefix() failed");
245 }
246
247 UnicodeString negPrefix;
248 pat.setNegativePrefix("-");
249 negPrefix = pat.getNegativePrefix(negPrefix);
250 logln((UnicodeString)"Negative prefix (should be -): " + negPrefix);
251 if(negPrefix != "-") {
252 errln((UnicodeString)"ERROR: setNegativePrefix() failed");
253 }
254
255 UnicodeString posSuffix;
256 pat.setPositiveSuffix("_");
257 posSuffix = pat.getPositiveSuffix(posSuffix);
258 logln((UnicodeString)"Positive suffix (should be _): " + posSuffix);
259 if(posSuffix != "_") {
260 errln((UnicodeString)"ERROR: setPositiveSuffix() failed");
261 }
262
263 UnicodeString negSuffix;
264 pat.setNegativeSuffix("~");
265 negSuffix = pat.getNegativeSuffix(negSuffix);
266 logln((UnicodeString)"Negative suffix (should be ~): " + negSuffix);
267 if(negSuffix != "~") {
268 errln((UnicodeString)"ERROR: setNegativeSuffix() failed");
269 }
270
271 int32_t multiplier = 0;
272 pat.setMultiplier(8);
273 multiplier = pat.getMultiplier();
274 logln((UnicodeString)"Multiplier (should be 8): " + multiplier);
275 if(multiplier != 8) {
276 errln((UnicodeString)"ERROR: setMultiplier() failed");
277 }
278
279 int32_t groupingSize = 0;
280 pat.setGroupingSize(2);
281 groupingSize = pat.getGroupingSize();
282 logln((UnicodeString)"Grouping size (should be 2): " + (int32_t) groupingSize);
283 if(groupingSize != 2) {
284 errln((UnicodeString)"ERROR: setGroupingSize() failed");
285 }
286
287 pat.setDecimalSeparatorAlwaysShown(TRUE);
288 UBool tf = pat.isDecimalSeparatorAlwaysShown();
289 logln((UnicodeString)"DecimalSeparatorIsAlwaysShown (should be TRUE) is " + (UnicodeString) (tf ? "TRUE" : "FALSE"));
290 if(tf != TRUE) {
291 errln((UnicodeString)"ERROR: setDecimalSeparatorAlwaysShown() failed");
292 }
293 // Added by Ken Liu testing set/isExponentSignAlwaysShown
294 pat.setExponentSignAlwaysShown(TRUE);
295 UBool esas = pat.isExponentSignAlwaysShown();
296 logln((UnicodeString)"ExponentSignAlwaysShown (should be TRUE) is " + (UnicodeString) (esas ? "TRUE" : "FALSE"));
297 if(esas != TRUE) {
298 errln((UnicodeString)"ERROR: ExponentSignAlwaysShown() failed");
299 }
300
301 // Added by Ken Liu testing set/isScientificNotation
302 pat.setScientificNotation(TRUE);
303 UBool sn = pat.isScientificNotation();
304 logln((UnicodeString)"isScientificNotation (should be TRUE) is " + (UnicodeString) (sn ? "TRUE" : "FALSE"));
305 if(sn != TRUE) {
306 errln((UnicodeString)"ERROR: setScientificNotation() failed");
307 }
57a6839d 308
b75a7d8f
A
309 // Added by Ken Liu testing set/getMinimumExponentDigits
310 int8_t MinimumExponentDigits = 0;
311 pat.setMinimumExponentDigits(2);
312 MinimumExponentDigits = pat.getMinimumExponentDigits();
313 logln((UnicodeString)"MinimumExponentDigits (should be 2) is " + (int8_t) MinimumExponentDigits);
314 if(MinimumExponentDigits != 2) {
315 errln((UnicodeString)"ERROR: setMinimumExponentDigits() failed");
316 }
317
318 // Added by Ken Liu testing set/getRoundingIncrement
319 double RoundingIncrement = 0.0;
320 pat.setRoundingIncrement(2.0);
321 RoundingIncrement = pat.getRoundingIncrement();
322 logln((UnicodeString)"RoundingIncrement (should be 2.0) is " + (double) RoundingIncrement);
323 if(RoundingIncrement != 2.0) {
324 errln((UnicodeString)"ERROR: setRoundingIncrement() failed");
325 }
326 //end of Ken's Adding
327
328 UnicodeString funkyPat;
329 funkyPat = pat.toPattern(funkyPat);
330 logln((UnicodeString)"Pattern is " + funkyPat);
331
332 UnicodeString locPat;
333 locPat = pat.toLocalizedPattern(locPat);
334 logln((UnicodeString)"Localized pattern is " + locPat);
335
336// ======= Test applyPattern()
337
338 logln((UnicodeString)"Testing applyPattern()");
339
340 UnicodeString p1("#,##0.0#;(#,##0.0#)");
341 logln((UnicodeString)"Applying pattern " + p1);
342 status = U_ZERO_ERROR;
343 pat.applyPattern(p1, status);
344 if(U_FAILURE(status)) {
345 errln((UnicodeString)"ERROR: applyPattern() failed with " + (int32_t) status);
346 }
347 UnicodeString s2;
348 s2 = pat.toPattern(s2);
349 logln((UnicodeString)"Extracted pattern is " + s2);
350 if(s2 != p1) {
351 errln((UnicodeString)"ERROR: toPattern() result did not match pattern applied");
352 }
353
354 if(pat.getSecondaryGroupingSize() != 0) {
355 errln("FAIL: Secondary Grouping Size should be 0, not %d\n", pat.getSecondaryGroupingSize());
356 }
357
358 if(pat.getGroupingSize() != 3) {
359 errln("FAIL: Primary Grouping Size should be 3, not %d\n", pat.getGroupingSize());
360 }
361
362 UnicodeString p2("#,##,##0.0# FF;(#,##,##0.0# FF)");
363 logln((UnicodeString)"Applying pattern " + p2);
364 status = U_ZERO_ERROR;
365 pat.applyLocalizedPattern(p2, status);
366 if(U_FAILURE(status)) {
367 errln((UnicodeString)"ERROR: applyPattern() failed with " + (int32_t) status);
368 }
369 UnicodeString s3;
370 s3 = pat.toLocalizedPattern(s3);
371 logln((UnicodeString)"Extracted pattern is " + s3);
372 if(s3 != p2) {
373 errln((UnicodeString)"ERROR: toLocalizedPattern() result did not match pattern applied");
374 }
375
376 status = U_ZERO_ERROR;
377 UParseError pe;
378 pat.applyLocalizedPattern(p2, pe, status);
379 if(U_FAILURE(status)) {
380 errln((UnicodeString)"ERROR: applyPattern((with ParseError)) failed with " + (int32_t) status);
381 }
382 UnicodeString s4;
383 s4 = pat.toLocalizedPattern(s3);
384 logln((UnicodeString)"Extracted pattern is " + s4);
385 if(s4 != p2) {
386 errln((UnicodeString)"ERROR: toLocalizedPattern(with ParseErr) result did not match pattern applied");
387 }
388
389 if(pat.getSecondaryGroupingSize() != 2) {
390 errln("FAIL: Secondary Grouping Size should be 2, not %d\n", pat.getSecondaryGroupingSize());
391 }
392
393 if(pat.getGroupingSize() != 3) {
394 errln("FAIL: Primary Grouping Size should be 3, not %d\n", pat.getGroupingSize());
395 }
396
397// ======= Test getStaticClassID()
398
399 logln((UnicodeString)"Testing getStaticClassID()");
400
401 status = U_ZERO_ERROR;
402 NumberFormat *test = new DecimalFormat(status);
403 if(U_FAILURE(status)) {
404 errln((UnicodeString)"ERROR: Couldn't create a DecimalFormat");
405 }
406
407 if(test->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
408 errln((UnicodeString)"ERROR: getDynamicClassID() didn't return the expected value");
409 }
410
411 delete test;
412}
413
729e4ab9
A
414void IntlTestDecimalFormatAPI::TestCurrencyPluralInfo(){
415 UErrorCode status = U_ZERO_ERROR;
416
417 CurrencyPluralInfo *cpi = new CurrencyPluralInfo(status);
418 if(U_FAILURE(status)) {
419 errln((UnicodeString)"ERROR: CurrencyPluralInfo(UErrorCode) could not be created");
420 }
421
422 CurrencyPluralInfo cpi1 = *cpi;
423
424 if(cpi->getDynamicClassID() != CurrencyPluralInfo::getStaticClassID()){
425 errln((UnicodeString)"ERROR: CurrencyPluralInfo::getDynamicClassID() didn't return the expected value");
426 }
427
428 cpi->setCurrencyPluralPattern("","",status);
429 if(U_FAILURE(status)) {
430 errln((UnicodeString)"ERROR: CurrencyPluralInfo::setCurrencyPluralPattern");
431 }
432
433 cpi->setLocale(Locale::getCanada(), status);
434 if(U_FAILURE(status)) {
435 errln((UnicodeString)"ERROR: CurrencyPluralInfo::setLocale");
436 }
57a6839d 437
729e4ab9
A
438 cpi->setPluralRules("",status);
439 if(U_FAILURE(status)) {
440 errln((UnicodeString)"ERROR: CurrencyPluralInfo::setPluralRules");
441 }
442
443 DecimalFormat *df = new DecimalFormat(status);
444 if(U_FAILURE(status)) {
445 errcheckln(status, "ERROR: Could not create DecimalFormat - %s", u_errorName(status));
446 }
447
448 df->adoptCurrencyPluralInfo(cpi);
449
450 df->getCurrencyPluralInfo();
451
452 df->setCurrencyPluralInfo(cpi1);
453
454 delete df;
455}
456
b75a7d8f
A
457void IntlTestDecimalFormatAPI::testRounding(/*char *par*/)
458{
459 UErrorCode status = U_ZERO_ERROR;
460 double Roundingnumber = 2.55;
461 double Roundingnumber1 = -2.55;
462 //+2.55 results -2.55 results
463 double result[]={ 3.0, -2.0, // kRoundCeiling 0,
464 2.0, -3.0, // kRoundFloor 1,
465 2.0, -2.0, // kRoundDown 2,
466 3.0, -3.0, // kRoundUp 3,
467 3.0, -3.0, // kRoundHalfEven 4,
468 3.0, -3.0, // kRoundHalfDown 5,
57a6839d 469 3.0, -3.0 // kRoundHalfUp 6
b75a7d8f
A
470 };
471 DecimalFormat pat(status);
472 if(U_FAILURE(status)) {
729e4ab9 473 errcheckln(status, "ERROR: Could not create DecimalFormat (default) - %s", u_errorName(status));
b75a7d8f
A
474 return;
475 }
476 uint16_t mode;
477 uint16_t i=0;
478 UnicodeString message;
479 UnicodeString resultStr;
480 for(mode=0;mode < 7;mode++){
481 pat.setRoundingMode((DecimalFormat::ERoundingMode)mode);
482 if(pat.getRoundingMode() != (DecimalFormat::ERoundingMode)mode){
483 errln((UnicodeString)"SetRoundingMode or GetRoundingMode failed for mode=" + mode);
484 }
485
486
487 //for +2.55 with RoundingIncrement=1.0
488 pat.setRoundingIncrement(1.0);
489 pat.format(Roundingnumber, resultStr);
51004dcb 490 message= (UnicodeString)"Round() failed: round(" + (double)Roundingnumber + UnicodeString(",") + mode + UnicodeString(",FALSE) with RoundingIncrement=1.0==>");
b75a7d8f
A
491 verify(message, resultStr, result[i++]);
492 message.remove();
493 resultStr.remove();
494
495 //for -2.55 with RoundingIncrement=1.0
496 pat.format(Roundingnumber1, resultStr);
51004dcb 497 message= (UnicodeString)"Round() failed: round(" + (double)Roundingnumber1 + UnicodeString(",") + mode + UnicodeString(",FALSE) with RoundingIncrement=1.0==>");
b75a7d8f
A
498 verify(message, resultStr, result[i++]);
499 message.remove();
500 resultStr.remove();
501 }
502
503}
504void IntlTestDecimalFormatAPI::verify(const UnicodeString& message, const UnicodeString& got, double expected){
505 logln((UnicodeString)message + got + (UnicodeString)" Expected : " + expected);
506 UnicodeString expectedStr("");
507 expectedStr=expectedStr + expected;
508 if(got != expectedStr ) {
51004dcb
A
509 errln((UnicodeString)"ERROR: " + message + got + (UnicodeString)" Expected : " + expectedStr);
510 }
511}
512
513void IntlTestDecimalFormatAPI::verifyString(const UnicodeString& message, const UnicodeString& got, UnicodeString& expected){
514 logln((UnicodeString)message + got + (UnicodeString)" Expected : " + expected);
515 if(got != expected ) {
516 errln((UnicodeString)"ERROR: " + message + got + (UnicodeString)" Expected : " + expected);
b75a7d8f
A
517 }
518}
519
729e4ab9
A
520void IntlTestDecimalFormatAPI::testRoundingInc(/*char *par*/)
521{
522 UErrorCode status = U_ZERO_ERROR;
523 DecimalFormat pat(UnicodeString("#,##0.00"),status);
524 if(U_FAILURE(status)) {
525 errcheckln(status, "ERROR: Could not create DecimalFormat (default) - %s", u_errorName(status));
526 return;
527 }
528
529 // get default rounding increment
530 double roundingInc = pat.getRoundingIncrement();
531 if (roundingInc != 0.0) {
532 errln((UnicodeString)"ERROR: Rounding increment not zero");
533 return;
534 }
535
57a6839d 536 // With rounding now being handled by decNumber, we no longer
729e4ab9
A
537 // set a rounding increment to enable non-default mode rounding,
538 // checking of which was the original point of this test.
539
57a6839d 540 // set rounding mode with zero increment. Rounding
729e4ab9
A
541 // increment should not be set by this operation
542 pat.setRoundingMode((DecimalFormat::ERoundingMode)0);
543 roundingInc = pat.getRoundingIncrement();
544 if (roundingInc != 0.0) {
545 errln((UnicodeString)"ERROR: Rounding increment not zero after setRoundingMode");
546 return;
547 }
548}
549
51004dcb
A
550void IntlTestDecimalFormatAPI::TestScale()
551{
552 typedef struct TestData {
553 double inputValue;
554 int inputScale;
57a6839d 555 const char *expectedOutput;
51004dcb
A
556 } TestData;
557
558 static TestData testData[] = {
559 { 100.0, 3, "100,000" },
560 { 10034.0, -2, "100.34" },
561 { 0.86, -3, "0.0009" },
562 { -0.000455, 1, "-0%" },
563 { -0.000555, 1, "-1%" },
564 { 0.000455, 1, "0%" },
565 { 0.000555, 1, "1%" },
566 };
567
568 UErrorCode status = U_ZERO_ERROR;
569 DecimalFormat pat(status);
570 if(U_FAILURE(status)) {
571 errcheckln(status, "ERROR: Could not create DecimalFormat (default) - %s", u_errorName(status));
572 return;
573 }
574
575 UnicodeString message;
576 UnicodeString resultStr;
577 UnicodeString exp;
578 UnicodeString percentPattern("#,##0%");
579 pat.setMaximumFractionDigits(4);
580
b331163b 581 for(int32_t i=0; i < UPRV_LENGTHOF(testData); i++) {
51004dcb
A
582 if ( i > 2 ) {
583 pat.applyPattern(percentPattern,status);
584 }
585 pat.setAttribute(UNUM_SCALE,testData[i].inputScale,status);
586 pat.format(testData[i].inputValue, resultStr);
57a6839d
A
587 message = UnicodeString("Unexpected output for ") + testData[i].inputValue + UnicodeString(" and scale ") +
588 testData[i].inputScale + UnicodeString(". Got: ");
51004dcb
A
589 exp = testData[i].expectedOutput;
590 verifyString(message, resultStr, exp);
591 message.remove();
592 resultStr.remove();
593 exp.remove();
594 }
595}
57a6839d
A
596
597
598#define ASSERT_EQUAL(expect, actual) { char tmp[200]; sprintf(tmp, "(%g==%g)", (double)(expect), (double)(actual)); \
599 assertTrue(tmp, ((expect)==(actual)), FALSE, TRUE, __FILE__, __LINE__); }
600
601void IntlTestDecimalFormatAPI::TestFixedDecimal() {
602 UErrorCode status = U_ZERO_ERROR;
603
b331163b 604 LocalPointer<DecimalFormat> df(new DecimalFormat("###", status), status);
57a6839d
A
605 TEST_ASSERT_STATUS(status);
606 FixedDecimal fd = df->getFixedDecimal(44, status);
607 TEST_ASSERT_STATUS(status);
608 ASSERT_EQUAL(44, fd.source);
609 ASSERT_EQUAL(0, fd.visibleDecimalDigitCount);
610
b331163b 611 df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.00##", status), status);
57a6839d
A
612 TEST_ASSERT_STATUS(status);
613 fd = df->getFixedDecimal(123.456, status);
614 TEST_ASSERT_STATUS(status);
615 ASSERT_EQUAL(3, fd.visibleDecimalDigitCount);
616 ASSERT_EQUAL(456, fd.decimalDigits);
617 ASSERT_EQUAL(456, fd.decimalDigitsWithoutTrailingZeros);
618 ASSERT_EQUAL(123, fd.intValue);
619 ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
620 ASSERT_EQUAL(FALSE, fd.isNegative);
621
b331163b 622 df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###", status), status);
57a6839d
A
623 TEST_ASSERT_STATUS(status);
624 fd = df->getFixedDecimal(123.456, status);
625 TEST_ASSERT_STATUS(status);
626 ASSERT_EQUAL(0, fd.visibleDecimalDigitCount);
627 ASSERT_EQUAL(0, fd.decimalDigits);
628 ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
629 ASSERT_EQUAL(123, fd.intValue);
630 ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
631 ASSERT_EQUAL(FALSE, fd.isNegative);
632
b331163b 633 df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.0", status), status);
57a6839d
A
634 TEST_ASSERT_STATUS(status);
635 fd = df->getFixedDecimal(123.01, status);
636 TEST_ASSERT_STATUS(status);
637 ASSERT_EQUAL(1, fd.visibleDecimalDigitCount);
638 ASSERT_EQUAL(0, fd.decimalDigits);
639 ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
640 ASSERT_EQUAL(123, fd.intValue);
641 ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
642 ASSERT_EQUAL(FALSE, fd.isNegative);
643
b331163b 644 df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.0", status), status);
57a6839d
A
645 TEST_ASSERT_STATUS(status);
646 fd = df->getFixedDecimal(123.06, status);
647 TEST_ASSERT_STATUS(status);
648 ASSERT_EQUAL(1, fd.visibleDecimalDigitCount);
649 ASSERT_EQUAL(1, fd.decimalDigits);
650 ASSERT_EQUAL(1, fd.decimalDigitsWithoutTrailingZeros);
651 ASSERT_EQUAL(123, fd.intValue);
652 ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
653 ASSERT_EQUAL(FALSE, fd.isNegative);
654
b331163b 655 df.adoptInsteadAndCheckErrorCode(new DecimalFormat("@@@@@", status), status); // Significant Digits
57a6839d
A
656 TEST_ASSERT_STATUS(status);
657 fd = df->getFixedDecimal(123, status);
658 TEST_ASSERT_STATUS(status);
659 ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
660 ASSERT_EQUAL(0, fd.decimalDigits);
661 ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
662 ASSERT_EQUAL(123, fd.intValue);
663 ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
664 ASSERT_EQUAL(FALSE, fd.isNegative);
665
b331163b 666 df.adoptInsteadAndCheckErrorCode(new DecimalFormat("@@@@@", status), status); // Significant Digits
57a6839d
A
667 TEST_ASSERT_STATUS(status);
668 fd = df->getFixedDecimal(1.23, status);
669 TEST_ASSERT_STATUS(status);
670 ASSERT_EQUAL(4, fd.visibleDecimalDigitCount);
671 ASSERT_EQUAL(2300, fd.decimalDigits);
672 ASSERT_EQUAL(23, fd.decimalDigitsWithoutTrailingZeros);
673 ASSERT_EQUAL(1, fd.intValue);
674 ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
675 ASSERT_EQUAL(FALSE, fd.isNegative);
676
677 fd = df->getFixedDecimal(uprv_getInfinity(), status);
678 TEST_ASSERT_STATUS(status);
679 ASSERT_EQUAL(TRUE, fd.isNanOrInfinity);
680 fd = df->getFixedDecimal(0.0, status);
681 ASSERT_EQUAL(FALSE, fd.isNanOrInfinity);
682 fd = df->getFixedDecimal(uprv_getNaN(), status);
683 ASSERT_EQUAL(TRUE, fd.isNanOrInfinity);
684 TEST_ASSERT_STATUS(status);
685
686 // Test Big Decimal input.
687 // 22 digits before and after decimal, will exceed the precision of a double
688 // and force DecimalFormat::getFixedDecimal() to work with a digit list.
b331163b
A
689 df.adoptInsteadAndCheckErrorCode(
690 new DecimalFormat("#####################0.00####################", status), status);
57a6839d
A
691 TEST_ASSERT_STATUS(status);
692 Formattable fable("12.34", status);
693 TEST_ASSERT_STATUS(status);
694 fd = df->getFixedDecimal(fable, status);
695 TEST_ASSERT_STATUS(status);
696 ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
697 ASSERT_EQUAL(34, fd.decimalDigits);
698 ASSERT_EQUAL(34, fd.decimalDigitsWithoutTrailingZeros);
699 ASSERT_EQUAL(12, fd.intValue);
700 ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
701 ASSERT_EQUAL(FALSE, fd.isNegative);
702
703 fable.setDecimalNumber("12.345678901234567890123456789", status);
704 TEST_ASSERT_STATUS(status);
705 fd = df->getFixedDecimal(fable, status);
706 TEST_ASSERT_STATUS(status);
707 ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
708 ASSERT_EQUAL(345678901234567890LL, fd.decimalDigits);
709 ASSERT_EQUAL(34567890123456789LL, fd.decimalDigitsWithoutTrailingZeros);
710 ASSERT_EQUAL(12, fd.intValue);
711 ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
712 ASSERT_EQUAL(FALSE, fd.isNegative);
713
714 // On field overflow, Integer part is truncated on the left, fraction part on the right.
715 fable.setDecimalNumber("123456789012345678901234567890.123456789012345678901234567890", status);
716 TEST_ASSERT_STATUS(status);
717 fd = df->getFixedDecimal(fable, status);
718 TEST_ASSERT_STATUS(status);
719 ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
720 ASSERT_EQUAL(123456789012345678LL, fd.decimalDigits);
721 ASSERT_EQUAL(123456789012345678LL, fd.decimalDigitsWithoutTrailingZeros);
722 ASSERT_EQUAL(345678901234567890LL, fd.intValue);
723 ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
724 ASSERT_EQUAL(FALSE, fd.isNegative);
725
726 // Digits way to the right of the decimal but within the format's precision aren't truncated
727 fable.setDecimalNumber("1.0000000000000000000012", status);
728 TEST_ASSERT_STATUS(status);
729 fd = df->getFixedDecimal(fable, status);
730 TEST_ASSERT_STATUS(status);
731 ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
732 ASSERT_EQUAL(12, fd.decimalDigits);
733 ASSERT_EQUAL(12, fd.decimalDigitsWithoutTrailingZeros);
734 ASSERT_EQUAL(1, fd.intValue);
735 ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
736 ASSERT_EQUAL(FALSE, fd.isNegative);
737
738 // Digits beyond the precision of the format are rounded away
739 fable.setDecimalNumber("1.000000000000000000000012", status);
740 TEST_ASSERT_STATUS(status);
741 fd = df->getFixedDecimal(fable, status);
742 TEST_ASSERT_STATUS(status);
743 ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
744 ASSERT_EQUAL(0, fd.decimalDigits);
745 ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
746 ASSERT_EQUAL(1, fd.intValue);
747 ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
748 ASSERT_EQUAL(FALSE, fd.isNegative);
749
750 // Negative numbers come through
751 fable.setDecimalNumber("-1.0000000000000000000012", status);
752 TEST_ASSERT_STATUS(status);
753 fd = df->getFixedDecimal(fable, status);
754 TEST_ASSERT_STATUS(status);
755 ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
756 ASSERT_EQUAL(12, fd.decimalDigits);
757 ASSERT_EQUAL(12, fd.decimalDigitsWithoutTrailingZeros);
758 ASSERT_EQUAL(1, fd.intValue);
759 ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
760 ASSERT_EQUAL(TRUE, fd.isNegative);
761
762 // MinFractionDigits from format larger than from number.
763 fable.setDecimalNumber("1000000000000000000000.3", status);
764 TEST_ASSERT_STATUS(status);
765 fd = df->getFixedDecimal(fable, status);
766 TEST_ASSERT_STATUS(status);
767 ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
768 ASSERT_EQUAL(30, fd.decimalDigits);
769 ASSERT_EQUAL(3, fd.decimalDigitsWithoutTrailingZeros);
770 ASSERT_EQUAL(100000000000000000LL, fd.intValue);
771 ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
772 ASSERT_EQUAL(FALSE, fd.isNegative);
773
774 // Test some int64_t values that are out of the range of a double
775 fable.setInt64(4503599627370496LL);
776 TEST_ASSERT_STATUS(status);
777 fd = df->getFixedDecimal(fable, status);
778 TEST_ASSERT_STATUS(status);
779 ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
780 ASSERT_EQUAL(0, fd.decimalDigits);
781 ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
782 ASSERT_EQUAL(4503599627370496LL, fd.intValue);
783 ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
784 ASSERT_EQUAL(FALSE, fd.isNegative);
785
786 fable.setInt64(4503599627370497LL);
787 TEST_ASSERT_STATUS(status);
788 fd = df->getFixedDecimal(fable, status);
789 TEST_ASSERT_STATUS(status);
790 ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
791 ASSERT_EQUAL(0, fd.decimalDigits);
792 ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
793 ASSERT_EQUAL(4503599627370497LL, fd.intValue);
794 ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
795 ASSERT_EQUAL(FALSE, fd.isNegative);
796
797 fable.setInt64(9223372036854775807LL);
798 TEST_ASSERT_STATUS(status);
799 fd = df->getFixedDecimal(fable, status);
800 TEST_ASSERT_STATUS(status);
801 ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
802 ASSERT_EQUAL(0, fd.decimalDigits);
803 ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
804 // note: going through DigitList path to FixedDecimal, which is trimming
805 // int64_t fields to 18 digits. See ticket Ticket #10374
806 // ASSERT_EQUAL(223372036854775807LL, fd.intValue);
807 if (!(fd.intValue == 223372036854775807LL || fd.intValue == 9223372036854775807LL)) {
808 dataerrln("File %s, Line %d, fd.intValue = %lld", __FILE__, __LINE__, fd.intValue);
809 }
810 ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
811 ASSERT_EQUAL(FALSE, fd.isNegative);
812
813}
814
815void IntlTestDecimalFormatAPI::TestBadFastpath() {
816 UErrorCode status = U_ZERO_ERROR;
817
b331163b 818 LocalPointer<DecimalFormat> df(new DecimalFormat("###", status), status);
57a6839d
A
819 if (U_FAILURE(status)) {
820 dataerrln("Error creating new DecimalFormat - %s", u_errorName(status));
821 return;
822 }
823
824 UnicodeString fmt;
825 fmt.remove();
826 assertEquals("Format 1234", "1234", df->format(1234, fmt));
827 df->setGroupingUsed(FALSE);
828 fmt.remove();
829 assertEquals("Format 1234", "1234", df->format(1234, fmt));
830 df->setGroupingUsed(TRUE);
831 fmt.remove();
832 assertEquals("Format 1234 w/ grouping", "1,234", df->format(1234, fmt));
833}
834
b331163b
A
835void IntlTestDecimalFormatAPI::TestRequiredDecimalPoint() {
836 UErrorCode status = U_ZERO_ERROR;
837 UnicodeString text("99");
838 Formattable result1;
839 UnicodeString pat1("##.0000");
840 UnicodeString pat2("00.0");
841
842 LocalPointer<DecimalFormat> df(new DecimalFormat(pat1, status), status);
843 if (U_FAILURE(status)) {
844 dataerrln("Error creating new DecimalFormat - %s", u_errorName(status));
845 return;
846 }
847
848 status = U_ZERO_ERROR;
849 df->applyPattern(pat1, status);
850 if(U_FAILURE(status)) {
851 errln((UnicodeString)"ERROR: applyPattern() failed");
852 }
853 df->parse(text, result1, status);
854 if(U_FAILURE(status)) {
855 errln((UnicodeString)"ERROR: parse() failed");
856 }
857 df->setDecimalPatternMatchRequired(TRUE);
858 df->parse(text, result1, status);
859 if(U_SUCCESS(status)) {
860 errln((UnicodeString)"ERROR: unexpected parse()");
861 }
862
863
864 status = U_ZERO_ERROR;
865 df->applyPattern(pat2, status);
866 df->setDecimalPatternMatchRequired(FALSE);
867 if(U_FAILURE(status)) {
868 errln((UnicodeString)"ERROR: applyPattern(2) failed");
869 }
870 df->parse(text, result1, status);
871 if(U_FAILURE(status)) {
872 errln((UnicodeString)"ERROR: parse(2) failed - " + u_errorName(status));
873 }
874 df->setDecimalPatternMatchRequired(TRUE);
875 df->parse(text, result1, status);
876 if(U_SUCCESS(status)) {
877 errln((UnicodeString)"ERROR: unexpected parse(2)");
878 }
879}
880
b75a7d8f 881#endif /* #if !UCONFIG_NO_FORMATTING */