1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /***********************************************************************
5 * Copyright (c) 1997-2010, International Business Machines Corporation
6 * and others. All Rights Reserved.
7 ***********************************************************************/
9 #include "unicode/utypes.h"
11 #if !UCONFIG_NO_FORMATTING
15 #include "unicode/numfmt.h"
16 #include "unicode/decimfmt.h"
17 #include "unicode/locid.h"
18 #include "unicode/unum.h"
19 #include "unicode/strenum.h"
21 // This is an API test, not a unit test. It doesn't test very many cases, and doesn't
22 // try to test the full functionality. It just calls each function in the class and
23 // verifies that it works on a basic level.
25 void IntlTestNumberFormatAPI::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
27 if (exec
) logln("TestSuite NumberFormatAPI");
29 case 0: name
= "NumberFormat API test";
31 logln("NumberFormat API test---"); logln("");
32 UErrorCode status
= U_ZERO_ERROR
;
34 Locale::setDefault(Locale::getEnglish(), status
);
35 if(U_FAILURE(status
)) {
36 errln("ERROR: Could not set default locale, test may not give correct results");
39 Locale::setDefault(saveLocale
, status
);
42 case 1: name
= "NumberFormatRegistration";
44 logln("NumberFormat Registration test---"); logln("");
45 UErrorCode status
= U_ZERO_ERROR
;
47 Locale::setDefault(Locale::getEnglish(), status
);
48 if(U_FAILURE(status
)) {
49 errln("ERROR: Could not set default locale, test may not give correct results");
52 Locale::setDefault(saveLocale
, status
);
55 default: name
= ""; break;
60 * This test does round-trip testing (format -> parse -> format -> parse -> etc.) of
63 void IntlTestNumberFormatAPI::testAPI(/* char* par */)
65 UErrorCode status
= U_ZERO_ERROR
;
67 // ======= Test constructors
69 logln("Testing NumberFormat constructors");
71 NumberFormat
*def
= NumberFormat::createInstance(status
);
72 if(U_FAILURE(status
)) {
73 dataerrln("ERROR: Could not create NumberFormat (default) - %s", u_errorName(status
));
76 status
= U_ZERO_ERROR
;
77 NumberFormat
*fr
= NumberFormat::createInstance(Locale::getFrench(), status
);
78 if(U_FAILURE(status
)) {
79 dataerrln("ERROR: Could not create NumberFormat (French) - %s", u_errorName(status
));
82 NumberFormat
*cur
= NumberFormat::createCurrencyInstance(status
);
83 if(U_FAILURE(status
)) {
84 dataerrln("ERROR: Could not create NumberFormat (currency, default) - %s", u_errorName(status
));
87 status
= U_ZERO_ERROR
;
88 NumberFormat
*cur_fr
= NumberFormat::createCurrencyInstance(Locale::getFrench(), status
);
89 if(U_FAILURE(status
)) {
90 dataerrln("ERROR: Could not create NumberFormat (currency, French) - %s", u_errorName(status
));
93 NumberFormat
*per
= NumberFormat::createPercentInstance(status
);
94 if(U_FAILURE(status
)) {
95 dataerrln("ERROR: Could not create NumberFormat (percent, default) - %s", u_errorName(status
));
98 status
= U_ZERO_ERROR
;
99 NumberFormat
*per_fr
= NumberFormat::createPercentInstance(Locale::getFrench(), status
);
100 if(U_FAILURE(status
)) {
101 dataerrln("ERROR: Could not create NumberFormat (percent, French) - %s", u_errorName(status
));
104 // ======= Test equality
105 if (per_fr
!= NULL
&& cur_fr
!= NULL
)
107 logln("Testing equality operator");
109 if( *per_fr
== *cur_fr
|| ! ( *per_fr
!= *cur_fr
) ) {
110 errln("ERROR: == failed");
114 // ======= Test various format() methods
117 logln("Testing various format() methods");
119 double d
= -10456.0037;
120 int32_t l
= 100000000;
124 UnicodeString res1
, res2
, res3
, res4
, res5
, res6
;
125 FieldPosition
pos1(FieldPosition::DONT_CARE
), pos2(FieldPosition::DONT_CARE
), pos3(FieldPosition::DONT_CARE
), pos4(FieldPosition::DONT_CARE
);
127 res1
= cur_fr
->format(d
, res1
);
128 logln( (UnicodeString
) "" + (int32_t) d
+ " formatted to " + res1
);
130 res2
= cur_fr
->format(l
, res2
);
131 logln((UnicodeString
) "" + (int32_t) l
+ " formatted to " + res2
);
133 res3
= cur_fr
->format(d
, res3
, pos1
);
134 logln( (UnicodeString
) "" + (int32_t) d
+ " formatted to " + res3
);
136 res4
= cur_fr
->format(l
, res4
, pos2
);
137 logln((UnicodeString
) "" + (int32_t) l
+ " formatted to " + res4
);
139 status
= U_ZERO_ERROR
;
140 res5
= cur_fr
->format(fD
, res5
, pos3
, status
);
141 if(U_FAILURE(status
)) {
142 errln("ERROR: format(Formattable [double]) failed");
144 logln((UnicodeString
) "" + (int32_t) fD
.getDouble() + " formatted to " + res5
);
146 status
= U_ZERO_ERROR
;
147 res6
= cur_fr
->format(fL
, res6
, pos4
, status
);
148 if(U_FAILURE(status
)) {
149 errln("ERROR: format(Formattable [long]) failed");
151 logln((UnicodeString
) "" + fL
.getLong() + " formatted to " + res6
);
154 // ======= Test parse()
157 logln("Testing parse()");
159 double d
= -10456.0037;
160 UnicodeString
text("-10,456.0037");
161 Formattable result1
, result2
, result3
;
162 ParsePosition
pos(0), pos01(0);
163 fr
->parseObject(text
, result1
, pos
);
164 if(result1
.getType() != Formattable::kDouble
&& result1
.getDouble() != d
) {
165 errln("ERROR: Roundtrip failed (via parse()) for " + text
);
167 logln(text
+ " parsed into " + (int32_t) result1
.getDouble());
169 fr
->parse(text
, result2
, pos01
);
170 if(result2
.getType() != Formattable::kDouble
&& result2
.getDouble() != d
) {
171 errln("ERROR: Roundtrip failed (via parse()) for " + text
);
173 logln(text
+ " parsed into " + (int32_t) result2
.getDouble());
175 status
= U_ZERO_ERROR
;
176 fr
->parse(text
, result3
, status
);
177 if(U_FAILURE(status
)) {
178 errln("ERROR: parse() failed");
180 if(result3
.getType() != Formattable::kDouble
&& result3
.getDouble() != d
) {
181 errln("ERROR: Roundtrip failed (via parse()) for " + text
);
183 logln(text
+ " parsed into " + (int32_t) result3
.getDouble());
186 // ======= Test getters and setters
187 if (fr
!= NULL
&& def
!= NULL
)
189 logln("Testing getters and setters");
192 const Locale
*locales
= NumberFormat::getAvailableLocales(count
);
193 logln((UnicodeString
) "Got " + count
+ " locales" );
194 for(int32_t i
= 0; i
< count
; i
++) {
195 UnicodeString
name(locales
[i
].getName(),"");
199 fr
->setParseIntegerOnly( def
->isParseIntegerOnly() );
200 if(fr
->isParseIntegerOnly() != def
->isParseIntegerOnly() ) {
201 errln("ERROR: setParseIntegerOnly() failed");
204 fr
->setGroupingUsed( def
->isGroupingUsed() );
205 if(fr
->isGroupingUsed() != def
->isGroupingUsed() ) {
206 errln("ERROR: setGroupingUsed() failed");
209 fr
->setMaximumIntegerDigits( def
->getMaximumIntegerDigits() );
210 if(fr
->getMaximumIntegerDigits() != def
->getMaximumIntegerDigits() ) {
211 errln("ERROR: setMaximumIntegerDigits() failed");
214 fr
->setMinimumIntegerDigits( def
->getMinimumIntegerDigits() );
215 if(fr
->getMinimumIntegerDigits() != def
->getMinimumIntegerDigits() ) {
216 errln("ERROR: setMinimumIntegerDigits() failed");
219 fr
->setMaximumFractionDigits( def
->getMaximumFractionDigits() );
220 if(fr
->getMaximumFractionDigits() != def
->getMaximumFractionDigits() ) {
221 errln("ERROR: setMaximumFractionDigits() failed");
224 fr
->setMinimumFractionDigits( def
->getMinimumFractionDigits() );
225 if(fr
->getMinimumFractionDigits() != def
->getMinimumFractionDigits() ) {
226 errln("ERROR: setMinimumFractionDigits() failed");
230 // ======= Test getStaticClassID()
232 logln("Testing getStaticClassID()");
234 status
= U_ZERO_ERROR
;
235 NumberFormat
*test
= new DecimalFormat(status
);
236 if(U_FAILURE(status
)) {
237 errcheckln(status
, "ERROR: Couldn't create a NumberFormat - %s", u_errorName(status
));
240 if(test
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
241 errln("ERROR: getDynamicClassID() didn't return the expected value");
253 #if !UCONFIG_NO_SERVICE
255 #define SRC_LOC Locale::getFrance()
256 #define SWAP_LOC Locale::getUS()
258 class NFTestFactory
: public SimpleNumberFormatFactory
{
259 NumberFormat
* currencyStyle
;
263 : SimpleNumberFormatFactory(SRC_LOC
, TRUE
)
265 UErrorCode status
= U_ZERO_ERROR
;
266 currencyStyle
= NumberFormat::createInstance(SWAP_LOC
, status
);
269 virtual ~NFTestFactory()
271 delete currencyStyle
;
274 virtual NumberFormat
* createFormat(const Locale
& /* loc */, UNumberFormatStyle formatType
)
276 if (formatType
== UNUM_CURRENCY
) {
277 return (NumberFormat
*)currencyStyle
->clone();
282 virtual inline UClassID
getDynamicClassID() const
284 return (UClassID
)&gID
;
287 static inline UClassID
getStaticClassID()
289 return (UClassID
)&gID
;
296 char NFTestFactory::gID
= 0;
300 IntlTestNumberFormatAPI::testRegistration()
302 #if !UCONFIG_NO_SERVICE
303 UErrorCode status
= U_ZERO_ERROR
;
305 LocalPointer
<NumberFormat
> f0(NumberFormat::createInstance(SWAP_LOC
, status
));
306 LocalPointer
<NumberFormat
> f1(NumberFormat::createInstance(SRC_LOC
, status
));
307 LocalPointer
<NumberFormat
> f2(NumberFormat::createCurrencyInstance(SRC_LOC
, status
));
308 URegistryKey key
= NumberFormat::registerFactory(new NFTestFactory(), status
);
309 LocalPointer
<NumberFormat
> f3(NumberFormat::createCurrencyInstance(SRC_LOC
, status
));
310 LocalPointer
<NumberFormat
> f3a(NumberFormat::createCurrencyInstance(SRC_LOC
, status
));
311 LocalPointer
<NumberFormat
> f4(NumberFormat::createInstance(SRC_LOC
, status
));
313 StringEnumeration
* locs
= NumberFormat::getAvailableLocales();
315 LocalUNumberFormatPointer
uf3(unum_open(UNUM_CURRENCY
, NULL
, 0, SRC_LOC
.getName(), NULL
, &status
));
316 LocalUNumberFormatPointer
uf4(unum_open(UNUM_DEFAULT
, NULL
, 0, SRC_LOC
.getName(), NULL
, &status
));
318 const UnicodeString
* res
;
319 for (res
= locs
->snext(status
); res
; res
= locs
->snext(status
)) {
320 logln(*res
); // service is still in synch
323 NumberFormat::unregister(key
, status
); // restore for other tests
324 LocalPointer
<NumberFormat
> f5(NumberFormat::createCurrencyInstance(SRC_LOC
, status
));
325 LocalUNumberFormatPointer
uf5(unum_open(UNUM_CURRENCY
, NULL
, 0, SRC_LOC
.getName(), NULL
, &status
));
327 if (U_FAILURE(status
)) {
328 dataerrln("Error creating instnaces.");
332 UnicodeString res0
, res1
, res2
, res3
, res4
, res5
;
344 unum_formatDouble(uf3
.getAlias(), n
, ures3
, 50, NULL
, &status
);
345 unum_formatDouble(uf4
.getAlias(), n
, ures4
, 50, NULL
, &status
);
346 unum_formatDouble(uf5
.getAlias(), n
, ures5
, 50, NULL
, &status
);
348 logln((UnicodeString
)"f0 swap int: " + res0
);
349 logln((UnicodeString
)"f1 src int: " + res1
);
350 logln((UnicodeString
)"f2 src cur: " + res2
);
351 logln((UnicodeString
)"f3 reg cur: " + res3
);
352 logln((UnicodeString
)"f4 reg int: " + res4
);
353 logln((UnicodeString
)"f5 unreg cur: " + res5
);
354 log("uf3 reg cur: ");
356 log("uf4 reg int: ");
358 log("uf5 ureg cur: ");
361 if (f3
.getAlias() == f3a
.getAlias()) {
362 errln("did not get new instance from service");
366 errln("registered service did not match");
369 errln("registered service did not inherit");
372 errln("unregistered service did not match original");
376 errln("registered service did not match / unum");
379 errln("registered service did not inherit / unum");
382 errln("unregistered service did not match original / unum");
386 for (res
= locs
->snext(status
); res
; res
= locs
->snext(status
)) {
387 errln(*res
); // service should be out of synch
390 locs
->reset(status
); // now in synch again, we hope
391 for (res
= locs
->snext(status
); res
; res
= locs
->snext(status
)) {
400 #endif /* #if !UCONFIG_NO_FORMATTING */