OLD | NEW |
(Empty) | |
| 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 d
oesn'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* &na
me, 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"), statu
s); |
| 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 w
ithin 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 - e
xitting"); |
| 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], sta
tus); |
| 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 |
OLD | NEW |