1 /* 2 ******************************************************************************* 3 * Copyright (C) 1997-2014, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 * 7 * File COMPACTDECIMALFORMATTEST.CPP 8 * 9 ******************************************************************************** 10 */ 11 #include <stdio.h> 12 #include <stdlib.h> 13 14 #include "intltest.h" 15 16 #if !UCONFIG_NO_FORMATTING 17 18 #include "unicode/compactdecimalformat.h" 19 #include "unicode/unum.h" 20 #include "cmemory.h" 21 22 typedef struct ExpectedResult { 23 double value; 24 const char *expected; 25 } ExpectedResult; 26 27 static const char *kShortStr = "Short"; 28 static const char *kLongStr = "Long"; 29 30 static ExpectedResult kEnglishShort[] = { 31 {0.0, "0"}, 32 {0.17, "0.17"}, 33 {1.0, "1"}, 34 {1234.0, "1.2K"}, 35 {12345.0, "12K"}, 36 {123456.0, "120K"}, 37 {1234567.0, "1.2M"}, 38 {12345678.0, "12M"}, 39 {123456789.0, "120M"}, 40 {1.23456789E9, "1.2B"}, 41 {1.23456789E10, "12B"}, 42 {1.23456789E11, "120B"}, 43 {1.23456789E12, "1.2T"}, 44 {1.23456789E13, "12T"}, 45 {1.23456789E14, "120T"}, 46 {1.23456789E15, "1200T"}}; 47 48 static ExpectedResult kSerbianShort[] = { 49 {1234.0, "1,2\\u00a0\\u0445\\u0438\\u0459."}, 50 {12345.0, "12\\u00a0\\u0445\\u0438\\u0459."}, 51 {20789.0, "21\\u00a0\\u0445\\u0438\\u0459."}, 52 {123456.0, "120\\u00a0\\u0445\\u0438\\u0459."}, 53 {1234567.0, "1,2\\u00A0\\u043C\\u0438\\u043B."}, 54 {12345678.0, "12\\u00A0\\u043C\\u0438\\u043B."}, 55 {123456789.0, "120\\u00A0\\u043C\\u0438\\u043B."}, 56 {1.23456789E9, "1,2\\u00A0\\u043C\\u043B\\u0440\\u0434."}, 57 {1.23456789E10, "12\\u00A0\\u043C\\u043B\\u0440\\u0434."}, 58 {1.23456789E11, "120\\u00A0\\u043C\\u043B\\u0440\\u0434."}, 59 {1.23456789E12, "1,2\\u00A0\\u0431\\u0438\\u043B."}, 60 {1.23456789E13, "12\\u00A0\\u0431\\u0438\\u043B."}, 61 {1.23456789E14, "120\\u00A0\\u0431\\u0438\\u043B."}, 62 {1.23456789E15, "1200\\u00A0\\u0431\\u0438\\u043B."}}; 63 64 static ExpectedResult kSerbianLong[] = { 65 {1234.0, "1,2 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0435"}, // 10^3 few 66 {12345.0, "12 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0430"}, // 10^3 other 67 {21789.0, "22 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0435"}, // 10^3 few 68 {123456.0, "120 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0430"}, // 10^3 other 69 {999999.0, "1 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D"}, // 10^6 one 70 {1234567.0, "1,2 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^6 few 71 {12345678.0, "12 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^6 other 72 {123456789.0, "120 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^6 other 73 {1.23456789E9, "1,2 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0435"}, // 10^9 few 74 {1.23456789E10, "12 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0438"}, // 10^9 other 75 {2.08901234E10, "21 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0430"}, // 10^9 one 76 {2.18901234E10, "22 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0435"}, // 10^9 few 77 {1.23456789E11, "120 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0438"}, // 10^9 other 78 {1.23456789E12, "1,2 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^12 few 79 {1.23456789E13, "12 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^12 other 80 {1.23456789E14, "120 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^12 other 81 {1.23456789E15, "1200 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}}; // 10^12 other 82 83 static ExpectedResult kSerbianLongNegative[] = { 84 {-1234.0, "-1,2 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0435"}, 85 {-12345.0, "-12 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0430"}, 86 {-21789.0, "-22 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0435"}, 87 {-123456.0, "-120 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0430"}, 88 {-999999.0, "-1 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D"}, 89 {-1234567.0, "-1,2 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, 90 {-12345678.0, "-12 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, 91 {-123456789.0, "-120 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, 92 {-1.23456789E9, "-1,2 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0435"}, 93 {-1.23456789E10, "-12 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0438"}, 94 {-2.08901234E10, "-21 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0430"}, 95 {-2.18901234E10, "-22 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0435"}, 96 {-1.23456789E11, "-120 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0438"}, 97 {-1.23456789E12, "-1,2 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, 98 {-1.23456789E13, "-12 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, 99 {-1.23456789E14, "-120 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, 100 {-1.23456789E15, "-1200 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}}; 101 102 static ExpectedResult kJapaneseShort[] = { 103 {1234.0, "1.2\\u5343"}, 104 {12345.0, "1.2\\u4E07"}, 105 {123456.0, "12\\u4E07"}, 106 {1234567.0, "120\\u4E07"}, 107 {12345678.0, "1200\\u4E07"}, 108 {123456789.0, "1.2\\u5104"}, 109 {1.23456789E9, "12\\u5104"}, 110 {1.23456789E10, "120\\u5104"}, 111 {1.23456789E11, "1200\\u5104"}, 112 {1.23456789E12, "1.2\\u5146"}, 113 {1.23456789E13, "12\\u5146"}, 114 {1.23456789E14, "120\\u5146"}}; 115 116 static ExpectedResult kSwahiliShort[] = { 117 {1234.0, "elfu\\u00a01.2"}, 118 {12345.0, "elfu\\u00a012"}, 119 {123456.0, "elfu\\u00a0120"}, 120 {1234567.0, "M1.2"}, 121 {12345678.0, "M12"}, 122 {123456789.0, "M120"}, 123 {1.23456789E9, "B1.2"}, 124 {1.23456789E10, "B12"}, 125 {1.23456789E11, "B120"}, 126 {1.23456789E12, "T1.2"}, 127 {1.23456789E13, "T12"}, 128 {1.23456789E15, "T1200"}}; 129 130 static ExpectedResult kCsShort[] = { 131 {1000.0, "1\\u00a0tis."}, 132 {1500.0, "1,5\\u00a0tis."}, 133 {5000.0, "5\\u00a0tis."}, 134 {23000.0, "23\\u00a0tis."}, 135 {127123.0, "130\\u00a0tis."}, 136 {1271234.0, "1,3\\u00a0mil."}, 137 {12712345.0, "13\\u00a0mil."}, 138 {127123456.0, "130\\u00a0mil."}, 139 {1.27123456E9, "1,3\\u00a0mld."}, 140 {1.27123456E10, "13\\u00a0mld."}, 141 {1.27123456E11, "130\\u00a0mld."}, 142 {1.27123456E12, "1,3\\u00a0bil."}, 143 {1.27123456E13, "13\\u00a0bil."}, 144 {1.27123456E14, "130\\u00a0bil."}}; 145 146 static ExpectedResult kSkLong[] = { 147 {1000.0, "1 tis\\u00edc"}, 148 {1572.0, "1,6 tis\\u00edc"}, 149 {5184.0, "5,2 tis\\u00edc"}}; 150 151 static ExpectedResult kSwahiliShortNegative[] = { 152 {-1234.0, "elfu\\u00a0-1.2"}, 153 {-12345.0, "elfu\\u00a0-12"}, 154 {-123456.0, "elfu\\u00a0-120"}, 155 {-1234567.0, "M-1.2"}, 156 {-12345678.0, "M-12"}, 157 {-123456789.0, "M-120"}, 158 {-1.23456789E9, "B-1.2"}, 159 {-1.23456789E10, "B-12"}, 160 {-1.23456789E11, "B-120"}, 161 {-1.23456789E12, "T-1.2"}, 162 {-1.23456789E13, "T-12"}, 163 {-1.23456789E15, "T-1200"}}; 164 165 static ExpectedResult kArabicLong[] = { 166 {-5300.0, "\\u200F-\\u0665\\u066B\\u0663 \\u0623\\u0644\\u0641"}}; 167 168 169 class CompactDecimalFormatTest : public IntlTest { 170 public: 171 CompactDecimalFormatTest() { 172 } 173 174 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0); 175 private: 176 void TestEnglishShort(); 177 void TestSerbianShort(); 178 void TestSerbianLong(); 179 void TestSerbianLongNegative(); 180 void TestJapaneseShort(); 181 void TestSwahiliShort(); 182 void TestCsShort(); 183 void TestSkLong(); 184 void TestSwahiliShortNegative(); 185 void TestArabicLong(); 186 void TestFieldPosition(); 187 void TestSignificantDigits(); 188 void CheckLocale( 189 const Locale& locale, UNumberCompactStyle style, 190 const ExpectedResult* expectedResult, int32_t expectedResultLength); 191 void CheckExpectedResult( 192 const CompactDecimalFormat* cdf, const ExpectedResult* expectedResult, 193 const char* description); 194 CompactDecimalFormat* createCDFInstance(const Locale& locale, UNumberCompactStyle style, UErrorCode& status); 195 static const char *StyleStr(UNumberCompactStyle style); 196 }; 197 198 void CompactDecimalFormatTest::runIndexedTest( 199 int32_t index, UBool exec, const char *&name, char *) { 200 if (exec) { 201 logln("TestSuite CompactDecimalFormatTest: "); 202 } 203 TESTCASE_AUTO_BEGIN; 204 TESTCASE_AUTO(TestEnglishShort); 205 TESTCASE_AUTO(TestSerbianShort); 206 TESTCASE_AUTO(TestSerbianLong); 207 TESTCASE_AUTO(TestSerbianLongNegative); 208 TESTCASE_AUTO(TestJapaneseShort); 209 TESTCASE_AUTO(TestSwahiliShort); 210 TESTCASE_AUTO(TestCsShort); 211 TESTCASE_AUTO(TestSkLong); 212 TESTCASE_AUTO(TestSwahiliShortNegative); 213 TESTCASE_AUTO(TestArabicLong); 214 TESTCASE_AUTO(TestFieldPosition); 215 TESTCASE_AUTO(TestSignificantDigits); 216 TESTCASE_AUTO_END; 217 } 218 219 void CompactDecimalFormatTest::TestEnglishShort() { 220 CheckLocale("en", UNUM_SHORT, kEnglishShort, UPRV_LENGTHOF(kEnglishShort)); 221 } 222 223 void CompactDecimalFormatTest::TestSerbianShort() { 224 CheckLocale("sr", UNUM_SHORT, kSerbianShort, UPRV_LENGTHOF(kSerbianShort)); 225 } 226 227 void CompactDecimalFormatTest::TestSerbianLong() { 228 CheckLocale("sr", UNUM_LONG, kSerbianLong, UPRV_LENGTHOF(kSerbianLong)); 229 } 230 231 void CompactDecimalFormatTest::TestSerbianLongNegative() { 232 CheckLocale("sr", UNUM_LONG, kSerbianLongNegative, UPRV_LENGTHOF(kSerbianLongNegative)); 233 } 234 235 void CompactDecimalFormatTest::TestJapaneseShort() { 236 CheckLocale(Locale::getJapan(), UNUM_SHORT, kJapaneseShort, UPRV_LENGTHOF(kJapaneseShort)); 237 } 238 239 void CompactDecimalFormatTest::TestSwahiliShort() { 240 CheckLocale("sw", UNUM_SHORT, kSwahiliShort, UPRV_LENGTHOF(kSwahiliShort)); 241 } 242 243 void CompactDecimalFormatTest::TestFieldPosition() { 244 // Swahili uses prefixes which forces offsets in field position to change 245 UErrorCode status = U_ZERO_ERROR; 246 LocalPointer<CompactDecimalFormat> cdf(createCDFInstance("sw", UNUM_SHORT, status)); 247 if (U_FAILURE(status)) { 248 dataerrln("Unable to create format object - %s", u_errorName(status)); 249 return; 250 } 251 FieldPosition fp(UNUM_INTEGER_FIELD); 252 UnicodeString result; 253 cdf->format(1234567.0, result, fp); 254 UnicodeString subString = result.tempSubString(fp.getBeginIndex(), fp.getEndIndex() - fp.getBeginIndex()); 255 if (subString != UnicodeString("1", -1, US_INV)) { 256 errln(UnicodeString("Expected 1, got ") + subString); 257 } 258 } 259 260 void CompactDecimalFormatTest::TestCsShort() { 261 CheckLocale("cs", UNUM_SHORT, kCsShort, UPRV_LENGTHOF(kCsShort)); 262 } 263 264 void CompactDecimalFormatTest::TestSkLong() { 265 // In CLDR we have: 266 // 1000 { 267 // few{"0"} 268 // one{"0"} 269 // other{"0"} 270 CheckLocale("sk", UNUM_LONG, kSkLong, UPRV_LENGTHOF(kSkLong)); 271 } 272 273 void CompactDecimalFormatTest::TestSwahiliShortNegative() { 274 CheckLocale("sw", UNUM_SHORT, kSwahiliShortNegative, UPRV_LENGTHOF(kSwahiliShortNegative)); 275 } 276 277 void CompactDecimalFormatTest::TestArabicLong() { 278 CheckLocale("ar", UNUM_LONG, kArabicLong, UPRV_LENGTHOF(kArabicLong)); 279 } 280 281 void CompactDecimalFormatTest::TestSignificantDigits() { 282 UErrorCode status = U_ZERO_ERROR; 283 LocalPointer<CompactDecimalFormat> cdf(CompactDecimalFormat::createInstance("en", UNUM_SHORT, status)); 284 if (U_FAILURE(status)) { 285 dataerrln("Unable to create format object - %s", u_errorName(status)); 286 return; 287 } 288 UnicodeString actual; 289 cdf->format(123456.0, actual); 290 // We expect 3 significant digits by default 291 UnicodeString expected("123K", -1, US_INV); 292 if (actual != expected) { 293 errln(UnicodeString("Fail: Expected: ") + expected + UnicodeString(" Got: ") + actual); 294 } 295 } 296 297 void CompactDecimalFormatTest::CheckLocale(const Locale& locale, UNumberCompactStyle style, const ExpectedResult* expectedResults, int32_t expectedResultLength) { 298 UErrorCode status = U_ZERO_ERROR; 299 LocalPointer<CompactDecimalFormat> cdf(createCDFInstance(locale, style, status)); 300 if (U_FAILURE(status)) { 301 dataerrln("Unable to create format object - %s", u_errorName(status)); 302 return; 303 } 304 char description[256]; 305 sprintf(description,"%s - %s", locale.getName(), StyleStr(style)); 306 for (int32_t i = 0; i < expectedResultLength; i++) { 307 CheckExpectedResult(cdf.getAlias(), &expectedResults[i], description); 308 } 309 } 310 311 void CompactDecimalFormatTest::CheckExpectedResult( 312 const CompactDecimalFormat* cdf, const ExpectedResult* expectedResult, const char* description) { 313 UnicodeString actual; 314 cdf->format(expectedResult->value, actual); 315 UnicodeString expected(expectedResult->expected, -1, US_INV); 316 expected = expected.unescape(); 317 if (actual != expected) { 318 errln(UnicodeString("Fail: Expected: ") + expected 319 + UnicodeString(" Got: ") + actual 320 + UnicodeString(" for: ") + UnicodeString(description)); 321 } 322 } 323 324 CompactDecimalFormat* 325 CompactDecimalFormatTest::createCDFInstance(const Locale& locale, UNumberCompactStyle style, UErrorCode& status) { 326 CompactDecimalFormat* result = CompactDecimalFormat::createInstance(locale, style, status); 327 if (U_FAILURE(status)) { 328 return NULL; 329 } 330 // All tests are written for two significant digits, so we explicitly set here 331 // in case default significant digits change. 332 result->setMaximumSignificantDigits(2); 333 return result; 334 } 335 336 const char *CompactDecimalFormatTest::StyleStr(UNumberCompactStyle style) { 337 if (style == UNUM_SHORT) { 338 return kShortStr; 339 } 340 return kLongStr; 341 } 342 343 extern IntlTest *createCompactDecimalFormatTest() { 344 return new CompactDecimalFormatTest(); 345 } 346 347 #endif 348