1// © 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: UTF-8 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 22ListFormatterTest::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 28void 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 39void 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 60UBool 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 83void 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. 95void 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. 104void 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 115void 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 139void 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 153void 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 167void 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 181void ListFormatterTest::TestChineseTradHK() { 182 UnicodeString and_string = UnicodeString("\\u53CA", -1, US_INV).unescape(); 183 UnicodeString comma_string = UnicodeString("\\u3001", -1, US_INV).unescape(); 184 UnicodeString results[4] = { 185 one, 186 one + and_string + two, 187 one + comma_string + two + and_string + three, 188 one + comma_string + two + comma_string + three + and_string + four 189 }; 190 191 CheckFourCases("zh_Hant_HK", one, two, three, four, results); 192} 193 194// Formatting in Russian. 195// "\\u0438" is used before the last element, and all elements up to (but not including) the penultimate are followed by a comma. 196void ListFormatterTest::TestRussian() { 197 UnicodeString and_string = UnicodeString(" \\u0438 ", -1, US_INV).unescape(); 198 UnicodeString results[4] = { 199 one, 200 one + and_string + two, 201 one + ", " + two + and_string + three, 202 one + ", " + two + ", " + three + and_string + four 203 }; 204 205 CheckFourCases("ru", one, two, three, four, results); 206} 207 208// Formatting in Malayalam. 209// For two elements, "\\u0d15\\u0d42\\u0d1f\\u0d3e\\u0d24\\u0d46" is inserted in between. 210// For more than two elements, comma is inserted between all elements up to (and including) the penultimate, 211// and the word \\u0d0e\\u0d28\\u0d4d\\u0d28\\u0d3f\\u0d35 is inserted in the end. 212void ListFormatterTest::TestMalayalam() { 213 UnicodeString pair_string = UnicodeString(" \\u0d15\\u0d42\\u0d1f\\u0d3e\\u0d24\\u0d46 ", -1, US_INV).unescape(); 214 UnicodeString total_string = UnicodeString(" \\u0d0e\\u0d28\\u0d4d\\u0d28\\u0d3f\\u0d35", -1, US_INV).unescape(); 215 UnicodeString results[4] = { 216 one, 217 one + pair_string + two, 218 one + ", " + two + ", " + three + total_string, 219 one + ", " + two + ", " + three + ", " + four + total_string 220 }; 221 222 CheckFourCases("ml", one, two, three, four, results); 223} 224 225// Formatting in Zulu. 226// "and" is used before the last element, and all elements up to (and including) the penultimate are followed by a comma. 227void ListFormatterTest::TestZulu() { 228 UnicodeString results[4] = { 229 one, 230 one + " ne-" + two, 231 one + ", " + two + ", ne-" + three, 232 one + ", " + two + ", " + three + ", ne-" + four 233 }; 234 235 CheckFourCases("zu", one, two, three, four, results); 236} 237 238void ListFormatterTest::TestOutOfOrderPatterns() { 239 UnicodeString results[4] = { 240 one, 241 two + " after " + one, 242 three + " in the last after " + two + " after the first " + one, 243 four + " in the last after " + three + " after " + two + " after the first " + one 244 }; 245 246 UErrorCode errorCode = U_ZERO_ERROR; 247 ListFormatData data("{1} after {0}", "{1} after the first {0}", 248 "{1} after {0}", "{1} in the last after {0}"); 249 ListFormatter formatter(data, errorCode); 250 251 UnicodeString input1[] = {one}; 252 CheckFormatting(&formatter, input1, 1, results[0]); 253 254 UnicodeString input2[] = {one, two}; 255 CheckFormatting(&formatter, input2, 2, results[1]); 256 257 UnicodeString input3[] = {one, two, three}; 258 CheckFormatting(&formatter, input3, 3, results[2]); 259 260 UnicodeString input4[] = {one, two, three, four}; 261 CheckFormatting(&formatter, input4, 4, results[3]); 262} 263 264void ListFormatterTest::runIndexedTest(int32_t index, UBool exec, 265 const char* &name, char* /*par */) { 266 switch(index) { 267 case 0: name = "TestRoot"; if (exec) TestRoot(); break; 268 case 1: name = "TestBogus"; if (exec) TestBogus(); break; 269 case 2: name = "TestEnglish"; if (exec) TestEnglish(); break; 270 case 3: name = "TestEnglishUS"; if (exec) TestEnglishUS(); break; 271 case 4: name = "TestRussian"; if (exec) TestRussian(); break; 272 case 5: name = "TestMalayalam"; if (exec) TestMalayalam(); break; 273 case 6: name = "TestZulu"; if (exec) TestZulu(); break; 274 case 7: name = "TestOutOfOrderPatterns"; if (exec) TestOutOfOrderPatterns(); break; 275 case 8: name = "Test9946"; if (exec) Test9946(); break; 276 case 9: name = "TestEnglishGB"; if (exec) TestEnglishGB(); break; 277 case 10: name = "TestNynorsk"; if (exec) TestNynorsk(); break; 278 case 11: name = "TestChineseTradHK"; if (exec) TestChineseTradHK(); break; 279 280 default: name = ""; break; 281 } 282} 283