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 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// 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. 152void 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. 168void 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. 183void 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 194void 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 220void 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