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 23void 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 */ 61void 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 103if (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 113if (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() 153if (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 185if (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 256class NFTestFactory : public SimpleNumberFormatFactory { 257 NumberFormat* currencyStyle; 258 259public: 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 290private: 291 static char gID; 292}; 293 294char NFTestFactory::gID = 0; 295#endif 296 297void 298IntlTestNumberFormatAPI::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 */ 399