Home | History | Annotate | Download | only in intltest
      1 /*
      2 *******************************************************************************
      3 * Copyright (C) 2007-2008, International Business Machines Corporation and
      4 * others. All Rights Reserved.
      5 ********************************************************************************
      6 
      7 * File PLURRULTS.cpp
      8 *
      9 ********************************************************************************
     10 */
     11 
     12 #include "unicode/utypes.h"
     13 
     14 #if !UCONFIG_NO_FORMATTING
     15 
     16 #include "plurults.h"
     17 #include "unicode/plurrule.h"
     18 
     19 
     20 
     21 void setupResult(const int32_t testSource[], char result[], int32_t* max);
     22 UBool checkEqual(PluralRules *test, char *result, int32_t max);
     23 UBool testEquality(PluralRules *test);
     24 
     25 // This is an API test, not a unit test.  It doesn't test very many cases, and doesn't
     26 // try to test the full functionality.  It just calls each function in the class and
     27 // verifies that it works on a basic level.
     28 
     29 void PluralRulesTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
     30 {
     31     if (exec) logln("TestSuite PluralRulesAPI");
     32     switch (index) {
     33         TESTCASE(0, testAPI);
     34         default: name = ""; break;
     35     }
     36 }
     37 
     38 #define PLURAL_TEST_NUM    18
     39 /**
     40  * Test various generic API methods of PluralRules for API coverage.
     41  */
     42 void PluralRulesTest::testAPI(/*char *par*/)
     43 {
     44     UnicodeString pluralTestData[PLURAL_TEST_NUM] = {
     45             UNICODE_STRING_SIMPLE("a: n is 1"),
     46             UNICODE_STRING_SIMPLE("a: n mod 10 is 2"),
     47             UNICODE_STRING_SIMPLE("a: n is not 1"),
     48             UNICODE_STRING_SIMPLE("a: n mod 3 is not 1"),
     49             UNICODE_STRING_SIMPLE("a: n in 2..5"),
     50             UNICODE_STRING_SIMPLE("a: n within 2..5"),
     51             UNICODE_STRING_SIMPLE("a: n not in 2..5"),
     52             UNICODE_STRING_SIMPLE("a: n not within 2..5"),
     53             UNICODE_STRING_SIMPLE("a: n mod 10 in 2..5"),
     54             UNICODE_STRING_SIMPLE("a: n mod 10 within 2..5"),
     55             UNICODE_STRING_SIMPLE("a: n mod 10 is 2 and n is not 12"),
     56             UNICODE_STRING_SIMPLE("a: n mod 10 in 2..3 or n mod 10 is 5"),
     57             UNICODE_STRING_SIMPLE("a: n mod 10 within 2..3 or n mod 10 is 5"),
     58             UNICODE_STRING_SIMPLE("a: n is 1 or n is 4 or n is 23"),
     59             UNICODE_STRING_SIMPLE("a: n mod 2 is 1 and n is not 3 and n in 1..11"),
     60             UNICODE_STRING_SIMPLE("a: n mod 2 is 1 and n is not 3 and n within 1..11"),
     61             UNICODE_STRING_SIMPLE("a: n mod 2 is 1 or n mod 5 is 1 and n is not 6"),
     62             "",
     63     };
     64     static const int32_t pluralTestResult[PLURAL_TEST_NUM][30] = {
     65         {1, 0},
     66         {2,12,22, 0},
     67         {0,2,3,4,5,0},
     68         {0,2,3,5,6,8,9,0},
     69         {2,3,4,5,0},
     70         {2,3,4,5,0},
     71         {0,1,6,7,8, 0},
     72         {0,1,6,7,8, 0},
     73         {2,3,4,5,12,13,14,15,22,23,24,25,0},
     74         {2,3,4,5,12,13,14,15,22,23,24,25,0},
     75         {2,22,32,42,0},
     76         {2,3,5,12,13,15,22,23,25,0},
     77         {2,3,5,12,13,15,22,23,25,0},
     78         {1,4,23,0},
     79         {1,5,7,9,11,0},
     80         {1,5,7,9,11,0},
     81         {1,3,5,7,9,11,13,15,16,0},
     82     };
     83     UErrorCode status = U_ZERO_ERROR;
     84 
     85     // ======= Test constructors
     86     logln("Testing PluralRules constructors");
     87 
     88 
     89     logln("\n start default locale test case ..\n");
     90 
     91     PluralRules defRule(status);
     92     PluralRules* test=new PluralRules(status);
     93     PluralRules* newEnPlural= test->forLocale(Locale::getEnglish(), status);
     94     if(U_FAILURE(status)) {
     95         dataerrln("ERROR: Could not create PluralRules (default) - exitting");
     96         delete test;
     97         return;
     98     }
     99 
    100     // ======= Test clone, assignment operator && == operator.
    101     PluralRules *dupRule = defRule.clone();
    102     if (dupRule!=NULL) {
    103         if ( *dupRule != defRule ) {
    104             errln("ERROR:  clone plural rules test failed!");
    105         }
    106     }
    107     *dupRule = *newEnPlural;
    108     if (dupRule!=NULL) {
    109         if ( *dupRule != *newEnPlural ) {
    110             errln("ERROR:  clone plural rules test failed!");
    111         }
    112         delete dupRule;
    113     }
    114 
    115     delete newEnPlural;
    116 
    117     // ======= Test empty plural rules
    118     logln("Testing Simple PluralRules");
    119 
    120     PluralRules* empRule = test->createRules(UNICODE_STRING_SIMPLE("a:n"), status);
    121     UnicodeString key;
    122     for (int32_t i=0; i<10; ++i) {
    123         key = empRule->select(i);
    124         if ( key.charAt(0)!= 0x61 ) { // 'a'
    125             errln("ERROR:  empty plural rules test failed! - exitting");
    126         }
    127     }
    128     if (empRule!=NULL) {
    129         delete empRule;
    130     }
    131 
    132     // ======= Test simple plural rules
    133     logln("Testing Simple PluralRules");
    134 
    135     char result[100];
    136     int32_t max;
    137 
    138     for (int32_t i=0; i<PLURAL_TEST_NUM-1; ++i) {
    139        PluralRules *newRules = test->createRules(pluralTestData[i], status);
    140        setupResult(pluralTestResult[i], result, &max);
    141        if ( !checkEqual(newRules, result, max) ) {
    142             errln("ERROR:  simple plural rules failed! - exitting");
    143             delete test;
    144             return;
    145         }
    146        if (newRules!=NULL) {
    147            delete newRules;
    148        }
    149     }
    150 
    151 
    152     // ======= Test complex plural rules
    153     logln("Testing Complex PluralRules");
    154     // TODO: the complex test data is hard coded. It's better to implement
    155     // a parser to parse the test data.
    156     UnicodeString complexRule = UNICODE_STRING_SIMPLE("a: n in 2..5; b: n in 5..8; c: n mod 2 is 1");
    157     UnicodeString complexRule2 = UNICODE_STRING_SIMPLE("a: n within 2..5; b: n within 5..8; c: n mod 2 is 1");
    158     char cRuleResult[] =
    159     {
    160        0x6F, // 'o'
    161        0x63, // 'c'
    162        0x61, // 'a'
    163        0x61, // 'a'
    164        0x61, // 'a'
    165        0x61, // 'a'
    166        0x62, // 'b'
    167        0x62, // 'b'
    168        0x62, // 'b'
    169        0x63, // 'c'
    170        0x6F, // 'o'
    171        0x63  // 'c'
    172     };
    173     PluralRules *newRules = test->createRules(complexRule, status);
    174     if ( !checkEqual(newRules, cRuleResult, 12) ) {
    175          errln("ERROR:  complex plural rules failed! - exitting");
    176          delete test;
    177          return;
    178      }
    179     if (newRules!=NULL) {
    180         delete newRules;
    181         newRules=NULL;
    182     }
    183     newRules = test->createRules(complexRule2, status);
    184     if ( !checkEqual(newRules, cRuleResult, 12) ) {
    185          errln("ERROR:  complex plural rules failed! - exitting");
    186          delete test;
    187          return;
    188      }
    189     if (newRules!=NULL) {
    190         delete newRules;
    191         newRules=NULL;
    192     }
    193 
    194     // ======= Test decimal fractions plural rules
    195     UnicodeString decimalRule= UNICODE_STRING_SIMPLE("a: n not in 0..100;");
    196     UnicodeString KEYWORD_A = UNICODE_STRING_SIMPLE("a");
    197     status = U_ZERO_ERROR;
    198     newRules = test->createRules(decimalRule, status);
    199     if (U_FAILURE(status)) {
    200         dataerrln("ERROR: Could not create PluralRules for testing fractions - exitting");
    201         delete test;
    202         return;
    203     }
    204     double fData[10] = {-100, -1, -0.0, 0, 0.1, 1, 1.999, 2.0, 100, 100.001 };
    205     UBool isKeywordA[10] = {
    206            TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE };
    207     for (int32_t i=0; i<10; i++) {
    208         if ((newRules->select(fData[i])== KEYWORD_A) != isKeywordA[i]) {
    209              errln("ERROR: plural rules for decimal fractions test failed!");
    210         }
    211     }
    212     if (newRules!=NULL) {
    213         delete newRules;
    214         newRules=NULL;
    215     }
    216 
    217 
    218 
    219     // ======= Test Equality
    220     logln("Testing Equality of PluralRules");
    221 
    222 
    223     if ( !testEquality(test) ) {
    224          errln("ERROR:  complex plural rules failed! - exitting");
    225          delete test;
    226          return;
    227      }
    228 
    229 
    230     // ======= Test getStaticClassID()
    231     logln("Testing getStaticClassID()");
    232 
    233     if(test->getDynamicClassID() != PluralRules::getStaticClassID()) {
    234         errln("ERROR: getDynamicClassID() didn't return the expected value");
    235     }
    236     // ====== Test fallback to parent locale
    237     PluralRules *en_UK = test->forLocale(Locale::getUK(), status);
    238     PluralRules *en = test->forLocale(Locale::getEnglish(), status);
    239     if (en_UK != NULL && en != NULL) {
    240         if ( *en_UK != *en ) {
    241             errln("ERROR:  test locale fallback failed!");
    242         }
    243     }
    244     delete en;
    245     delete en_UK;
    246 
    247     PluralRules *zh_Hant = test->forLocale(Locale::getTaiwan(), status);
    248     PluralRules *zh = test->forLocale(Locale::getChinese(), status);
    249     if (zh_Hant != NULL && zh != NULL) {
    250         if ( *zh_Hant != *zh ) {
    251             errln("ERROR:  test locale fallback failed!");
    252         }
    253     }
    254     delete zh_Hant;
    255     delete zh;
    256     delete test;
    257 }
    258 
    259 void setupResult(const int32_t testSource[], char result[], int32_t* max) {
    260     int32_t i=0;
    261     int32_t curIndex=0;
    262 
    263     do {
    264         while (curIndex < testSource[i]) {
    265             result[curIndex++]=0x6F; //'o' other
    266         }
    267         result[curIndex++]=0x61; // 'a'
    268 
    269     } while(testSource[++i]>0);
    270     *max=curIndex;
    271 }
    272 
    273 
    274 UBool checkEqual(PluralRules *test, char *result, int32_t max) {
    275     UnicodeString key;
    276     UBool isEqual = TRUE;
    277     for (int32_t i=0; i<max; ++i) {
    278         key= test->select(i);
    279         if ( key.charAt(0)!=result[i] ) {
    280             isEqual = FALSE;
    281         }
    282     }
    283     return isEqual;
    284 }
    285 
    286 #define MAX_EQ_ROW  2
    287 #define MAX_EQ_COL  5
    288 UBool testEquality(PluralRules *test) {
    289     UnicodeString testEquRules[MAX_EQ_ROW][MAX_EQ_COL] = {
    290         {   UNICODE_STRING_SIMPLE("a: n in 2..3"),
    291             UNICODE_STRING_SIMPLE("a: n is 2 or n is 3"),
    292             UNICODE_STRING_SIMPLE( "a:n is 3 and n in 2..5 or n is 2"),
    293             "",
    294         },
    295         {   UNICODE_STRING_SIMPLE("a: n is 12; b:n mod 10 in 2..3"),
    296             UNICODE_STRING_SIMPLE("b: n mod 10 in 2..3 and n is not 12; a: n in 12..12"),
    297             UNICODE_STRING_SIMPLE("b: n is 13; a: n in 12..13; b: n mod 10 is 2 or n mod 10 is 3"),
    298             "",
    299         }
    300     };
    301     UErrorCode status = U_ZERO_ERROR;
    302     UnicodeString key[MAX_EQ_COL];
    303     UBool ret=TRUE;
    304     for (int32_t i=0; i<MAX_EQ_ROW; ++i) {
    305         PluralRules* rules[MAX_EQ_COL];
    306 
    307         for (int32_t j=0; j<MAX_EQ_COL; ++j) {
    308             rules[j]=NULL;
    309         }
    310         int32_t totalRules=0;
    311         while((totalRules<MAX_EQ_COL) && (testEquRules[i][totalRules].length()>0) ) {
    312             rules[totalRules]=test->createRules(testEquRules[i][totalRules], status);
    313             totalRules++;
    314         }
    315         for (int32_t n=0; n<300 && ret ; ++n) {
    316             for(int32_t j=0; j<totalRules;++j) {
    317                 key[j] = rules[j]->select(n);
    318             }
    319             for(int32_t j=0; j<totalRules-1;++j) {
    320                 if (key[j]!=key[j+1]) {
    321                     ret= FALSE;
    322                     break;
    323                 }
    324             }
    325 
    326         }
    327         for (int32_t j=0; j<MAX_EQ_COL; ++j) {
    328             if (rules[j]!=NULL) {
    329                 delete rules[j];
    330             }
    331         }
    332     }
    333 
    334     return ret;
    335 }
    336 #endif /* #if !UCONFIG_NO_FORMATTING */
    337 
    338