]>
Commit | Line | Data |
---|---|---|
1 | // © 2016 and later: Unicode, Inc. and others. | |
2 | // License & terms of use: http://www.unicode.org/copyright.html | |
3 | /******************************************************************** | |
4 | * COPYRIGHT: | |
5 | * Copyright (c) 1997-2015, International Business Machines Corporation and | |
6 | * others. All Rights Reserved. | |
7 | ********************************************************************/ | |
8 | ||
9 | #include "unicode/utypes.h" | |
10 | ||
11 | #if !UCONFIG_NO_FORMATTING | |
12 | ||
13 | #include "dcfmapts.h" | |
14 | ||
15 | #include "unicode/currpinf.h" | |
16 | #include "unicode/dcfmtsym.h" | |
17 | #include "unicode/decimfmt.h" | |
18 | #include "unicode/fmtable.h" | |
19 | #include "unicode/localpointer.h" | |
20 | #include "unicode/parseerr.h" | |
21 | #include "unicode/stringpiece.h" | |
22 | ||
23 | #include "putilimp.h" | |
24 | #include "plurrule_impl.h" | |
25 | #include "number_decimalquantity.h" | |
26 | ||
27 | #include <stdio.h> | |
28 | ||
29 | // This is an API test, not a unit test. It doesn't test very many cases, and doesn't | |
30 | // try to test the full functionality. It just calls each function in the class and | |
31 | // verifies that it works on a basic level. | |
32 | ||
33 | void IntlTestDecimalFormatAPI::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) | |
34 | { | |
35 | if (exec) logln((UnicodeString)"TestSuite DecimalFormatAPI"); | |
36 | switch (index) { | |
37 | case 0: name = "DecimalFormat API test"; | |
38 | if (exec) { | |
39 | logln((UnicodeString)"DecimalFormat API test---"); logln((UnicodeString)""); | |
40 | UErrorCode status = U_ZERO_ERROR; | |
41 | Locale saveLocale; | |
42 | Locale::setDefault(Locale::getEnglish(), status); | |
43 | if(U_FAILURE(status)) { | |
44 | errln((UnicodeString)"ERROR: Could not set default locale, test may not give correct results"); | |
45 | } | |
46 | testAPI(/*par*/); | |
47 | Locale::setDefault(saveLocale, status); | |
48 | } | |
49 | break; | |
50 | case 1: name = "Rounding test"; | |
51 | if(exec) { | |
52 | logln((UnicodeString)"DecimalFormat Rounding test---"); | |
53 | testRounding(/*par*/); | |
54 | } | |
55 | break; | |
56 | case 2: name = "Test6354"; | |
57 | if(exec) { | |
58 | logln((UnicodeString)"DecimalFormat Rounding Increment test---"); | |
59 | testRoundingInc(/*par*/); | |
60 | } | |
61 | break; | |
62 | case 3: name = "TestCurrencyPluralInfo"; | |
63 | if(exec) { | |
64 | logln((UnicodeString)"CurrencyPluralInfo API test---"); | |
65 | TestCurrencyPluralInfo(); | |
66 | } | |
67 | break; | |
68 | case 4: name = "TestScale"; | |
69 | if(exec) { | |
70 | logln((UnicodeString)"Scale test---"); | |
71 | TestScale(); | |
72 | } | |
73 | break; | |
74 | case 5: name = "TestFixedDecimal"; | |
75 | if(exec) { | |
76 | logln((UnicodeString)"TestFixedDecimal ---"); | |
77 | TestFixedDecimal(); | |
78 | } | |
79 | break; | |
80 | case 6: name = "TestBadFastpath"; | |
81 | if(exec) { | |
82 | logln((UnicodeString)"TestBadFastpath ---"); | |
83 | TestBadFastpath(); | |
84 | } | |
85 | break; | |
86 | case 7: name = "TestRequiredDecimalPoint"; | |
87 | if(exec) { | |
88 | logln((UnicodeString)"TestRequiredDecimalPoint ---"); | |
89 | TestRequiredDecimalPoint(); | |
90 | } | |
91 | break; | |
92 | case 8: name = "testErrorCode"; | |
93 | if(exec) { | |
94 | logln((UnicodeString)"testErrorCode ---"); | |
95 | testErrorCode(); | |
96 | } | |
97 | break; | |
98 | case 9: name = "testInvalidObject"; | |
99 | if(exec) { | |
100 | logln((UnicodeString) "testInvalidObject ---"); | |
101 | testInvalidObject(); | |
102 | } | |
103 | break; | |
104 | default: name = ""; break; | |
105 | } | |
106 | } | |
107 | ||
108 | /** | |
109 | * This test checks various generic API methods in DecimalFormat to achieve 100% | |
110 | * API coverage. | |
111 | */ | |
112 | void IntlTestDecimalFormatAPI::testAPI(/*char *par*/) | |
113 | { | |
114 | UErrorCode status = U_ZERO_ERROR; | |
115 | ||
116 | // ======= Test constructors | |
117 | ||
118 | logln((UnicodeString)"Testing DecimalFormat constructors"); | |
119 | ||
120 | DecimalFormat def(status); | |
121 | if(U_FAILURE(status)) { | |
122 | errcheckln(status, "ERROR: Could not create DecimalFormat (default) - %s", u_errorName(status)); | |
123 | return; | |
124 | } | |
125 | ||
126 | // bug 10864 | |
127 | status = U_ZERO_ERROR; | |
128 | DecimalFormat noGrouping("###0.##", status); | |
129 | assertEquals("Grouping size should be 0 for no grouping.", 0, noGrouping.getGroupingSize()); | |
130 | noGrouping.setGroupingUsed(TRUE); | |
131 | assertEquals("Grouping size should still be 0.", 0, noGrouping.getGroupingSize()); | |
132 | // end bug 10864 | |
133 | ||
134 | // bug 13442 comment 14 | |
135 | status = U_ZERO_ERROR; | |
136 | { | |
137 | DecimalFormat df("0", {"en", status}, status); | |
138 | UnicodeString result; | |
139 | assertEquals("pat 0: ", 0, df.getGroupingSize()); | |
140 | assertEquals("pat 0: ", (UBool) FALSE, (UBool) df.isGroupingUsed()); | |
141 | df.setGroupingUsed(false); | |
142 | assertEquals("pat 0 then disabled: ", 0, df.getGroupingSize()); | |
143 | assertEquals("pat 0 then disabled: ", u"1111", df.format(1111, result.remove())); | |
144 | df.setGroupingUsed(true); | |
145 | assertEquals("pat 0 then enabled: ", 0, df.getGroupingSize()); | |
146 | assertEquals("pat 0 then enabled: ", u"1111", df.format(1111, result.remove())); | |
147 | } | |
148 | { | |
149 | DecimalFormat df("#,##0", {"en", status}, status); | |
150 | UnicodeString result; | |
151 | assertEquals("pat #,##0: ", 3, df.getGroupingSize()); | |
152 | assertEquals("pat #,##0: ", (UBool) TRUE, (UBool) df.isGroupingUsed()); | |
153 | df.setGroupingUsed(false); | |
154 | assertEquals("pat #,##0 then disabled: ", 3, df.getGroupingSize()); | |
155 | assertEquals("pat #,##0 then disabled: ", u"1111", df.format(1111, result.remove())); | |
156 | df.setGroupingUsed(true); | |
157 | assertEquals("pat #,##0 then enabled: ", 3, df.getGroupingSize()); | |
158 | assertEquals("pat #,##0 then enabled: ", u"1,111", df.format(1111, result.remove())); | |
159 | } | |
160 | // end bug 13442 comment 14 | |
161 | ||
162 | status = U_ZERO_ERROR; | |
163 | const UnicodeString pattern("#,##0.# FF"); | |
164 | DecimalFormat pat(pattern, status); | |
165 | if(U_FAILURE(status)) { | |
166 | errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern)"); | |
167 | return; | |
168 | } | |
169 | ||
170 | status = U_ZERO_ERROR; | |
171 | DecimalFormatSymbols *symbols = new DecimalFormatSymbols(Locale::getFrench(), status); | |
172 | if(U_FAILURE(status)) { | |
173 | errln((UnicodeString)"ERROR: Could not create DecimalFormatSymbols (French)"); | |
174 | return; | |
175 | } | |
176 | ||
177 | status = U_ZERO_ERROR; | |
178 | DecimalFormat cust1(pattern, symbols, status); | |
179 | if(U_FAILURE(status)) { | |
180 | errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols*)"); | |
181 | } | |
182 | ||
183 | status = U_ZERO_ERROR; | |
184 | DecimalFormat cust2(pattern, *symbols, status); | |
185 | if(U_FAILURE(status)) { | |
186 | errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols)"); | |
187 | } | |
188 | ||
189 | DecimalFormat copy(pat); | |
190 | ||
191 | // ======= Test clone(), assignment, and equality | |
192 | ||
193 | logln((UnicodeString)"Testing clone(), assignment and equality operators"); | |
194 | ||
195 | if( ! (copy == pat) || copy != pat) { | |
196 | errln((UnicodeString)"ERROR: Copy constructor or == failed"); | |
197 | } | |
198 | ||
199 | copy = cust1; | |
200 | if(copy != cust1) { | |
201 | errln((UnicodeString)"ERROR: Assignment (or !=) failed"); | |
202 | } | |
203 | ||
204 | Format *clone = def.clone(); | |
205 | if( ! (*clone == def) ) { | |
206 | errln((UnicodeString)"ERROR: Clone() failed"); | |
207 | } | |
208 | delete clone; | |
209 | ||
210 | // ======= Test various format() methods | |
211 | ||
212 | logln((UnicodeString)"Testing various format() methods"); | |
213 | ||
214 | double d = -10456.0037; | |
215 | int32_t l = 100000000; | |
216 | Formattable fD(d); | |
217 | Formattable fL(l); | |
218 | ||
219 | UnicodeString res1, res2, res3, res4; | |
220 | FieldPosition pos1(FieldPosition::DONT_CARE), pos2(FieldPosition::DONT_CARE), pos3(FieldPosition::DONT_CARE), pos4(FieldPosition::DONT_CARE); | |
221 | ||
222 | res1 = def.format(d, res1, pos1); | |
223 | logln( (UnicodeString) "" + (int32_t) d + " formatted to " + res1); | |
224 | ||
225 | res2 = pat.format(l, res2, pos2); | |
226 | logln((UnicodeString) "" + (int32_t) l + " formatted to " + res2); | |
227 | ||
228 | status = U_ZERO_ERROR; | |
229 | res3 = cust1.format(fD, res3, pos3, status); | |
230 | if(U_FAILURE(status)) { | |
231 | errln((UnicodeString)"ERROR: format(Formattable [double]) failed"); | |
232 | } | |
233 | logln((UnicodeString) "" + (int32_t) fD.getDouble() + " formatted to " + res3); | |
234 | ||
235 | status = U_ZERO_ERROR; | |
236 | res4 = cust2.format(fL, res4, pos4, status); | |
237 | if(U_FAILURE(status)) { | |
238 | errln((UnicodeString)"ERROR: format(Formattable [long]) failed"); | |
239 | } | |
240 | logln((UnicodeString) "" + fL.getLong() + " formatted to " + res4); | |
241 | ||
242 | // ======= Test parse() | |
243 | ||
244 | logln((UnicodeString)"Testing parse()"); | |
245 | ||
246 | UnicodeString text("-10,456.0037"); | |
247 | Formattable result1, result2; | |
248 | ParsePosition pos(0); | |
249 | UnicodeString patt("#,##0.#"); | |
250 | status = U_ZERO_ERROR; | |
251 | pat.applyPattern(patt, status); | |
252 | if(U_FAILURE(status)) { | |
253 | errln((UnicodeString)"ERROR: applyPattern() failed"); | |
254 | } | |
255 | pat.parse(text, result1, pos); | |
256 | if(result1.getType() != Formattable::kDouble && result1.getDouble() != d) { | |
257 | errln((UnicodeString)"ERROR: Roundtrip failed (via parse()) for " + text); | |
258 | } | |
259 | logln(text + " parsed into " + (int32_t) result1.getDouble()); | |
260 | ||
261 | status = U_ZERO_ERROR; | |
262 | pat.parse(text, result2, status); | |
263 | if(U_FAILURE(status)) { | |
264 | errln((UnicodeString)"ERROR: parse() failed"); | |
265 | } | |
266 | if(result2.getType() != Formattable::kDouble && result2.getDouble() != d) { | |
267 | errln((UnicodeString)"ERROR: Roundtrip failed (via parse()) for " + text); | |
268 | } | |
269 | logln(text + " parsed into " + (int32_t) result2.getDouble()); | |
270 | ||
271 | // ======= Test getters and setters | |
272 | ||
273 | logln((UnicodeString)"Testing getters and setters"); | |
274 | ||
275 | const DecimalFormatSymbols *syms = pat.getDecimalFormatSymbols(); | |
276 | DecimalFormatSymbols *newSyms = new DecimalFormatSymbols(*syms); | |
277 | def.setDecimalFormatSymbols(*newSyms); | |
278 | def.adoptDecimalFormatSymbols(newSyms); // don't use newSyms after this | |
279 | if( *(pat.getDecimalFormatSymbols()) != *(def.getDecimalFormatSymbols())) { | |
280 | errln((UnicodeString)"ERROR: adopt or set DecimalFormatSymbols() failed"); | |
281 | } | |
282 | ||
283 | UnicodeString posPrefix; | |
284 | pat.setPositivePrefix("+"); | |
285 | posPrefix = pat.getPositivePrefix(posPrefix); | |
286 | logln((UnicodeString)"Positive prefix (should be +): " + posPrefix); | |
287 | if(posPrefix != "+") { | |
288 | errln((UnicodeString)"ERROR: setPositivePrefix() failed"); | |
289 | } | |
290 | ||
291 | UnicodeString negPrefix; | |
292 | pat.setNegativePrefix("-"); | |
293 | negPrefix = pat.getNegativePrefix(negPrefix); | |
294 | logln((UnicodeString)"Negative prefix (should be -): " + negPrefix); | |
295 | if(negPrefix != "-") { | |
296 | errln((UnicodeString)"ERROR: setNegativePrefix() failed"); | |
297 | } | |
298 | ||
299 | UnicodeString posSuffix; | |
300 | pat.setPositiveSuffix("_"); | |
301 | posSuffix = pat.getPositiveSuffix(posSuffix); | |
302 | logln((UnicodeString)"Positive suffix (should be _): " + posSuffix); | |
303 | if(posSuffix != "_") { | |
304 | errln((UnicodeString)"ERROR: setPositiveSuffix() failed"); | |
305 | } | |
306 | ||
307 | UnicodeString negSuffix; | |
308 | pat.setNegativeSuffix("~"); | |
309 | negSuffix = pat.getNegativeSuffix(negSuffix); | |
310 | logln((UnicodeString)"Negative suffix (should be ~): " + negSuffix); | |
311 | if(negSuffix != "~") { | |
312 | errln((UnicodeString)"ERROR: setNegativeSuffix() failed"); | |
313 | } | |
314 | ||
315 | int32_t multiplier = 0; | |
316 | pat.setMultiplier(8); | |
317 | multiplier = pat.getMultiplier(); | |
318 | logln((UnicodeString)"Multiplier (should be 8): " + multiplier); | |
319 | if(multiplier != 8) { | |
320 | errln((UnicodeString)"ERROR: setMultiplier() failed"); | |
321 | } | |
322 | ||
323 | int32_t groupingSize = 0; | |
324 | pat.setGroupingSize(2); | |
325 | groupingSize = pat.getGroupingSize(); | |
326 | logln((UnicodeString)"Grouping size (should be 2): " + (int32_t) groupingSize); | |
327 | if(groupingSize != 2) { | |
328 | errln((UnicodeString)"ERROR: setGroupingSize() failed"); | |
329 | } | |
330 | ||
331 | pat.setDecimalSeparatorAlwaysShown(TRUE); | |
332 | UBool tf = pat.isDecimalSeparatorAlwaysShown(); | |
333 | logln((UnicodeString)"DecimalSeparatorIsAlwaysShown (should be TRUE) is " + (UnicodeString) (tf ? "TRUE" : "FALSE")); | |
334 | if(tf != TRUE) { | |
335 | errln((UnicodeString)"ERROR: setDecimalSeparatorAlwaysShown() failed"); | |
336 | } | |
337 | // Added by Ken Liu testing set/isExponentSignAlwaysShown | |
338 | pat.setExponentSignAlwaysShown(TRUE); | |
339 | UBool esas = pat.isExponentSignAlwaysShown(); | |
340 | logln((UnicodeString)"ExponentSignAlwaysShown (should be TRUE) is " + (UnicodeString) (esas ? "TRUE" : "FALSE")); | |
341 | if(esas != TRUE) { | |
342 | errln((UnicodeString)"ERROR: ExponentSignAlwaysShown() failed"); | |
343 | } | |
344 | ||
345 | // Added by Ken Liu testing set/isScientificNotation | |
346 | pat.setScientificNotation(TRUE); | |
347 | UBool sn = pat.isScientificNotation(); | |
348 | logln((UnicodeString)"isScientificNotation (should be TRUE) is " + (UnicodeString) (sn ? "TRUE" : "FALSE")); | |
349 | if(sn != TRUE) { | |
350 | errln((UnicodeString)"ERROR: setScientificNotation() failed"); | |
351 | } | |
352 | ||
353 | // Added by Ken Liu testing set/getMinimumExponentDigits | |
354 | int8_t MinimumExponentDigits = 0; | |
355 | pat.setMinimumExponentDigits(2); | |
356 | MinimumExponentDigits = pat.getMinimumExponentDigits(); | |
357 | logln((UnicodeString)"MinimumExponentDigits (should be 2) is " + (int8_t) MinimumExponentDigits); | |
358 | if(MinimumExponentDigits != 2) { | |
359 | errln((UnicodeString)"ERROR: setMinimumExponentDigits() failed"); | |
360 | } | |
361 | ||
362 | // Added by Ken Liu testing set/getRoundingIncrement | |
363 | double RoundingIncrement = 0.0; | |
364 | pat.setRoundingIncrement(2.0); | |
365 | RoundingIncrement = pat.getRoundingIncrement(); | |
366 | logln((UnicodeString)"RoundingIncrement (should be 2.0) is " + (double) RoundingIncrement); | |
367 | if(RoundingIncrement != 2.0) { | |
368 | errln((UnicodeString)"ERROR: setRoundingIncrement() failed"); | |
369 | } | |
370 | //end of Ken's Adding | |
371 | ||
372 | UnicodeString funkyPat; | |
373 | funkyPat = pat.toPattern(funkyPat); | |
374 | logln((UnicodeString)"Pattern is " + funkyPat); | |
375 | ||
376 | UnicodeString locPat; | |
377 | locPat = pat.toLocalizedPattern(locPat); | |
378 | logln((UnicodeString)"Localized pattern is " + locPat); | |
379 | ||
380 | // ======= Test applyPattern() | |
381 | ||
382 | logln((UnicodeString)"Testing applyPattern()"); | |
383 | pat = DecimalFormat(status); // reset | |
384 | ||
385 | UnicodeString p1("#,##0.0#;(#,##0.0#)"); | |
386 | logln((UnicodeString)"Applying pattern " + p1); | |
387 | status = U_ZERO_ERROR; | |
388 | pat.applyPattern(p1, status); | |
389 | if(U_FAILURE(status)) { | |
390 | errln((UnicodeString)"ERROR: applyPattern() failed with " + (int32_t) status); | |
391 | } | |
392 | UnicodeString s2; | |
393 | s2 = pat.toPattern(s2); | |
394 | logln((UnicodeString)"Extracted pattern is " + s2); | |
395 | assertEquals("toPattern() result did not match pattern applied", p1, s2); | |
396 | ||
397 | if(pat.getSecondaryGroupingSize() != 0) { | |
398 | errln("FAIL: Secondary Grouping Size should be 0, not %d\n", pat.getSecondaryGroupingSize()); | |
399 | } | |
400 | ||
401 | if(pat.getGroupingSize() != 3) { | |
402 | errln("FAIL: Primary Grouping Size should be 3, not %d\n", pat.getGroupingSize()); | |
403 | } | |
404 | ||
405 | UnicodeString p2("#,##,##0.0# FF;(#,##,##0.0# FF)"); | |
406 | logln((UnicodeString)"Applying pattern " + p2); | |
407 | status = U_ZERO_ERROR; | |
408 | pat.applyLocalizedPattern(p2, status); | |
409 | if(U_FAILURE(status)) { | |
410 | errln((UnicodeString)"ERROR: applyPattern() failed with " + (int32_t) status); | |
411 | } | |
412 | UnicodeString s3; | |
413 | s3 = pat.toLocalizedPattern(s3); | |
414 | logln((UnicodeString)"Extracted pattern is " + s3); | |
415 | assertEquals("toLocalizedPattern() result did not match pattern applied", p2, s3); | |
416 | ||
417 | status = U_ZERO_ERROR; | |
418 | UParseError pe; | |
419 | pat.applyLocalizedPattern(p2, pe, status); | |
420 | if(U_FAILURE(status)) { | |
421 | errln((UnicodeString)"ERROR: applyPattern((with ParseError)) failed with " + (int32_t) status); | |
422 | } | |
423 | UnicodeString s4; | |
424 | s4 = pat.toLocalizedPattern(s3); | |
425 | logln((UnicodeString)"Extracted pattern is " + s4); | |
426 | assertEquals("toLocalizedPattern(with ParseErr) result did not match pattern applied", p2, s4); | |
427 | ||
428 | if(pat.getSecondaryGroupingSize() != 2) { | |
429 | errln("FAIL: Secondary Grouping Size should be 2, not %d\n", pat.getSecondaryGroupingSize()); | |
430 | } | |
431 | ||
432 | if(pat.getGroupingSize() != 3) { | |
433 | errln("FAIL: Primary Grouping Size should be 3, not %d\n", pat.getGroupingSize()); | |
434 | } | |
435 | ||
436 | // ======= Test getStaticClassID() | |
437 | ||
438 | logln((UnicodeString)"Testing getStaticClassID()"); | |
439 | ||
440 | status = U_ZERO_ERROR; | |
441 | NumberFormat *test = new DecimalFormat(status); | |
442 | if(U_FAILURE(status)) { | |
443 | errln((UnicodeString)"ERROR: Couldn't create a DecimalFormat"); | |
444 | } | |
445 | ||
446 | if(test->getDynamicClassID() != DecimalFormat::getStaticClassID()) { | |
447 | errln((UnicodeString)"ERROR: getDynamicClassID() didn't return the expected value"); | |
448 | } | |
449 | ||
450 | delete test; | |
451 | } | |
452 | ||
453 | void IntlTestDecimalFormatAPI::TestCurrencyPluralInfo(){ | |
454 | UErrorCode status = U_ZERO_ERROR; | |
455 | ||
456 | LocalPointer<CurrencyPluralInfo>cpi(new CurrencyPluralInfo(status), status); | |
457 | if(U_FAILURE(status)) { | |
458 | errln((UnicodeString)"ERROR: CurrencyPluralInfo(UErrorCode) could not be created"); | |
459 | return; | |
460 | } | |
461 | ||
462 | CurrencyPluralInfo cpi1 = *cpi; | |
463 | ||
464 | if(cpi->getDynamicClassID() != CurrencyPluralInfo::getStaticClassID()){ | |
465 | errln((UnicodeString)"ERROR: CurrencyPluralInfo::getDynamicClassID() didn't return the expected value"); | |
466 | } | |
467 | ||
468 | cpi->setCurrencyPluralPattern("","",status); | |
469 | if(U_FAILURE(status)) { | |
470 | errln((UnicodeString)"ERROR: CurrencyPluralInfo::setCurrencyPluralPattern"); | |
471 | } | |
472 | ||
473 | cpi->setLocale(Locale::getCanada(), status); | |
474 | if(U_FAILURE(status)) { | |
475 | errln((UnicodeString)"ERROR: CurrencyPluralInfo::setLocale"); | |
476 | } | |
477 | ||
478 | cpi->setPluralRules("",status); | |
479 | if(U_FAILURE(status)) { | |
480 | errln((UnicodeString)"ERROR: CurrencyPluralInfo::setPluralRules"); | |
481 | } | |
482 | ||
483 | LocalPointer<DecimalFormat>df(new DecimalFormat(status)); | |
484 | if(U_FAILURE(status)) { | |
485 | errcheckln(status, "ERROR: Could not create DecimalFormat - %s", u_errorName(status)); | |
486 | return; | |
487 | } | |
488 | ||
489 | df->adoptCurrencyPluralInfo(cpi.orphan()); | |
490 | ||
491 | df->getCurrencyPluralInfo(); | |
492 | ||
493 | df->setCurrencyPluralInfo(cpi1); | |
494 | ||
495 | } | |
496 | ||
497 | void IntlTestDecimalFormatAPI::testRounding(/*char *par*/) | |
498 | { | |
499 | UErrorCode status = U_ZERO_ERROR; | |
500 | double Roundingnumber = 2.55; | |
501 | double Roundingnumber1 = -2.55; | |
502 | //+2.55 results -2.55 results | |
503 | double result[]={ 3.0, -2.0, // kRoundCeiling 0, | |
504 | 2.0, -3.0, // kRoundFloor 1, | |
505 | 2.0, -2.0, // kRoundDown 2, | |
506 | 3.0, -3.0, // kRoundUp 3, | |
507 | 3.0, -3.0, // kRoundHalfEven 4, | |
508 | 3.0, -3.0, // kRoundHalfDown 5, | |
509 | 3.0, -3.0 // kRoundHalfUp 6 | |
510 | }; | |
511 | DecimalFormat pat(status); | |
512 | if(U_FAILURE(status)) { | |
513 | errcheckln(status, "ERROR: Could not create DecimalFormat (default) - %s", u_errorName(status)); | |
514 | return; | |
515 | } | |
516 | uint16_t mode; | |
517 | uint16_t i=0; | |
518 | UnicodeString message; | |
519 | UnicodeString resultStr; | |
520 | for(mode=0;mode < 7;mode++){ | |
521 | pat.setRoundingMode((DecimalFormat::ERoundingMode)mode); | |
522 | if(pat.getRoundingMode() != (DecimalFormat::ERoundingMode)mode){ | |
523 | errln((UnicodeString)"SetRoundingMode or GetRoundingMode failed for mode=" + mode); | |
524 | } | |
525 | ||
526 | ||
527 | //for +2.55 with RoundingIncrement=1.0 | |
528 | pat.setRoundingIncrement(1.0); | |
529 | pat.format(Roundingnumber, resultStr); | |
530 | message= (UnicodeString)"round(" + (double)Roundingnumber + UnicodeString(",") + mode + UnicodeString(",FALSE) with RoundingIncrement=1.0==>"); | |
531 | verify(message, resultStr, result[i++]); | |
532 | message.remove(); | |
533 | resultStr.remove(); | |
534 | ||
535 | //for -2.55 with RoundingIncrement=1.0 | |
536 | pat.format(Roundingnumber1, resultStr); | |
537 | message= (UnicodeString)"round(" + (double)Roundingnumber1 + UnicodeString(",") + mode + UnicodeString(",FALSE) with RoundingIncrement=1.0==>"); | |
538 | verify(message, resultStr, result[i++]); | |
539 | message.remove(); | |
540 | resultStr.remove(); | |
541 | } | |
542 | ||
543 | } | |
544 | void IntlTestDecimalFormatAPI::verify(const UnicodeString& message, const UnicodeString& got, double expected){ | |
545 | logln((UnicodeString)message + got + (UnicodeString)" Expected : " + expected); | |
546 | UnicodeString expectedStr(""); | |
547 | expectedStr=expectedStr + expected; | |
548 | if(got != expectedStr ) { | |
549 | errln((UnicodeString)"ERROR: " + message + got + (UnicodeString)" Expected : " + expectedStr); | |
550 | } | |
551 | } | |
552 | ||
553 | void IntlTestDecimalFormatAPI::verifyString(const UnicodeString& message, const UnicodeString& got, UnicodeString& expected){ | |
554 | logln((UnicodeString)message + got + (UnicodeString)" Expected : " + expected); | |
555 | if(got != expected ) { | |
556 | errln((UnicodeString)"ERROR: " + message + got + (UnicodeString)" Expected : " + expected); | |
557 | } | |
558 | } | |
559 | ||
560 | void IntlTestDecimalFormatAPI::testRoundingInc(/*char *par*/) | |
561 | { | |
562 | UErrorCode status = U_ZERO_ERROR; | |
563 | DecimalFormat pat(UnicodeString("#,##0.00"),status); | |
564 | if(U_FAILURE(status)) { | |
565 | errcheckln(status, "ERROR: Could not create DecimalFormat (default) - %s", u_errorName(status)); | |
566 | return; | |
567 | } | |
568 | ||
569 | // get default rounding increment | |
570 | double roundingInc = pat.getRoundingIncrement(); | |
571 | if (roundingInc != 0.0) { | |
572 | errln((UnicodeString)"ERROR: Rounding increment not zero"); | |
573 | return; | |
574 | } | |
575 | ||
576 | // With rounding now being handled by decNumber, we no longer | |
577 | // set a rounding increment to enable non-default mode rounding, | |
578 | // checking of which was the original point of this test. | |
579 | ||
580 | // set rounding mode with zero increment. Rounding | |
581 | // increment should not be set by this operation | |
582 | pat.setRoundingMode((DecimalFormat::ERoundingMode)0); | |
583 | roundingInc = pat.getRoundingIncrement(); | |
584 | if (roundingInc != 0.0) { | |
585 | errln((UnicodeString)"ERROR: Rounding increment not zero after setRoundingMode"); | |
586 | return; | |
587 | } | |
588 | } | |
589 | ||
590 | void IntlTestDecimalFormatAPI::TestScale() | |
591 | { | |
592 | typedef struct TestData { | |
593 | double inputValue; | |
594 | int inputScale; | |
595 | const char *expectedOutput; | |
596 | } TestData; | |
597 | ||
598 | static TestData testData[] = { | |
599 | { 100.0, 3, "100,000" }, | |
600 | { 10034.0, -2, "100.34" }, | |
601 | { 0.86, -3, "0.0009" }, | |
602 | { -0.000455, 1, "-0%" }, | |
603 | { -0.000555, 1, "-1%" }, | |
604 | { 0.000455, 1, "0%" }, | |
605 | { 0.000555, 1, "1%" }, | |
606 | }; | |
607 | ||
608 | UErrorCode status = U_ZERO_ERROR; | |
609 | DecimalFormat pat(status); | |
610 | if(U_FAILURE(status)) { | |
611 | errcheckln(status, "ERROR: Could not create DecimalFormat (default) - %s", u_errorName(status)); | |
612 | return; | |
613 | } | |
614 | ||
615 | UnicodeString message; | |
616 | UnicodeString resultStr; | |
617 | UnicodeString exp; | |
618 | UnicodeString percentPattern("#,##0%"); | |
619 | pat.setMaximumFractionDigits(4); | |
620 | ||
621 | for(int32_t i=0; i < UPRV_LENGTHOF(testData); i++) { | |
622 | if ( i > 2 ) { | |
623 | pat.applyPattern(percentPattern,status); | |
624 | } | |
625 | // Test both the attribute and the setter | |
626 | if (i % 2 == 0) { | |
627 | pat.setAttribute(UNUM_SCALE, testData[i].inputScale,status); | |
628 | assertEquals("", testData[i].inputScale, pat.getMultiplierScale()); | |
629 | } else { | |
630 | pat.setMultiplierScale(testData[i].inputScale); | |
631 | assertEquals("", testData[i].inputScale, pat.getAttribute(UNUM_SCALE, status)); | |
632 | } | |
633 | pat.format(testData[i].inputValue, resultStr); | |
634 | message = UnicodeString("Unexpected output for ") + testData[i].inputValue + UnicodeString(" and scale ") + | |
635 | testData[i].inputScale + UnicodeString(". Got: "); | |
636 | exp = testData[i].expectedOutput; | |
637 | verifyString(message, resultStr, exp); | |
638 | message.remove(); | |
639 | resultStr.remove(); | |
640 | exp.remove(); | |
641 | } | |
642 | } | |
643 | ||
644 | ||
645 | #define ASSERT_EQUAL(expect, actual) UPRV_BLOCK_MACRO_BEGIN { \ | |
646 | /* ICU-20080: Use temporary variables to avoid strange compiler behaviour \ | |
647 | (with the nice side-effect of avoiding repeated function calls too). */ \ | |
648 | auto lhs = (expect); \ | |
649 | auto rhs = (actual); \ | |
650 | char tmp[200]; \ | |
651 | sprintf(tmp, "(%g==%g)", (double)lhs, (double)rhs); \ | |
652 | assertTrue(tmp, (lhs==rhs), FALSE, TRUE, __FILE__, __LINE__); \ | |
653 | } UPRV_BLOCK_MACRO_END | |
654 | ||
655 | #if defined(_MSC_VER) | |
656 | // Ignore the noisy warning 4805 (comparisons between int and bool) in the function below as we use the ICU TRUE/FALSE macros | |
657 | // which are int values, whereas some of the DecimalQuantity methods return C++ bools. | |
658 | #pragma warning(push) | |
659 | #pragma warning(disable: 4805) | |
660 | #endif | |
661 | void IntlTestDecimalFormatAPI::TestFixedDecimal() { | |
662 | UErrorCode status = U_ZERO_ERROR; | |
663 | ||
664 | LocalPointer<DecimalFormat> df(new DecimalFormat("###", status), status); | |
665 | assertSuccess(WHERE, status); | |
666 | if (status == U_MISSING_RESOURCE_ERROR) { | |
667 | return; | |
668 | } | |
669 | number::impl::DecimalQuantity fd; | |
670 | df->formatToDecimalQuantity(44, fd, status); | |
671 | assertSuccess(WHERE, status); | |
672 | ASSERT_EQUAL(44, fd.getPluralOperand(PLURAL_OPERAND_N)); | |
673 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
674 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
675 | ||
676 | df->formatToDecimalQuantity(-44, fd, status); | |
677 | assertSuccess(WHERE, status); | |
678 | ASSERT_EQUAL(44, fd.getPluralOperand(PLURAL_OPERAND_N)); | |
679 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
680 | ASSERT_EQUAL(TRUE, fd.isNegative()); | |
681 | ||
682 | df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.00##", status), status); | |
683 | assertSuccess(WHERE, status); | |
684 | df->formatToDecimalQuantity(123.456, fd, status); | |
685 | assertSuccess(WHERE, status); | |
686 | ASSERT_EQUAL(3, fd.getPluralOperand(PLURAL_OPERAND_V)); // v | |
687 | ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_F)); // f | |
688 | ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_T)); // t | |
689 | ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I)); // i | |
690 | ASSERT_EQUAL(123.456, fd.getPluralOperand(PLURAL_OPERAND_N)); // n | |
691 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
692 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
693 | ||
694 | df->formatToDecimalQuantity(-123.456, fd, status); | |
695 | assertSuccess(WHERE, status); | |
696 | ASSERT_EQUAL(3, fd.getPluralOperand(PLURAL_OPERAND_V)); // v | |
697 | ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_F)); // f | |
698 | ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_T)); // t | |
699 | ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I)); // i | |
700 | ASSERT_EQUAL(123.456, fd.getPluralOperand(PLURAL_OPERAND_N)); // n | |
701 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
702 | ASSERT_EQUAL(TRUE, fd.isNegative()); | |
703 | ||
704 | // test max int digits | |
705 | df->setMaximumIntegerDigits(2); | |
706 | df->formatToDecimalQuantity(123.456, fd, status); | |
707 | assertSuccess(WHERE, status); | |
708 | ASSERT_EQUAL(3, fd.getPluralOperand(PLURAL_OPERAND_V)); // v | |
709 | ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_F)); // f | |
710 | ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_T)); // t | |
711 | ASSERT_EQUAL(23, fd.getPluralOperand(PLURAL_OPERAND_I)); // i | |
712 | ASSERT_EQUAL(23.456, fd.getPluralOperand(PLURAL_OPERAND_N)); // n | |
713 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
714 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
715 | ||
716 | df->formatToDecimalQuantity(-123.456, fd, status); | |
717 | assertSuccess(WHERE, status); | |
718 | ASSERT_EQUAL(3, fd.getPluralOperand(PLURAL_OPERAND_V)); // v | |
719 | ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_F)); // f | |
720 | ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_T)); // t | |
721 | ASSERT_EQUAL(23, fd.getPluralOperand(PLURAL_OPERAND_I)); // i | |
722 | ASSERT_EQUAL(23.456, fd.getPluralOperand(PLURAL_OPERAND_N)); // n | |
723 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
724 | ASSERT_EQUAL(TRUE, fd.isNegative()); | |
725 | ||
726 | // test max fraction digits | |
727 | df->setMaximumIntegerDigits(2000000000); | |
728 | df->setMaximumFractionDigits(2); | |
729 | df->formatToDecimalQuantity(123.456, fd, status); | |
730 | assertSuccess(WHERE, status); | |
731 | ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); // v | |
732 | ASSERT_EQUAL(46, fd.getPluralOperand(PLURAL_OPERAND_F)); // f | |
733 | ASSERT_EQUAL(46, fd.getPluralOperand(PLURAL_OPERAND_T)); // t | |
734 | ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I)); // i | |
735 | ASSERT_EQUAL(123.46, fd.getPluralOperand(PLURAL_OPERAND_N)); // n | |
736 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
737 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
738 | ||
739 | df->formatToDecimalQuantity(-123.456, fd, status); | |
740 | assertSuccess(WHERE, status); | |
741 | ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); // v | |
742 | ASSERT_EQUAL(46, fd.getPluralOperand(PLURAL_OPERAND_F)); // f | |
743 | ASSERT_EQUAL(46, fd.getPluralOperand(PLURAL_OPERAND_T)); // t | |
744 | ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I)); // i | |
745 | ASSERT_EQUAL(123.46, fd.getPluralOperand(PLURAL_OPERAND_N)); // n | |
746 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
747 | ASSERT_EQUAL(TRUE, fd.isNegative()); | |
748 | ||
749 | // test esoteric rounding | |
750 | df->setMaximumFractionDigits(6); | |
751 | df->setRoundingIncrement(7.3); | |
752 | ||
753 | df->formatToDecimalQuantity(30.0, fd, status); | |
754 | assertSuccess(WHERE, status); | |
755 | ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); // v | |
756 | ASSERT_EQUAL(20, fd.getPluralOperand(PLURAL_OPERAND_F)); // f | |
757 | ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_T)); // t | |
758 | ASSERT_EQUAL(29, fd.getPluralOperand(PLURAL_OPERAND_I)); // i | |
759 | ASSERT_EQUAL(29.2, fd.getPluralOperand(PLURAL_OPERAND_N)); // n | |
760 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
761 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
762 | ||
763 | df->formatToDecimalQuantity(-30.0, fd, status); | |
764 | assertSuccess(WHERE, status); | |
765 | ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); // v | |
766 | ASSERT_EQUAL(20, fd.getPluralOperand(PLURAL_OPERAND_F)); // f | |
767 | ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_T)); // t | |
768 | ASSERT_EQUAL(29, fd.getPluralOperand(PLURAL_OPERAND_I)); // i | |
769 | ASSERT_EQUAL(29.2, fd.getPluralOperand(PLURAL_OPERAND_N)); // n | |
770 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
771 | ASSERT_EQUAL(TRUE, fd.isNegative()); | |
772 | ||
773 | df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###", status), status); | |
774 | assertSuccess(WHERE, status); | |
775 | df->formatToDecimalQuantity(123.456, fd, status); | |
776 | assertSuccess(WHERE, status); | |
777 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
778 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
779 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
780 | ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
781 | ASSERT_EQUAL(TRUE, fd.hasIntegerValue()); | |
782 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
783 | ||
784 | df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.0", status), status); | |
785 | assertSuccess(WHERE, status); | |
786 | df->formatToDecimalQuantity(123.01, fd, status); | |
787 | assertSuccess(WHERE, status); | |
788 | ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
789 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
790 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
791 | ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
792 | ASSERT_EQUAL(TRUE, fd.hasIntegerValue()); | |
793 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
794 | ||
795 | df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.0", status), status); | |
796 | assertSuccess(WHERE, status); | |
797 | df->formatToDecimalQuantity(123.06, fd, status); | |
798 | assertSuccess(WHERE, status); | |
799 | ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
800 | ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
801 | ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
802 | ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
803 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
804 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
805 | ||
806 | df.adoptInsteadAndCheckErrorCode(new DecimalFormat("@@@@@", status), status); // Significant Digits | |
807 | assertSuccess(WHERE, status); | |
808 | df->formatToDecimalQuantity(123, fd, status); | |
809 | assertSuccess(WHERE, status); | |
810 | ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
811 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
812 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
813 | ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
814 | ASSERT_EQUAL(TRUE, fd.hasIntegerValue()); | |
815 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
816 | ||
817 | df.adoptInsteadAndCheckErrorCode(new DecimalFormat("@@@@@", status), status); // Significant Digits | |
818 | assertSuccess(WHERE, status); | |
819 | df->formatToDecimalQuantity(1.23, fd, status); | |
820 | assertSuccess(WHERE, status); | |
821 | ASSERT_EQUAL(4, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
822 | ASSERT_EQUAL(2300, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
823 | ASSERT_EQUAL(23, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
824 | ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
825 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
826 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
827 | ||
828 | df->formatToDecimalQuantity(uprv_getInfinity(), fd, status); | |
829 | assertSuccess(WHERE, status); | |
830 | ASSERT_EQUAL(TRUE, fd.isNaN() || fd.isInfinite()); | |
831 | df->formatToDecimalQuantity(0.0, fd, status); | |
832 | ASSERT_EQUAL(FALSE, fd.isNaN() || fd.isInfinite()); | |
833 | df->formatToDecimalQuantity(uprv_getNaN(), fd, status); | |
834 | ASSERT_EQUAL(TRUE, fd.isNaN() || fd.isInfinite()); | |
835 | assertSuccess(WHERE, status); | |
836 | ||
837 | // Test Big Decimal input. | |
838 | // 22 digits before and after decimal, will exceed the precision of a double | |
839 | // and force DecimalFormat::getFixedDecimal() to work with a digit list. | |
840 | df.adoptInsteadAndCheckErrorCode( | |
841 | new DecimalFormat("#####################0.00####################", status), status); | |
842 | assertSuccess(WHERE, status); | |
843 | Formattable fable("12.34", status); | |
844 | assertSuccess(WHERE, status); | |
845 | df->formatToDecimalQuantity(fable, fd, status); | |
846 | assertSuccess(WHERE, status); | |
847 | ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
848 | ASSERT_EQUAL(34, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
849 | ASSERT_EQUAL(34, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
850 | ASSERT_EQUAL(12, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
851 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
852 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
853 | ||
854 | fable.setDecimalNumber("12.3456789012345678900123456789", status); | |
855 | assertSuccess(WHERE, status); | |
856 | df->formatToDecimalQuantity(fable, fd, status); | |
857 | assertSuccess(WHERE, status); | |
858 | ASSERT_EQUAL(22, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
859 | ASSERT_EQUAL(3456789012345678900LL, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
860 | ASSERT_EQUAL(34567890123456789LL, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
861 | ASSERT_EQUAL(12, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
862 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
863 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
864 | ||
865 | // On field overflow, Integer part is truncated on the left, fraction part on the right. | |
866 | fable.setDecimalNumber("123456789012345678901234567890.123456789012345678901234567890", status); | |
867 | assertSuccess(WHERE, status); | |
868 | df->formatToDecimalQuantity(fable, fd, status); | |
869 | assertSuccess(WHERE, status); | |
870 | ASSERT_EQUAL(22, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
871 | ASSERT_EQUAL(1234567890123456789LL, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
872 | ASSERT_EQUAL(1234567890123456789LL, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
873 | ASSERT_EQUAL(345678901234567890LL, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
874 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
875 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
876 | ||
877 | // Digits way to the right of the decimal but within the format's precision aren't truncated | |
878 | fable.setDecimalNumber("1.0000000000000000000012", status); | |
879 | assertSuccess(WHERE, status); | |
880 | df->formatToDecimalQuantity(fable, fd, status); | |
881 | assertSuccess(WHERE, status); | |
882 | ASSERT_EQUAL(22, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
883 | ASSERT_EQUAL(12, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
884 | ASSERT_EQUAL(12, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
885 | ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
886 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
887 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
888 | ||
889 | // Digits beyond the precision of the format are rounded away | |
890 | fable.setDecimalNumber("1.000000000000000000000012", status); | |
891 | assertSuccess(WHERE, status); | |
892 | df->formatToDecimalQuantity(fable, fd, status); | |
893 | assertSuccess(WHERE, status); | |
894 | ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
895 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
896 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
897 | ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
898 | ASSERT_EQUAL(TRUE, fd.hasIntegerValue()); | |
899 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
900 | ||
901 | // Negative numbers come through | |
902 | fable.setDecimalNumber("-1.0000000000000000000012", status); | |
903 | assertSuccess(WHERE, status); | |
904 | df->formatToDecimalQuantity(fable, fd, status); | |
905 | assertSuccess(WHERE, status); | |
906 | ASSERT_EQUAL(22, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
907 | ASSERT_EQUAL(12, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
908 | ASSERT_EQUAL(12, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
909 | ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
910 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
911 | ASSERT_EQUAL(TRUE, fd.isNegative()); | |
912 | ||
913 | // MinFractionDigits from format larger than from number. | |
914 | fable.setDecimalNumber("1000000000000000000000.3", status); | |
915 | assertSuccess(WHERE, status); | |
916 | df->formatToDecimalQuantity(fable, fd, status); | |
917 | assertSuccess(WHERE, status); | |
918 | ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
919 | ASSERT_EQUAL(30, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
920 | ASSERT_EQUAL(3, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
921 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
922 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
923 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
924 | ||
925 | fable.setDecimalNumber("1000000000000000050000.3", status); | |
926 | assertSuccess(WHERE, status); | |
927 | df->formatToDecimalQuantity(fable, fd, status); | |
928 | assertSuccess(WHERE, status); | |
929 | ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
930 | ASSERT_EQUAL(30, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
931 | ASSERT_EQUAL(3, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
932 | ASSERT_EQUAL(50000LL, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
933 | ASSERT_EQUAL(FALSE, fd.hasIntegerValue()); | |
934 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
935 | ||
936 | // Test some int64_t values that are out of the range of a double | |
937 | fable.setInt64(4503599627370496LL); | |
938 | assertSuccess(WHERE, status); | |
939 | df->formatToDecimalQuantity(fable, fd, status); | |
940 | assertSuccess(WHERE, status); | |
941 | ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
942 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
943 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
944 | ASSERT_EQUAL(4503599627370496LL, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
945 | ASSERT_EQUAL(TRUE, fd.hasIntegerValue()); | |
946 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
947 | ||
948 | fable.setInt64(4503599627370497LL); | |
949 | assertSuccess(WHERE, status); | |
950 | df->formatToDecimalQuantity(fable, fd, status); | |
951 | assertSuccess(WHERE, status); | |
952 | ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
953 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
954 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
955 | ASSERT_EQUAL(4503599627370497LL, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
956 | ASSERT_EQUAL(TRUE, fd.hasIntegerValue()); | |
957 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
958 | ||
959 | fable.setInt64(9223372036854775807LL); | |
960 | assertSuccess(WHERE, status); | |
961 | df->formatToDecimalQuantity(fable, fd, status); | |
962 | assertSuccess(WHERE, status); | |
963 | ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); | |
964 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_F)); | |
965 | ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_T)); | |
966 | // note: going through DigitList path to FixedDecimal, which is trimming | |
967 | // int64_t fields to 18 digits. See ticket Ticket #10374 | |
968 | ASSERT_EQUAL(223372036854775807LL, fd.getPluralOperand(PLURAL_OPERAND_I)); | |
969 | ASSERT_EQUAL(TRUE, fd.hasIntegerValue()); | |
970 | ASSERT_EQUAL(FALSE, fd.isNegative()); | |
971 | ||
972 | } | |
973 | #if defined(_MSC_VER) | |
974 | // Re-enable 4805 warnings (comparisons between int and bool). | |
975 | #pragma warning(pop) | |
976 | #endif | |
977 | ||
978 | void IntlTestDecimalFormatAPI::TestBadFastpath() { | |
979 | UErrorCode status = U_ZERO_ERROR; | |
980 | ||
981 | LocalPointer<DecimalFormat> df(new DecimalFormat("###", status), status); | |
982 | if (U_FAILURE(status)) { | |
983 | dataerrln("Error creating new DecimalFormat - %s", u_errorName(status)); | |
984 | return; | |
985 | } | |
986 | ||
987 | UnicodeString fmt; | |
988 | fmt.remove(); | |
989 | assertEquals("Format 1234", "1234", df->format((int32_t)1234, fmt)); | |
990 | df->setGroupingUsed(FALSE); | |
991 | fmt.remove(); | |
992 | assertEquals("Format 1234", "1234", df->format((int32_t)1234, fmt)); | |
993 | df->setGroupingUsed(TRUE); | |
994 | df->setGroupingSize(3); | |
995 | fmt.remove(); | |
996 | assertEquals("Format 1234 w/ grouping", "1,234", df->format((int32_t)1234, fmt)); | |
997 | } | |
998 | ||
999 | void IntlTestDecimalFormatAPI::TestRequiredDecimalPoint() { | |
1000 | UErrorCode status = U_ZERO_ERROR; | |
1001 | UnicodeString text("99"); | |
1002 | Formattable result1; | |
1003 | UnicodeString pat1("##.0000"); | |
1004 | UnicodeString pat2("00.0"); | |
1005 | ||
1006 | LocalPointer<DecimalFormat> df(new DecimalFormat(pat1, status), status); | |
1007 | if (U_FAILURE(status)) { | |
1008 | dataerrln("Error creating new DecimalFormat - %s", u_errorName(status)); | |
1009 | return; | |
1010 | } | |
1011 | ||
1012 | status = U_ZERO_ERROR; | |
1013 | df->applyPattern(pat1, status); | |
1014 | if(U_FAILURE(status)) { | |
1015 | errln((UnicodeString)"ERROR: applyPattern() failed"); | |
1016 | } | |
1017 | df->parse(text, result1, status); | |
1018 | if(U_FAILURE(status)) { | |
1019 | errln((UnicodeString)"ERROR: parse() failed"); | |
1020 | } | |
1021 | df->setDecimalPatternMatchRequired(TRUE); | |
1022 | df->parse(text, result1, status); | |
1023 | if(U_SUCCESS(status)) { | |
1024 | errln((UnicodeString)"ERROR: unexpected parse()"); | |
1025 | } | |
1026 | ||
1027 | ||
1028 | status = U_ZERO_ERROR; | |
1029 | df->applyPattern(pat2, status); | |
1030 | df->setDecimalPatternMatchRequired(FALSE); | |
1031 | if(U_FAILURE(status)) { | |
1032 | errln((UnicodeString)"ERROR: applyPattern(2) failed"); | |
1033 | } | |
1034 | df->parse(text, result1, status); | |
1035 | if(U_FAILURE(status)) { | |
1036 | errln((UnicodeString)"ERROR: parse(2) failed - " + u_errorName(status)); | |
1037 | } | |
1038 | df->setDecimalPatternMatchRequired(TRUE); | |
1039 | df->parse(text, result1, status); | |
1040 | if(U_SUCCESS(status)) { | |
1041 | errln((UnicodeString)"ERROR: unexpected parse(2)"); | |
1042 | } | |
1043 | } | |
1044 | ||
1045 | void IntlTestDecimalFormatAPI::testErrorCode() { | |
1046 | // Try each DecimalFormat constructor with an errorCode set on input, | |
1047 | // Verify no crashes or leaks, and that the errorCode is not altered. | |
1048 | ||
1049 | UErrorCode status = U_ZERO_ERROR; | |
1050 | const UnicodeString pattern(u"0.###E0"); | |
1051 | UParseError pe; | |
1052 | DecimalFormatSymbols symbols(Locale::getUS(), status); | |
1053 | assertSuccess(WHERE, status); | |
1054 | ||
1055 | { | |
1056 | status = U_INTERNAL_PROGRAM_ERROR; | |
1057 | DecimalFormat df(status); | |
1058 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1059 | } | |
1060 | { | |
1061 | status = U_INTERNAL_PROGRAM_ERROR; | |
1062 | DecimalFormat df(pattern, status); | |
1063 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1064 | } | |
1065 | { | |
1066 | status = U_INTERNAL_PROGRAM_ERROR; | |
1067 | DecimalFormat df(pattern, new DecimalFormatSymbols(symbols), status); | |
1068 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1069 | } | |
1070 | { | |
1071 | status = U_INTERNAL_PROGRAM_ERROR; | |
1072 | DecimalFormat df(pattern, new DecimalFormatSymbols(symbols), UNUM_DECIMAL_COMPACT_LONG, status); | |
1073 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1074 | } | |
1075 | { | |
1076 | status = U_INTERNAL_PROGRAM_ERROR; | |
1077 | DecimalFormat df(pattern, new DecimalFormatSymbols(symbols), pe, status); | |
1078 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1079 | } | |
1080 | { | |
1081 | status = U_INTERNAL_PROGRAM_ERROR; | |
1082 | DecimalFormat df(pattern, symbols ,status); | |
1083 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1084 | } | |
1085 | ||
1086 | // Try each DecimalFormat method with an error code parameter, verifying that | |
1087 | // an input error is not altered, and that no segmentation faults occur. | |
1088 | ||
1089 | status = U_INTERNAL_PROGRAM_ERROR; | |
1090 | DecimalFormat dfBogus(status); | |
1091 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1092 | ||
1093 | status = U_ZERO_ERROR; | |
1094 | DecimalFormat dfGood(pattern, new DecimalFormatSymbols(symbols), status); | |
1095 | assertSuccess(WHERE, status); | |
1096 | ||
1097 | for (DecimalFormat *df: {&dfBogus, &dfGood}) { | |
1098 | status = U_INTERNAL_PROGRAM_ERROR; | |
1099 | df->setAttribute(UNUM_PARSE_INT_ONLY, 0, status); | |
1100 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1101 | ||
1102 | status = U_INTERNAL_PROGRAM_ERROR; | |
1103 | df->getAttribute(UNUM_MAX_FRACTION_DIGITS, status); | |
1104 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1105 | ||
1106 | status = U_INTERNAL_PROGRAM_ERROR; | |
1107 | UnicodeString dest; | |
1108 | FieldPosition fp; | |
1109 | df->format(1.2, dest, fp, status); | |
1110 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1111 | ||
1112 | status = U_INTERNAL_PROGRAM_ERROR; | |
1113 | df->format(1.2, dest, nullptr, status); | |
1114 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1115 | ||
1116 | status = U_INTERNAL_PROGRAM_ERROR; | |
1117 | df->format((int32_t)666, dest, nullptr, status); | |
1118 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1119 | ||
1120 | status = U_INTERNAL_PROGRAM_ERROR; | |
1121 | df->format((int64_t)666, dest, nullptr, status); | |
1122 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1123 | ||
1124 | status = U_INTERNAL_PROGRAM_ERROR; | |
1125 | df->format(StringPiece("3.1415926535897932384626"), dest, nullptr, status); | |
1126 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1127 | ||
1128 | status = U_INTERNAL_PROGRAM_ERROR; | |
1129 | df->applyPattern(pattern, status); | |
1130 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1131 | ||
1132 | status = U_INTERNAL_PROGRAM_ERROR; | |
1133 | df->applyLocalizedPattern(pattern, pe, status); | |
1134 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1135 | ||
1136 | status = U_INTERNAL_PROGRAM_ERROR; | |
1137 | df->applyLocalizedPattern(pattern, status); | |
1138 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1139 | ||
1140 | status = U_INTERNAL_PROGRAM_ERROR; | |
1141 | df->setCurrency(u"USD", status); | |
1142 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1143 | ||
1144 | status = U_INTERNAL_PROGRAM_ERROR; | |
1145 | df->setCurrencyUsage(UCURR_USAGE_CASH, &status); | |
1146 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1147 | } | |
1148 | } | |
1149 | ||
1150 | void IntlTestDecimalFormatAPI::testInvalidObject() { | |
1151 | { | |
1152 | UErrorCode status = U_INTERNAL_PROGRAM_ERROR; | |
1153 | DecimalFormat dfBogus(status); | |
1154 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1155 | ||
1156 | status = U_ZERO_ERROR; | |
1157 | DecimalFormat dfGood(status); | |
1158 | assertSuccess(WHERE, status); | |
1159 | ||
1160 | // An invalid object should not be equal to a valid object. | |
1161 | // This also tests that no segmentation fault occurs in the comparison operator due | |
1162 | // to any dangling/nullptr pointers. (ICU-20381). | |
1163 | assertTrue(WHERE, dfGood != dfBogus); | |
1164 | ||
1165 | status = U_MEMORY_ALLOCATION_ERROR; | |
1166 | DecimalFormat dfBogus2(status); | |
1167 | assertEquals(WHERE, U_MEMORY_ALLOCATION_ERROR, status); | |
1168 | ||
1169 | // Two invalid objects should not be equal. | |
1170 | // (Also verify that nullptr isn't t dereferenced in the comparision operator.) | |
1171 | assertTrue(WHERE, dfBogus != dfBogus2); | |
1172 | ||
1173 | // Verify the comparison operator works for two valid objects. | |
1174 | status = U_ZERO_ERROR; | |
1175 | DecimalFormat dfGood2(status); | |
1176 | assertSuccess(WHERE, status); | |
1177 | assertTrue(WHERE, dfGood == dfGood2); | |
1178 | ||
1179 | // Verify that the assignment operator sets the object to an invalid state, and | |
1180 | // that no segmentation fault occurs due to any dangling/nullptr pointers. | |
1181 | status = U_INTERNAL_PROGRAM_ERROR; | |
1182 | DecimalFormat dfAssignmentBogus = DecimalFormat(status); | |
1183 | // Verify comparison for the assigned object. | |
1184 | assertTrue(WHERE, dfAssignmentBogus != dfGood); | |
1185 | assertTrue(WHERE, dfAssignmentBogus != dfGood2); | |
1186 | assertTrue(WHERE, dfAssignmentBogus != dfBogus); | |
1187 | ||
1188 | // Verify that cloning our original invalid object gives nullptr. | |
1189 | auto dfBogusClone = dfBogus.clone(); | |
1190 | assertTrue(WHERE, dfBogusClone == nullptr); | |
1191 | // Verify that cloning our assigned invalid object gives nullptr. | |
1192 | auto dfBogusClone2 = dfAssignmentBogus.clone(); | |
1193 | assertTrue(WHERE, dfBogusClone2 == nullptr); | |
1194 | ||
1195 | // Verify copy constructing from an invalid object is also invalid. | |
1196 | DecimalFormat dfCopy(dfBogus); | |
1197 | assertTrue(WHERE, dfCopy != dfGood); | |
1198 | assertTrue(WHERE, dfCopy != dfGood2); | |
1199 | assertTrue(WHERE, dfCopy != dfBogus); | |
1200 | DecimalFormat dfCopyAssign = dfBogus; | |
1201 | assertTrue(WHERE, dfCopyAssign != dfGood); | |
1202 | assertTrue(WHERE, dfCopyAssign != dfGood2); | |
1203 | assertTrue(WHERE, dfCopyAssign != dfBogus); | |
1204 | auto dfBogusCopyClone1 = dfCopy.clone(); | |
1205 | auto dfBogusCopyClone2 = dfCopyAssign.clone(); | |
1206 | assertTrue(WHERE, dfBogusCopyClone1 == nullptr); | |
1207 | assertTrue(WHERE, dfBogusCopyClone2 == nullptr); | |
1208 | } | |
1209 | ||
1210 | { | |
1211 | // Try each DecimalFormat class method that lacks an error code parameter, verifying | |
1212 | // we don't crash (segmentation fault) on invalid objects. | |
1213 | ||
1214 | UErrorCode status = U_ZERO_ERROR; | |
1215 | const UnicodeString pattern(u"0.###E0"); | |
1216 | UParseError pe; | |
1217 | DecimalFormatSymbols symbols(Locale::getUS(), status); | |
1218 | assertSuccess(WHERE, status); | |
1219 | CurrencyPluralInfo currencyPI(status); | |
1220 | assertSuccess(WHERE, status); | |
1221 | ||
1222 | status = U_INTERNAL_PROGRAM_ERROR; | |
1223 | DecimalFormat dfBogus1(status); | |
1224 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1225 | ||
1226 | status = U_INTERNAL_PROGRAM_ERROR; | |
1227 | DecimalFormat dfBogus2(pattern, status); | |
1228 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1229 | ||
1230 | status = U_INTERNAL_PROGRAM_ERROR; | |
1231 | DecimalFormat dfBogus3(pattern, new DecimalFormatSymbols(symbols), status); | |
1232 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1233 | ||
1234 | status = U_INTERNAL_PROGRAM_ERROR; | |
1235 | DecimalFormat dfBogus4(pattern, new DecimalFormatSymbols(symbols), UNumberFormatStyle::UNUM_CURRENCY, status); | |
1236 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1237 | ||
1238 | status = U_INTERNAL_PROGRAM_ERROR; | |
1239 | DecimalFormat dfBogus5(pattern, new DecimalFormatSymbols(symbols), pe, status); | |
1240 | assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status); | |
1241 | ||
1242 | for (DecimalFormat *df : {&dfBogus1, &dfBogus2, &dfBogus3, &dfBogus4, &dfBogus5}) | |
1243 | { | |
1244 | df->setGroupingUsed(true); | |
1245 | ||
1246 | df->setParseIntegerOnly(false); | |
1247 | ||
1248 | df->setLenient(true); | |
1249 | ||
1250 | auto dfClone = df->clone(); | |
1251 | assertTrue(WHERE, dfClone == nullptr); | |
1252 | ||
1253 | UnicodeString dest; | |
1254 | FieldPosition fp; | |
1255 | df->format(1.2, dest, fp); | |
1256 | df->format(static_cast<int32_t>(1234), dest, fp); | |
1257 | df->format(static_cast<int64_t>(1234), dest, fp); | |
1258 | ||
1259 | UnicodeString text("-1,234.00"); | |
1260 | Formattable result; | |
1261 | ParsePosition pos(0); | |
1262 | df->parse(text, result, pos); | |
1263 | ||
1264 | CurrencyAmount* ca = df->parseCurrency(text, pos); | |
1265 | assertTrue(WHERE, ca == nullptr); | |
1266 | ||
1267 | const DecimalFormatSymbols* dfs = df->getDecimalFormatSymbols(); | |
1268 | assertTrue(WHERE, dfs == nullptr); | |
1269 | ||
1270 | df->adoptDecimalFormatSymbols(nullptr); | |
1271 | ||
1272 | df->setDecimalFormatSymbols(symbols); | |
1273 | ||
1274 | const CurrencyPluralInfo* cpi = df->getCurrencyPluralInfo(); | |
1275 | assertTrue(WHERE, cpi == nullptr); | |
1276 | ||
1277 | df->adoptCurrencyPluralInfo(nullptr); | |
1278 | ||
1279 | df->setCurrencyPluralInfo(currencyPI); | |
1280 | ||
1281 | UnicodeString prefix("-123"); | |
1282 | df->getPositivePrefix(dest); | |
1283 | df->setPositivePrefix(prefix); | |
1284 | df->getNegativePrefix(dest); | |
1285 | df->setNegativePrefix(prefix); | |
1286 | df->getPositiveSuffix(dest); | |
1287 | df->setPositiveSuffix(prefix); | |
1288 | df->getNegativeSuffix(dest); | |
1289 | df->setNegativeSuffix(prefix); | |
1290 | ||
1291 | df->isSignAlwaysShown(); | |
1292 | ||
1293 | df->setSignAlwaysShown(true); | |
1294 | ||
1295 | df->getMultiplier(); | |
1296 | df->setMultiplier(10); | |
1297 | ||
1298 | df->getMultiplierScale(); | |
1299 | df->setMultiplierScale(2); | |
1300 | ||
1301 | df->getRoundingIncrement(); | |
1302 | df->setRoundingIncrement(1.2); | |
1303 | ||
1304 | df->getRoundingMode(); | |
1305 | df->setRoundingMode(DecimalFormat::ERoundingMode::kRoundDown); | |
1306 | ||
1307 | df->getFormatWidth(); | |
1308 | df->setFormatWidth(0); | |
1309 | ||
1310 | UnicodeString pad(" "); | |
1311 | df->getPadCharacterString(); | |
1312 | df->setPadCharacter(pad); | |
1313 | ||
1314 | df->getPadPosition(); | |
1315 | df->setPadPosition(DecimalFormat::EPadPosition::kPadBeforePrefix); | |
1316 | ||
1317 | df->isScientificNotation(); | |
1318 | df->setScientificNotation(false); | |
1319 | ||
1320 | df->getMinimumExponentDigits(); | |
1321 | df->setMinimumExponentDigits(1); | |
1322 | ||
1323 | df->isExponentSignAlwaysShown(); | |
1324 | df->setExponentSignAlwaysShown(true); | |
1325 | ||
1326 | df->getGroupingSize(); | |
1327 | df->setGroupingSize(3); | |
1328 | ||
1329 | df->getSecondaryGroupingSize(); | |
1330 | df->setSecondaryGroupingSize(-1); | |
1331 | ||
1332 | df->getMinimumGroupingDigits(); | |
1333 | df->setMinimumGroupingDigits(-1); | |
1334 | ||
1335 | df->isDecimalSeparatorAlwaysShown(); | |
1336 | df->setDecimalSeparatorAlwaysShown(true); | |
1337 | ||
1338 | df->isDecimalPatternMatchRequired(); | |
1339 | df->setDecimalPatternMatchRequired(false); | |
1340 | ||
1341 | df->isParseNoExponent(); | |
1342 | df->setParseNoExponent(true); | |
1343 | ||
1344 | df->isParseCaseSensitive(); | |
1345 | df->setParseCaseSensitive(false); | |
1346 | ||
1347 | df->isFormatFailIfMoreThanMaxDigits(); | |
1348 | df->setFormatFailIfMoreThanMaxDigits(true); | |
1349 | ||
1350 | df->toPattern(dest); | |
1351 | df->toLocalizedPattern(dest); | |
1352 | ||
1353 | df->setMaximumIntegerDigits(10); | |
1354 | df->setMinimumIntegerDigits(0); | |
1355 | ||
1356 | df->setMaximumFractionDigits(2); | |
1357 | df->setMinimumFractionDigits(0); | |
1358 | ||
1359 | df->getMinimumSignificantDigits(); | |
1360 | df->setMinimumSignificantDigits(0); | |
1361 | ||
1362 | df->getMaximumSignificantDigits(); | |
1363 | df->setMaximumSignificantDigits(5); | |
1364 | ||
1365 | df->areSignificantDigitsUsed(); | |
1366 | df->setSignificantDigitsUsed(true); | |
1367 | ||
1368 | df->setCurrency(u"USD"); | |
1369 | ||
1370 | df->getCurrencyUsage(); | |
1371 | ||
1372 | const number::LocalizedNumberFormatter* lnf = df->toNumberFormatter(status); | |
1373 | assertEquals("toNumberFormatter should return nullptr", | |
1374 | (int64_t) nullptr, (int64_t) lnf); | |
1375 | ||
1376 | // Should not crash when chaining to error code enabled methods on the LNF | |
1377 | lnf->formatInt(1, status); | |
1378 | lnf->formatDouble(1.0, status); | |
1379 | lnf->formatDecimal("1", status); | |
1380 | lnf->toFormat(status); | |
1381 | lnf->toSkeleton(status); | |
1382 | lnf->copyErrorTo(status); | |
1383 | } | |
1384 | ||
1385 | } | |
1386 | } | |
1387 | ||
1388 | #endif /* #if !UCONFIG_NO_FORMATTING */ |