]>
Commit | Line | Data |
---|---|---|
f3c0d7a5 A |
1 | // © 2016 and later: Unicode, Inc. and others. |
2 | // License & terms of use: http://www.unicode.org/copyright.html | |
374ca955 | 3 | /*********************************************************************** |
b75a7d8f | 4 | * COPYRIGHT: |
729e4ab9 | 5 | * Copyright (c) 1997-2010, International Business Machines Corporation |
374ca955 A |
6 | * and others. All Rights Reserved. |
7 | ***********************************************************************/ | |
b75a7d8f A |
8 | |
9 | #include "unicode/utypes.h" | |
10 | ||
11 | #if !UCONFIG_NO_FORMATTING | |
12 | ||
13 | #include "nmfmapts.h" | |
14 | ||
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" | |
20 | ||
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. | |
24 | ||
25 | void IntlTestNumberFormatAPI::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) | |
26 | { | |
27 | if (exec) logln("TestSuite NumberFormatAPI"); | |
28 | switch (index) { | |
29 | case 0: name = "NumberFormat API test"; | |
30 | if (exec) { | |
31 | logln("NumberFormat API test---"); logln(""); | |
32 | UErrorCode status = U_ZERO_ERROR; | |
73c04bcf | 33 | Locale saveLocale; |
b75a7d8f A |
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"); | |
37 | } | |
38 | testAPI(/* par */); | |
73c04bcf | 39 | Locale::setDefault(saveLocale, status); |
b75a7d8f A |
40 | } |
41 | break; | |
42 | case 1: name = "NumberFormatRegistration"; | |
43 | if (exec) { | |
44 | logln("NumberFormat Registration test---"); logln(""); | |
45 | UErrorCode status = U_ZERO_ERROR; | |
73c04bcf | 46 | Locale saveLocale; |
b75a7d8f A |
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"); | |
50 | } | |
51 | testRegistration(); | |
73c04bcf | 52 | Locale::setDefault(saveLocale, status); |
b75a7d8f A |
53 | } |
54 | break; | |
55 | default: name = ""; break; | |
56 | } | |
57 | } | |
58 | ||
59 | /** | |
60 | * This test does round-trip testing (format -> parse -> format -> parse -> etc.) of | |
61 | * NumberFormat. | |
62 | */ | |
63 | void IntlTestNumberFormatAPI::testAPI(/* char* par */) | |
64 | { | |
65 | UErrorCode status = U_ZERO_ERROR; | |
66 | ||
67 | // ======= Test constructors | |
68 | ||
69 | logln("Testing NumberFormat constructors"); | |
70 | ||
71 | NumberFormat *def = NumberFormat::createInstance(status); | |
72 | if(U_FAILURE(status)) { | |
729e4ab9 | 73 | dataerrln("ERROR: Could not create NumberFormat (default) - %s", u_errorName(status)); |
b75a7d8f A |
74 | } |
75 | ||
76 | status = U_ZERO_ERROR; | |
77 | NumberFormat *fr = NumberFormat::createInstance(Locale::getFrench(), status); | |
78 | if(U_FAILURE(status)) { | |
729e4ab9 | 79 | dataerrln("ERROR: Could not create NumberFormat (French) - %s", u_errorName(status)); |
b75a7d8f A |
80 | } |
81 | ||
82 | NumberFormat *cur = NumberFormat::createCurrencyInstance(status); | |
83 | if(U_FAILURE(status)) { | |
729e4ab9 | 84 | dataerrln("ERROR: Could not create NumberFormat (currency, default) - %s", u_errorName(status)); |
b75a7d8f A |
85 | } |
86 | ||
87 | status = U_ZERO_ERROR; | |
88 | NumberFormat *cur_fr = NumberFormat::createCurrencyInstance(Locale::getFrench(), status); | |
89 | if(U_FAILURE(status)) { | |
729e4ab9 | 90 | dataerrln("ERROR: Could not create NumberFormat (currency, French) - %s", u_errorName(status)); |
b75a7d8f A |
91 | } |
92 | ||
93 | NumberFormat *per = NumberFormat::createPercentInstance(status); | |
94 | if(U_FAILURE(status)) { | |
729e4ab9 | 95 | dataerrln("ERROR: Could not create NumberFormat (percent, default) - %s", u_errorName(status)); |
b75a7d8f A |
96 | } |
97 | ||
98 | status = U_ZERO_ERROR; | |
99 | NumberFormat *per_fr = NumberFormat::createPercentInstance(Locale::getFrench(), status); | |
100 | if(U_FAILURE(status)) { | |
729e4ab9 | 101 | dataerrln("ERROR: Could not create NumberFormat (percent, French) - %s", u_errorName(status)); |
b75a7d8f A |
102 | } |
103 | ||
104 | // ======= Test equality | |
73c04bcf A |
105 | if (per_fr != NULL && cur_fr != NULL) |
106 | { | |
b75a7d8f A |
107 | logln("Testing equality operator"); |
108 | ||
109 | if( *per_fr == *cur_fr || ! ( *per_fr != *cur_fr) ) { | |
110 | errln("ERROR: == failed"); | |
111 | } | |
73c04bcf | 112 | } |
b75a7d8f A |
113 | |
114 | // ======= Test various format() methods | |
73c04bcf A |
115 | if (cur_fr != NULL) |
116 | { | |
b75a7d8f A |
117 | logln("Testing various format() methods"); |
118 | ||
119 | double d = -10456.0037; | |
120 | int32_t l = 100000000; | |
121 | Formattable fD(d); | |
122 | Formattable fL(l); | |
123 | ||
124 | UnicodeString res1, res2, res3, res4, res5, res6; | |
f3c0d7a5 | 125 | FieldPosition pos1(FieldPosition::DONT_CARE), pos2(FieldPosition::DONT_CARE), pos3(FieldPosition::DONT_CARE), pos4(FieldPosition::DONT_CARE); |
b75a7d8f A |
126 | |
127 | res1 = cur_fr->format(d, res1); | |
128 | logln( (UnicodeString) "" + (int32_t) d + " formatted to " + res1); | |
129 | ||
130 | res2 = cur_fr->format(l, res2); | |
131 | logln((UnicodeString) "" + (int32_t) l + " formatted to " + res2); | |
132 | ||
133 | res3 = cur_fr->format(d, res3, pos1); | |
134 | logln( (UnicodeString) "" + (int32_t) d + " formatted to " + res3); | |
135 | ||
136 | res4 = cur_fr->format(l, res4, pos2); | |
137 | logln((UnicodeString) "" + (int32_t) l + " formatted to " + res4); | |
138 | ||
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"); | |
143 | } | |
144 | logln((UnicodeString) "" + (int32_t) fD.getDouble() + " formatted to " + res5); | |
145 | ||
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"); | |
150 | } | |
151 | logln((UnicodeString) "" + fL.getLong() + " formatted to " + res6); | |
73c04bcf | 152 | } |
b75a7d8f A |
153 | |
154 | // ======= Test parse() | |
73c04bcf A |
155 | if (fr != NULL) |
156 | { | |
b75a7d8f A |
157 | logln("Testing parse()"); |
158 | ||
73c04bcf | 159 | double d = -10456.0037; |
b75a7d8f A |
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); | |
166 | } | |
167 | logln(text + " parsed into " + (int32_t) result1.getDouble()); | |
168 | ||
169 | fr->parse(text, result2, pos01); | |
170 | if(result2.getType() != Formattable::kDouble && result2.getDouble() != d) { | |
171 | errln("ERROR: Roundtrip failed (via parse()) for " + text); | |
172 | } | |
173 | logln(text + " parsed into " + (int32_t) result2.getDouble()); | |
174 | ||
175 | status = U_ZERO_ERROR; | |
176 | fr->parse(text, result3, status); | |
177 | if(U_FAILURE(status)) { | |
178 | errln("ERROR: parse() failed"); | |
179 | } | |
180 | if(result3.getType() != Formattable::kDouble && result3.getDouble() != d) { | |
181 | errln("ERROR: Roundtrip failed (via parse()) for " + text); | |
182 | } | |
183 | logln(text + " parsed into " + (int32_t) result3.getDouble()); | |
73c04bcf | 184 | } |
b75a7d8f A |
185 | |
186 | // ======= Test getters and setters | |
73c04bcf A |
187 | if (fr != NULL && def != NULL) |
188 | { | |
b75a7d8f A |
189 | logln("Testing getters and setters"); |
190 | ||
191 | int32_t count = 0; | |
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(),""); | |
196 | logln(name); | |
197 | } | |
198 | ||
199 | fr->setParseIntegerOnly( def->isParseIntegerOnly() ); | |
200 | if(fr->isParseIntegerOnly() != def->isParseIntegerOnly() ) { | |
201 | errln("ERROR: setParseIntegerOnly() failed"); | |
202 | } | |
203 | ||
204 | fr->setGroupingUsed( def->isGroupingUsed() ); | |
205 | if(fr->isGroupingUsed() != def->isGroupingUsed() ) { | |
206 | errln("ERROR: setGroupingUsed() failed"); | |
207 | } | |
208 | ||
209 | fr->setMaximumIntegerDigits( def->getMaximumIntegerDigits() ); | |
210 | if(fr->getMaximumIntegerDigits() != def->getMaximumIntegerDigits() ) { | |
211 | errln("ERROR: setMaximumIntegerDigits() failed"); | |
212 | } | |
213 | ||
214 | fr->setMinimumIntegerDigits( def->getMinimumIntegerDigits() ); | |
215 | if(fr->getMinimumIntegerDigits() != def->getMinimumIntegerDigits() ) { | |
216 | errln("ERROR: setMinimumIntegerDigits() failed"); | |
217 | } | |
218 | ||
219 | fr->setMaximumFractionDigits( def->getMaximumFractionDigits() ); | |
220 | if(fr->getMaximumFractionDigits() != def->getMaximumFractionDigits() ) { | |
221 | errln("ERROR: setMaximumFractionDigits() failed"); | |
222 | } | |
223 | ||
224 | fr->setMinimumFractionDigits( def->getMinimumFractionDigits() ); | |
225 | if(fr->getMinimumFractionDigits() != def->getMinimumFractionDigits() ) { | |
226 | errln("ERROR: setMinimumFractionDigits() failed"); | |
227 | } | |
73c04bcf | 228 | } |
b75a7d8f A |
229 | |
230 | // ======= Test getStaticClassID() | |
231 | ||
232 | logln("Testing getStaticClassID()"); | |
233 | ||
234 | status = U_ZERO_ERROR; | |
235 | NumberFormat *test = new DecimalFormat(status); | |
236 | if(U_FAILURE(status)) { | |
729e4ab9 | 237 | errcheckln(status, "ERROR: Couldn't create a NumberFormat - %s", u_errorName(status)); |
b75a7d8f A |
238 | } |
239 | ||
240 | if(test->getDynamicClassID() != DecimalFormat::getStaticClassID()) { | |
241 | errln("ERROR: getDynamicClassID() didn't return the expected value"); | |
242 | } | |
243 | ||
244 | delete test; | |
245 | delete def; | |
246 | delete fr; | |
247 | delete cur; | |
248 | delete cur_fr; | |
249 | delete per; | |
250 | delete per_fr; | |
251 | } | |
252 | ||
374ca955 A |
253 | #if !UCONFIG_NO_SERVICE |
254 | ||
b75a7d8f A |
255 | #define SRC_LOC Locale::getFrance() |
256 | #define SWAP_LOC Locale::getUS() | |
257 | ||
258 | class NFTestFactory : public SimpleNumberFormatFactory { | |
374ca955 | 259 | NumberFormat* currencyStyle; |
b75a7d8f A |
260 | |
261 | public: | |
374ca955 A |
262 | NFTestFactory() |
263 | : SimpleNumberFormatFactory(SRC_LOC, TRUE) | |
264 | { | |
265 | UErrorCode status = U_ZERO_ERROR; | |
266 | currencyStyle = NumberFormat::createInstance(SWAP_LOC, status); | |
267 | } | |
268 | ||
269 | virtual ~NFTestFactory() | |
270 | { | |
271 | delete currencyStyle; | |
272 | } | |
273 | ||
274 | virtual NumberFormat* createFormat(const Locale& /* loc */, UNumberFormatStyle formatType) | |
275 | { | |
276 | if (formatType == UNUM_CURRENCY) { | |
277 | return (NumberFormat*)currencyStyle->clone(); | |
278 | } | |
279 | return NULL; | |
280 | } | |
b75a7d8f A |
281 | |
282 | virtual inline UClassID getDynamicClassID() const | |
283 | { | |
374ca955 | 284 | return (UClassID)&gID; |
b75a7d8f A |
285 | } |
286 | ||
287 | static inline UClassID getStaticClassID() | |
288 | { | |
374ca955 | 289 | return (UClassID)&gID; |
b75a7d8f A |
290 | } |
291 | ||
292 | private: | |
293 | static char gID; | |
294 | }; | |
295 | ||
296 | char NFTestFactory::gID = 0; | |
374ca955 | 297 | #endif |
b75a7d8f A |
298 | |
299 | void | |
300 | IntlTestNumberFormatAPI::testRegistration() | |
301 | { | |
374ca955 A |
302 | #if !UCONFIG_NO_SERVICE |
303 | UErrorCode status = U_ZERO_ERROR; | |
304 | ||
729e4ab9 A |
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)); | |
374ca955 | 308 | URegistryKey key = NumberFormat::registerFactory(new NFTestFactory(), status); |
729e4ab9 A |
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)); | |
374ca955 A |
312 | |
313 | StringEnumeration* locs = NumberFormat::getAvailableLocales(); | |
314 | ||
729e4ab9 A |
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)); | |
b75a7d8f A |
317 | |
318 | const UnicodeString* res; | |
374ca955 A |
319 | for (res = locs->snext(status); res; res = locs->snext(status)) { |
320 | logln(*res); // service is still in synch | |
321 | } | |
322 | ||
323 | NumberFormat::unregister(key, status); // restore for other tests | |
729e4ab9 A |
324 | LocalPointer<NumberFormat> f5(NumberFormat::createCurrencyInstance(SRC_LOC, status)); |
325 | LocalUNumberFormatPointer uf5(unum_open(UNUM_CURRENCY, NULL, 0, SRC_LOC.getName(), NULL, &status)); | |
73c04bcf A |
326 | |
327 | if (U_FAILURE(status)) { | |
328 | dataerrln("Error creating instnaces."); | |
329 | return; | |
374ca955 | 330 | } else { |
73c04bcf A |
331 | float n = 1234.567f; |
332 | UnicodeString res0, res1, res2, res3, res4, res5; | |
333 | UChar ures3[50]; | |
334 | UChar ures4[50]; | |
335 | UChar ures5[50]; | |
336 | ||
337 | f0->format(n, res0); | |
338 | f1->format(n, res1); | |
339 | f2->format(n, res2); | |
340 | f3->format(n, res3); | |
341 | f4->format(n, res4); | |
342 | f5->format(n, res5); | |
343 | ||
729e4ab9 A |
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); | |
73c04bcf A |
347 | |
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: "); | |
355 | logln(ures3); | |
356 | log("uf4 reg int: "); | |
357 | logln(ures4); | |
358 | log("uf5 ureg cur: "); | |
359 | logln(ures5); | |
360 | ||
729e4ab9 | 361 | if (f3.getAlias() == f3a.getAlias()) { |
73c04bcf | 362 | errln("did not get new instance from service"); |
729e4ab9 | 363 | f3a.orphan(); |
73c04bcf A |
364 | } |
365 | if (res3 != res0) { | |
366 | errln("registered service did not match"); | |
367 | } | |
368 | if (res4 != res1) { | |
369 | errln("registered service did not inherit"); | |
370 | } | |
371 | if (res5 != res2) { | |
372 | errln("unregistered service did not match original"); | |
373 | } | |
374ca955 | 374 | |
73c04bcf A |
375 | if (res0 != ures3) { |
376 | errln("registered service did not match / unum"); | |
377 | } | |
378 | if (res1 != ures4) { | |
379 | errln("registered service did not inherit / unum"); | |
380 | } | |
381 | if (res2 != ures5) { | |
382 | errln("unregistered service did not match original / unum"); | |
383 | } | |
374ca955 A |
384 | } |
385 | ||
374ca955 A |
386 | for (res = locs->snext(status); res; res = locs->snext(status)) { |
387 | errln(*res); // service should be out of synch | |
388 | } | |
389 | ||
390 | locs->reset(status); // now in synch again, we hope | |
391 | for (res = locs->snext(status); res; res = locs->snext(status)) { | |
392 | logln(*res); | |
393 | } | |
394 | ||
395 | delete locs; | |
396 | #endif | |
b75a7d8f A |
397 | } |
398 | ||
399 | ||
400 | #endif /* #if !UCONFIG_NO_FORMATTING */ |