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 // Formatting in Russian. 151 // "\\u0438" is used before the last element, and all elements up to (but not including) the penultimate are followed by a comma. 152 void ListFormatterTest::TestRussian() { 153 UnicodeString and_string = UnicodeString(" \\u0438 ", -1, US_INV).unescape(); 154 UnicodeString results[4] = { 155 one, 156 one + and_string + two, 157 one + ", " + two + and_string + three, 158 one + ", " + two + ", " + three + and_string + four 159 }; 160 161 CheckFourCases("ru", one, two, three, four, results); 162 } 163 164 // Formatting in Malayalam. 165 // For two elements, "\\u0d15\\u0d42\\u0d1f\\u0d3e\\u0d24\\u0d46" is inserted in between. 166 // For more than two elements, comma is inserted between all elements up to (and including) the penultimate, 167 // and the word \\u0d0e\\u0d28\\u0d4d\\u0d28\\u0d3f\\u0d35 is inserted in the end. 168 void ListFormatterTest::TestMalayalam() { 169 UnicodeString pair_string = UnicodeString(" \\u0d15\\u0d42\\u0d1f\\u0d3e\\u0d24\\u0d46 ", -1, US_INV).unescape(); 170 UnicodeString total_string = UnicodeString(" \\u0d0e\\u0d28\\u0d4d\\u0d28\\u0d3f\\u0d35", -1, US_INV).unescape(); 171 UnicodeString results[4] = { 172 one, 173 one + pair_string + two, 174 one + ", " + two + ", " + three + total_string, 175 one + ", " + two + ", " + three + ", " + four + total_string 176 }; 177 178 CheckFourCases("ml", one, two, three, four, results); 179 } 180 181 // Formatting in Zulu. 182 // "and" is used before the last element, and all elements up to (and including) the penultimate are followed by a comma. 183 void ListFormatterTest::TestZulu() { 184 UnicodeString results[4] = { 185 one, 186 one + " ne-" + two, 187 one + ", " + two + ", ne-" + three, 188 one + ", " + two + ", " + three + ", ne-" + four 189 }; 190 191 CheckFourCases("zu", one, two, three, four, results); 192 } 193 194 void ListFormatterTest::TestOutOfOrderPatterns() { 195 UnicodeString results[4] = { 196 one, 197 two + " after " + one, 198 three + " in the last after " + two + " after the first " + one, 199 four + " in the last after " + three + " after " + two + " after the first " + one 200 }; 201 202 UErrorCode errorCode = U_ZERO_ERROR; 203 ListFormatData data("{1} after {0}", "{1} after the first {0}", 204 "{1} after {0}", "{1} in the last after {0}"); 205 ListFormatter formatter(data, errorCode); 206 207 UnicodeString input1[] = {one}; 208 CheckFormatting(&formatter, input1, 1, results[0]); 209 210 UnicodeString input2[] = {one, two}; 211 CheckFormatting(&formatter, input2, 2, results[1]); 212 213 UnicodeString input3[] = {one, two, three}; 214 CheckFormatting(&formatter, input3, 3, results[2]); 215 216 UnicodeString input4[] = {one, two, three, four}; 217 CheckFormatting(&formatter, input4, 4, results[3]); 218 } 219 220 void ListFormatterTest::runIndexedTest(int32_t index, UBool exec, 221 const char* &name, char* /*par */) { 222 switch(index) { 223 case 0: name = "TestRoot"; if (exec) TestRoot(); break; 224 case 1: name = "TestBogus"; if (exec) TestBogus(); break; 225 case 2: name = "TestEnglish"; if (exec) TestEnglish(); break; 226 case 3: name = "TestEnglishUS"; if (exec) TestEnglishUS(); break; 227 case 4: name = "TestRussian"; if (exec) TestRussian(); break; 228 case 5: name = "TestMalayalam"; if (exec) TestMalayalam(); break; 229 case 6: name = "TestZulu"; if (exec) TestZulu(); break; 230 case 7: name = "TestOutOfOrderPatterns"; if (exec) TestOutOfOrderPatterns(); break; 231 case 8: name = "Test9946"; if (exec) Test9946(); break; 232 233 default: name = ""; break; 234 } 235 } 236