]>
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 | ||
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 | ||
29 | void 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 | */ | |
96 | void 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 |
414 | void 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 |
457 | void 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 | } | |
504 | void 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 | ||
513 | void 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 |
520 | void 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 |
550 | void 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 | ||
601 | void 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 | ||
815 | void 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 |
835 | void 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 */ |