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