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