1 // Copyright (C) 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /* 4 ******************************************************************************* 5 * 6 * Copyright (C) 2012-2016, International Business Machines 7 * Corporation and others. All Rights Reserved. 8 * 9 ******************************************************************************* 10 * file name: listformattertest.cpp 11 * encoding: US-ASCII 12 * tab size: 8 (not used) 13 * indentation:4 14 * 15 * created on: 2012aug27 16 * created by: Umesh P. Nair 17 */ 18 19 #include "listformattertest.h" 20 #include <string.h> 21 22 ListFormatterTest::ListFormatterTest() : 23 prefix("Prefix: ", -1, US_INV), 24 one("Alice", -1, US_INV), two("Bob", -1, US_INV), 25 three("Charlie", -1, US_INV), four("Delta", -1, US_INV) { 26 } 27 28 void ListFormatterTest::CheckFormatting(const ListFormatter* formatter, UnicodeString data[], int32_t dataSize, 29 const UnicodeString& expected_result) { 30 UnicodeString actualResult(prefix); 31 UErrorCode errorCode = U_ZERO_ERROR; 32 formatter->format(data, dataSize, actualResult, errorCode); 33 UnicodeString expectedStringWithPrefix = prefix + expected_result; 34 if (expectedStringWithPrefix != actualResult) { 35 errln(UnicodeString("Expected: |") + expectedStringWithPrefix + "|, Actual: |" + actualResult + "|"); 36 } 37 } 38 39 void ListFormatterTest::CheckFourCases(const char* locale_string, UnicodeString one, UnicodeString two, 40 UnicodeString three, UnicodeString four, UnicodeString results[4]) { 41 UErrorCode errorCode = U_ZERO_ERROR; 42 LocalPointer<ListFormatter> formatter(ListFormatter::createInstance(Locale(locale_string), errorCode)); 43 if (U_FAILURE(errorCode)) { 44 dataerrln("ListFormatter::createInstance(Locale(\"%s\"), errorCode) failed in CheckFourCases: %s", locale_string, u_errorName(errorCode)); 45 return; 46 } 47 UnicodeString input1[] = {one}; 48 CheckFormatting(formatter.getAlias(), input1, 1, results[0]); 49 50 UnicodeString input2[] = {one, two}; 51 CheckFormatting(formatter.getAlias(), input2, 2, results[1]); 52 53 UnicodeString input3[] = {one, two, three}; 54 CheckFormatting(formatter.getAlias(), input3, 3, results[2]); 55 56 UnicodeString input4[] = {one, two, three, four}; 57 CheckFormatting(formatter.getAlias(), input4, 4, results[3]); 58 } 59 60 UBool ListFormatterTest::RecordFourCases(const Locale& locale, UnicodeString one, UnicodeString two, 61 UnicodeString three, UnicodeString four, UnicodeString results[4]) { 62 UErrorCode errorCode = U_ZERO_ERROR; 63 LocalPointer<ListFormatter> formatter(ListFormatter::createInstance(locale, errorCode)); 64 if (U_FAILURE(errorCode)) { 65 dataerrln("ListFormatter::createInstance(\"%s\", errorCode) failed in RecordFourCases: %s", locale.getName(), u_errorName(errorCode)); 66 return FALSE; 67 } 68 UnicodeString input1[] = {one}; 69 formatter->format(input1, 1, results[0], errorCode); 70 UnicodeString input2[] = {one, two}; 71 formatter->format(input2, 2, results[1], errorCode); 72 UnicodeString input3[] = {one, two, three}; 73 formatter->format(input3, 3, results[2], errorCode); 74 UnicodeString input4[] = {one, two, three, four}; 75 formatter->format(input4, 4, results[3], errorCode); 76 if (U_FAILURE(errorCode)) { 77 errln("RecordFourCases failed: %s", u_errorName(errorCode)); 78 return FALSE; 79 } 80 return TRUE; 81 } 82 83 void ListFormatterTest::TestRoot() { 84 UnicodeString results[4] = { 85 one, 86 one + ", " + two, 87 one + ", " + two + ", " + three, 88 one + ", " + two + ", " + three + ", " + four 89 }; 90 91 CheckFourCases("", one, two, three, four, results); 92 } 93 94 // Bogus locale should fallback to root. 95 void ListFormatterTest::TestBogus() { 96 UnicodeString results[4]; 97 if (RecordFourCases(Locale::getDefault(), one, two, three, four, results)) { 98 CheckFourCases("ex_PY", one, two, three, four, results); 99 } 100 } 101 102 // Formatting in English. 103 // "and" is used before the last element, and all elements up to (and including) the penultimate are followed by a comma. 104 void ListFormatterTest::TestEnglish() { 105 UnicodeString results[4] = { 106 one, 107 one + " and " + two, 108 one + ", " + two + ", and " + three, 109 one + ", " + two + ", " + three + ", and " + four 110 }; 111 112 CheckFourCases("en", one, two, three, four, results); 113 } 114 115 void ListFormatterTest::Test9946() { 116 UErrorCode errorCode = U_ZERO_ERROR; 117 LocalPointer<ListFormatter> formatter(ListFormatter::createInstance(Locale("en"), errorCode)); 118 if (U_FAILURE(errorCode)) { 119 dataerrln( 120 "ListFormatter::createInstance(Locale(\"en\"), errorCode) failed in Test9946: %s", 121 u_errorName(errorCode)); 122 return; 123 } 124 UnicodeString data[3] = {"{0}", "{1}", "{2}"}; 125 UnicodeString actualResult; 126 formatter->format(data, 3, actualResult, errorCode); 127 if (U_FAILURE(errorCode)) { 128 dataerrln( 129 "ListFormatter::createInstance(Locale(\"en\"), errorCode) failed in Test9946: %s", 130 u_errorName(errorCode)); 131 return; 132 } 133 UnicodeString expected("{0}, {1}, and {2}"); 134 if (expected != actualResult) { 135 errln("Expected " + expected + ", got " + actualResult); 136 } 137 } 138 139 void ListFormatterTest::TestEnglishUS() { 140 UnicodeString results[4] = { 141 one, 142 one + " and " + two, 143 one + ", " + two + ", and " + three, 144 one + ", " + two + ", " + three + ", and " + four 145 }; 146 147 CheckFourCases("en_US", one, two, three, four, results); 148 } 149 150 // Tests resource loading and inheritance when region sublocale 151 // has only partial data for the listPattern element (overriding 152 // some of the parent data). #12994 153 void ListFormatterTest::TestEnglishGB() { 154 UnicodeString results[4] = { 155 one, 156 one + " and " + two, 157 one + ", " + two + " and " + three, 158 one + ", " + two + ", " + three + " and " + four 159 }; 160 161 CheckFourCases("en_GB", one, two, three, four, results); 162 } 163 164 // Tests resource loading and inheritance when region sublocale 165 // has only partial data for the listPattern element (overriding 166 // some of the parent data). #12994 167 void ListFormatterTest::TestNynorsk() { 168 UnicodeString results[4] = { 169 one, 170 one + " og " + two, 171 one + ", " + two + " og " + three, 172 one + ", " + two + ", " + three + " og " + four 173 }; 174 175 CheckFourCases("nn", one, two, three, four, results); 176 } 177 178 // Tests resource loading and inheritance when region sublocale 179 // has only partial data for the listPattern element (overriding 180 // some of the parent data). #12994 181 void ListFormatterTest::TestChineseTradHK() { 182 UnicodeString results[4] = { 183 one, 184 one + "\u53CA" + two, 185 one + "\u3001" + two + "\u53CA" + three, 186 one + "\u3001" + two + "\u3001" + three + "\u53CA" + four 187 }; 188 189 CheckFourCases("zh_Hant_HK", one, two, three, four, results); 190 } 191 192 // Formatting in Russian. 193 // "\\u0438" is used before the last element, and all elements up to (but not including) the penultimate are followed by a comma. 194 void ListFormatterTest::TestRussian() { 195 UnicodeString and_string = UnicodeString(" \\u0438 ", -1, US_INV).unescape(); 196 UnicodeString results[4] = { 197 one, 198 one + and_string + two, 199 one + ", " + two + and_string + three, 200 one + ", " + two + ", " + three + and_string + four 201 }; 202 203 CheckFourCases("ru", one, two, three, four, results); 204 } 205 206 // Formatting in Malayalam. 207 // For two elements, "\\u0d15\\u0d42\\u0d1f\\u0d3e\\u0d24\\u0d46" is inserted in between. 208 // For more than two elements, comma is inserted between all elements up to (and including) the penultimate, 209 // and the word \\u0d0e\\u0d28\\u0d4d\\u0d28\\u0d3f\\u0d35 is inserted in the end. 210 void ListFormatterTest::TestMalayalam() { 211 UnicodeString pair_string = UnicodeString(" \\u0d15\\u0d42\\u0d1f\\u0d3e\\u0d24\\u0d46 ", -1, US_INV).unescape(); 212 UnicodeString total_string = UnicodeString(" \\u0d0e\\u0d28\\u0d4d\\u0d28\\u0d3f\\u0d35", -1, US_INV).unescape(); 213 UnicodeString results[4] = { 214 one, 215 one + pair_string + two, 216 one + ", " + two + ", " + three + total_string, 217 one + ", " + two + ", " + three + ", " + four + total_string 218 }; 219 220 CheckFourCases("ml", one, two, three, four, results); 221 } 222 223 // Formatting in Zulu. 224 // "and" is used before the last element, and all elements up to (and including) the penultimate are followed by a comma. 225 void ListFormatterTest::TestZulu() { 226 UnicodeString results[4] = { 227 one, 228 one + " ne-" + two, 229 one + ", " + two + ", ne-" + three, 230 one + ", " + two + ", " + three + ", ne-" + four 231 }; 232 233 CheckFourCases("zu", one, two, three, four, results); 234 } 235 236 void ListFormatterTest::TestOutOfOrderPatterns() { 237 UnicodeString results[4] = { 238 one, 239 two + " after " + one, 240 three + " in the last after " + two + " after the first " + one, 241 four + " in the last after " + three + " after " + two + " after the first " + one 242 }; 243 244 UErrorCode errorCode = U_ZERO_ERROR; 245 ListFormatData data("{1} after {0}", "{1} after the first {0}", 246 "{1} after {0}", "{1} in the last after {0}"); 247 ListFormatter formatter(data, errorCode); 248 249 UnicodeString input1[] = {one}; 250 CheckFormatting(&formatter, input1, 1, results[0]); 251 252 UnicodeString input2[] = {one, two}; 253 CheckFormatting(&formatter, input2, 2, results[1]); 254 255 UnicodeString input3[] = {one, two, three}; 256 CheckFormatting(&formatter, input3, 3, results[2]); 257 258 UnicodeString input4[] = {one, two, three, four}; 259 CheckFormatting(&formatter, input4, 4, results[3]); 260 } 261 262 void ListFormatterTest::runIndexedTest(int32_t index, UBool exec, 263 const char* &name, char* /*par */) { 264 switch(index) { 265 case 0: name = "TestRoot"; if (exec) TestRoot(); break; 266 case 1: name = "TestBogus"; if (exec) TestBogus(); break; 267 case 2: name = "TestEnglish"; if (exec) TestEnglish(); break; 268 case 3: name = "TestEnglishUS"; if (exec) TestEnglishUS(); break; 269 case 4: name = "TestRussian"; if (exec) TestRussian(); break; 270 case 5: name = "TestMalayalam"; if (exec) TestMalayalam(); break; 271 case 6: name = "TestZulu"; if (exec) TestZulu(); break; 272 case 7: name = "TestOutOfOrderPatterns"; if (exec) TestOutOfOrderPatterns(); break; 273 case 8: name = "Test9946"; if (exec) Test9946(); break; 274 case 9: name = "TestEnglishGB"; if (exec) TestEnglishGB(); break; 275 case 10: name = "TestNynorsk"; if (exec) TestNynorsk(); break; 276 case 11: name = "TestChineseTradHK"; if (exec) TestChineseTradHK(); break; 277 278 default: name = ""; break; 279 } 280 } 281