Home | History | Annotate | Download | only in intltest
      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 */
    399