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