]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/intltest/listformattertest.cpp
ICU-66108.tar.gz
[apple/icu.git] / icuSources / test / intltest / listformattertest.cpp
index 763f933095e2ef39992ce7f1e872595cf4d77aec..b4418bcd42d35f3b739bf727c9fddd82b60f12a6 100644 (file)
 
 #if !UCONFIG_NO_FORMATTING
 
+void ListFormatterTest::runIndexedTest(int32_t index, UBool exec,
+                                       const char* &name, char* /*par */) {
+    TESTCASE_AUTO_BEGIN;
+    TESTCASE_AUTO(TestRoot);
+    TESTCASE_AUTO(TestBogus);
+    TESTCASE_AUTO(TestEnglish);
+    TESTCASE_AUTO(TestEnglishUS);
+    TESTCASE_AUTO(TestRussian);
+    TESTCASE_AUTO(TestMalayalam);
+    TESTCASE_AUTO(TestZulu);
+    TESTCASE_AUTO(TestOutOfOrderPatterns);
+    TESTCASE_AUTO(Test9946);
+    TESTCASE_AUTO(TestEnglishGB);
+    TESTCASE_AUTO(TestNynorsk);
+    TESTCASE_AUTO(TestChineseTradHK);
+    TESTCASE_AUTO(TestFieldPositionIteratorWontCrash);
+    TESTCASE_AUTO(TestFieldPositionIteratorWith1Item);
+    TESTCASE_AUTO(TestFieldPositionIteratorWith1ItemAndDataBefore);
+    TESTCASE_AUTO(TestFieldPositionIteratorWith2Items);
+    TESTCASE_AUTO(TestFieldPositionIteratorWith2ItemsAndDataBefore);
+    TESTCASE_AUTO(TestFieldPositionIteratorWith2ItemsPatternShift);
+    TESTCASE_AUTO(TestFieldPositionIteratorWith3Items);
+    TESTCASE_AUTO(TestFieldPositionIteratorWith3ItemsAndDataBefore);
+    TESTCASE_AUTO(TestFieldPositionIteratorWith3ItemsPatternShift);
+    TESTCASE_AUTO(TestFormattedValue);
+    TESTCASE_AUTO(TestDifferentStyles);
+    TESTCASE_AUTO(TestBadStylesFail);
+    TESTCASE_AUTO(TestCreateStyled);
+    TESTCASE_AUTO(TestContextual);
+    TESTCASE_AUTO_END;
+}
+
 namespace {
 const char* attrString(int32_t attrId) {
   switch (attrId) {
@@ -524,8 +556,9 @@ void ListFormatterTest::TestOutOfOrderPatterns() {
     };
 
     IcuTestErrorCode errorCode(*this, "TestOutOfOrderPatterns()");
+    Locale locale("en");
     ListFormatData data("{1} after {0}", "{1} after the first {0}",
-                        "{1} after {0}", "{1} in the last after {0}");
+                        "{1} after {0}", "{1} in the last after {0}", locale);
     ListFormatter formatter(data, errorCode);
 
     UnicodeString input1[] = {one};
@@ -611,58 +644,160 @@ void ListFormatterTest::TestBadStylesFail() {
     }
 }
 
-void ListFormatterTest::runIndexedTest(int32_t index, UBool exec,
-                                       const char* &name, char* /*par */) {
-    switch(index) {
-        case 0: name = "TestRoot"; if (exec) TestRoot(); break;
-        case 1: name = "TestBogus"; if (exec) TestBogus(); break;
-        case 2: name = "TestEnglish"; if (exec) TestEnglish(); break;
-        case 3: name = "TestEnglishUS"; if (exec) TestEnglishUS(); break;
-        case 4: name = "TestRussian"; if (exec) TestRussian(); break;
-        case 5: name = "TestMalayalam"; if (exec) TestMalayalam(); break;
-        case 6: name = "TestZulu"; if (exec) TestZulu(); break;
-        case 7: name = "TestOutOfOrderPatterns"; if (exec) TestOutOfOrderPatterns(); break;
-        case 8: name = "Test9946"; if (exec) Test9946(); break;
-        case 9: name = "TestEnglishGB"; if (exec) TestEnglishGB(); break;
-        case 10: name = "TestNynorsk"; if (exec) TestNynorsk(); break;
-        case 11: name = "TestChineseTradHK"; if (exec) TestChineseTradHK(); break;
-        case 12: name = "TestFieldPositionIteratorWontCrash";
-                 if (exec) TestFieldPositionIteratorWontCrash();
-                 break;
-        case 13: name = "TestFieldPositionIteratorWith1Item";
-                 if (exec) TestFieldPositionIteratorWith1Item();
-                 break;
-        case 14: name = "TestFieldPositionIteratorWith1ItemAndDataBefore";
-                 if (exec) TestFieldPositionIteratorWith1ItemAndDataBefore();
-                 break;
-        case 15: name = "TestFieldPositionIteratorWith2Items";
-                 if (exec) TestFieldPositionIteratorWith2Items();
-                 break;
-        case 16: name = "TestFieldPositionIteratorWith2ItemsAndDataBefore";
-                 if (exec) TestFieldPositionIteratorWith2ItemsAndDataBefore();
-                 break;
-        case 17: name = "TestFieldPositionIteratorWith2ItemsPatternShift";
-                 if (exec) TestFieldPositionIteratorWith2ItemsPatternShift();
-                 break;
-        case 18: name = "TestFieldPositionIteratorWith3Items";
-                 if (exec) TestFieldPositionIteratorWith3Items();
-                 break;
-        case 19: name = "TestFieldPositionIteratorWith3ItemsAndDataBefore";
-                 if (exec) TestFieldPositionIteratorWith3ItemsAndDataBefore();
-                 break;
-        case 20: name = "TestFieldPositionIteratorWith3ItemsPatternShift";
-                 if (exec) TestFieldPositionIteratorWith3ItemsPatternShift();
-                 break;
-        case 21: name = "TestFormattedValue";
-                 if (exec) TestFormattedValue();
-                 break;
-        case 22: name = "TestDifferentStyles";
-                 if (exec) TestDifferentStyles();
-                 break;
-        case 23: name = "TestBadStylesFail";
-                 if (exec) TestBadStylesFail();
-                 break;
-        default: name = ""; break;
+void ListFormatterTest::TestCreateStyled() {
+    IcuTestErrorCode status(*this, "TestCreateStyled");
+    // Locale en has interesting data
+    struct TestCase {
+        const char* locale;
+        UListFormatterType type;
+        UListFormatterWidth width;
+        const char16_t* expected3;
+        const char16_t* expected2;
+        const char16_t* expected1;
+    } cases[] = {
+        { "pt", ULISTFMT_TYPE_AND, ULISTFMT_WIDTH_WIDE, u"A, B e C", u"A e B", u"A" },
+        { "pt", ULISTFMT_TYPE_AND, ULISTFMT_WIDTH_SHORT, u"A, B e C", u"A e B", u"A" },
+        { "pt", ULISTFMT_TYPE_AND, ULISTFMT_WIDTH_NARROW, u"A, B, C", u"A, B", u"A" },
+        { "pt", ULISTFMT_TYPE_OR, ULISTFMT_WIDTH_WIDE, u"A, B ou C", u"A ou B", u"A" },
+        { "pt", ULISTFMT_TYPE_OR, ULISTFMT_WIDTH_SHORT, u"A, B ou C", u"A ou B", u"A" },
+        { "pt", ULISTFMT_TYPE_OR, ULISTFMT_WIDTH_NARROW, u"A, B ou C", u"A ou B", u"A" },
+        { "pt", ULISTFMT_TYPE_UNITS, ULISTFMT_WIDTH_WIDE, u"A, B e C", u"A e B", u"A" },
+        { "pt", ULISTFMT_TYPE_UNITS, ULISTFMT_WIDTH_SHORT, u"A, B e C", u"A e B", u"A" },
+        { "pt", ULISTFMT_TYPE_UNITS, ULISTFMT_WIDTH_NARROW, u"A B C", u"A B", u"A" },
+        { "en", ULISTFMT_TYPE_AND, ULISTFMT_WIDTH_WIDE, u"A, B, and C", u"A and B", u"A" },
+        { "en", ULISTFMT_TYPE_AND, ULISTFMT_WIDTH_SHORT, u"A, B, & C", u"A & B", u"A" },
+        { "en", ULISTFMT_TYPE_AND, ULISTFMT_WIDTH_NARROW, u"A, B, C", u"A, B", u"A" },
+        { "en", ULISTFMT_TYPE_OR, ULISTFMT_WIDTH_WIDE, u"A, B, or C", u"A or B", u"A" },
+        { "en", ULISTFMT_TYPE_OR, ULISTFMT_WIDTH_SHORT, u"A, B, or C", u"A or B", u"A" },
+        { "en", ULISTFMT_TYPE_OR, ULISTFMT_WIDTH_NARROW, u"A, B, or C", u"A or B", u"A" },
+        { "en", ULISTFMT_TYPE_UNITS, ULISTFMT_WIDTH_WIDE, u"A, B, C", u"A, B", u"A" },
+        { "en", ULISTFMT_TYPE_UNITS, ULISTFMT_WIDTH_SHORT, u"A, B, C", u"A, B", u"A" },
+        { "en", ULISTFMT_TYPE_UNITS, ULISTFMT_WIDTH_NARROW, u"A B C", u"A B", u"A" },
+    };
+    for (auto cas : cases) {
+        LocalPointer<ListFormatter> fmt(
+            ListFormatter::createInstance(cas.locale, cas.type, cas.width, status),
+            status);
+        if (status.errIfFailureAndReset()) {
+            continue;
+        }
+        UnicodeString message = UnicodeString(u"TestCreateStyled loc=")
+            + cas.locale + u" type="
+            + Int64ToUnicodeString(cas.type) + u" width="
+            + Int64ToUnicodeString(cas.width);
+        const UnicodeString inputs3[] = {
+            u"A",
+            u"B",
+            u"C"
+        };
+        FormattedList result = fmt->formatStringsToValue(inputs3, UPRV_LENGTHOF(inputs3), status);
+        assertEquals(message, cas.expected3, result.toTempString(status));
+        const UnicodeString inputs2[] = {
+            u"A",
+            u"B"
+        };
+        result = fmt->formatStringsToValue(inputs2, UPRV_LENGTHOF(inputs2), status);
+        assertEquals(message, cas.expected2, result.toTempString(status));
+        const UnicodeString inputs1[] = {
+            u"A"
+        };
+        result = fmt->formatStringsToValue(inputs1, UPRV_LENGTHOF(inputs1), status);
+        assertEquals(message, cas.expected1, result.toTempString(status));
+    }
+}
+
+void ListFormatterTest::TestContextual() {
+    IcuTestErrorCode status(*this, "TestContextual");
+    std::vector<std::string> es = { "es", "es_419" , "es_PY", "es_DO" };
+    std::vector<std::string> he = { "he", "he_IL", "iw", "iw_IL" };
+    std::vector<std::string> th = { "th", "th_TH" };
+    UListFormatterWidth widths [] = {
+        ULISTFMT_WIDTH_WIDE, ULISTFMT_WIDTH_SHORT, ULISTFMT_WIDTH_NARROW
+    };
+    struct TestCase {
+        std::vector<std::string> locales;
+        UListFormatterType type;
+        const char16_t* expected;
+        const char16_t* data1;
+        const char16_t* data2;
+        const char16_t* data3;
+    } cases[] = {
+        { es, ULISTFMT_TYPE_AND, u"fascinante e increíblemente",
+          u"fascinante",                     u"increíblemente",       nullptr },
+        { es, ULISTFMT_TYPE_AND, u"Comunicaciones Industriales e IIoT",
+          u"Comunicaciones Industriales",    u"IIoT",                 nullptr },
+        { es, ULISTFMT_TYPE_AND, u"España e Italia",         u"España",   u"Italia",      nullptr },
+        { es, ULISTFMT_TYPE_AND, u"hijas intrépidas e hijos solidarios",
+          u"hijas intrépidas",               u"hijos solidarios",     nullptr },
+        { es, ULISTFMT_TYPE_AND, u"a un hombre e hirieron a otro",
+          u"a un hombre",                    u"hirieron a otro",      nullptr },
+        { es, ULISTFMT_TYPE_AND, u"hija e hijo",             u"hija",     u"hijo",        nullptr },
+        { es, ULISTFMT_TYPE_AND, u"esposa, hija e hijo",     u"esposa",   u"hija",        u"hijo" },
+        // For 'y' exception
+        { es, ULISTFMT_TYPE_AND, u"oro y hierro",            u"oro",      u"hierro",      nullptr },
+        { es, ULISTFMT_TYPE_AND, u"agua y hielo",            u"agua",     u"hielo",       nullptr },
+        { es, ULISTFMT_TYPE_AND, u"colágeno y hialurónico",  u"colágeno", u"hialurónico", nullptr },
+
+        { es, ULISTFMT_TYPE_OR, u"desierto u oasis",         u"desierto", u"oasis",       nullptr },
+        { es, ULISTFMT_TYPE_OR, u"oasis, desierto u océano", u"oasis",    u"desierto",    u"océano" },
+        { es, ULISTFMT_TYPE_OR, u"7 u 8",                    u"7",        u"8",           nullptr },
+        { es, ULISTFMT_TYPE_OR, u"7 u 80",                   u"7",        u"80",          nullptr },
+        { es, ULISTFMT_TYPE_OR, u"7 u 800",                  u"7",        u"800",         nullptr },
+        { es, ULISTFMT_TYPE_OR, u"6, 7 u 8",                 u"6",        u"7",           u"8" },
+        { es, ULISTFMT_TYPE_OR, u"10 u 11",                  u"10",       u"11",          nullptr },
+        { es, ULISTFMT_TYPE_OR, u"10 o 111",                 u"10",       u"111",         nullptr },
+        { es, ULISTFMT_TYPE_OR, u"10 o 11.2",                u"10",       u"11.2",        nullptr },
+        { es, ULISTFMT_TYPE_OR, u"9, 10 u 11",               u"9",        u"10",          u"11" },
+
+        { he, ULISTFMT_TYPE_AND, u"a, b ו-c",               u"a",      u"b",      u"c" },
+        { he, ULISTFMT_TYPE_AND, u"a ו-b",                  u"a",      u"b",      nullptr },
+        { he, ULISTFMT_TYPE_AND, u"1, 2 ו-3",               u"1",      u"2",      u"3" },
+        { he, ULISTFMT_TYPE_AND, u"1 ו-2",                  u"1",      u"2",      nullptr },
+        { he, ULISTFMT_TYPE_AND, u"אהבה ומקווה",            u"אהבה",   u"מקווה",  nullptr },
+        { he, ULISTFMT_TYPE_AND, u"אהבה, מקווה ואמונה",     u"אהבה",   u"מקווה",  u"אמונה" },
+        
+        // rdar://64483589
+        { th, ULISTFMT_TYPE_AND, u"ข้อความธรรมดาและ 1 ภาพ",                    u"ข้อความธรรมดา",  u"1 ภาพ",        nullptr },
+        { th, ULISTFMT_TYPE_AND, u"ข้อความธรรมดาและข้อความธรรมดา",               u"ข้อความธรรมดา", u"ข้อความธรรมดา",  nullptr },
+        { th, ULISTFMT_TYPE_AND, u"0 และ 1 ภาพ",                              u"0",            u"1 ภาพ",        nullptr },
+        { th, ULISTFMT_TYPE_AND, u"0 และข้อความธรรมดา",                         u"0",           u"ข้อความธรรมดา",  nullptr },
+        { th, ULISTFMT_TYPE_AND, u"ข้อความธรรมดา ข้อความธรรมดา และข้อความธรรมดา",  u"ข้อความธรรมดา", u"ข้อความธรรมดา", u"ข้อความธรรมดา" },
+        { th, ULISTFMT_TYPE_AND, u"ข้อความธรรมดา ข้อความธรรมดา และ 1 ภาพ",       u"ข้อความธรรมดา", u"ข้อความธรรมดา",  u"1 ภาพ" },
+        { th, ULISTFMT_TYPE_OR,  u"ข้อความธรรมดา หรือ 1 ภาพ",                     u"ข้อความธรรมดา", u"1 ภาพ",        nullptr },
+        { th, ULISTFMT_TYPE_OR,  u"ข้อความธรรมดา หรือ ข้อความธรรมดา",               u"ข้อความธรรมดา", u"ข้อความธรรมดา",  nullptr },
+        { th, ULISTFMT_TYPE_OR,  u"ข้อความธรรมดา, ข้อความธรรมดา หรือ 1 ภาพ",       u"ข้อความธรรมดา", u"ข้อความธรรมดา", u"1 ภาพ" },
+    };
+    for (auto width : widths) {
+        for (auto cas : cases) {
+            for (auto locale : cas.locales) {
+                if ((locale == "th" || locale == "th_TH") && cas.type == ULISTFMT_TYPE_OR && (width == ULISTFMT_WIDTH_SHORT || width == ULISTFMT_WIDTH_NARROW)) {
+                    // this test was written to assume all the widths product the same result, but that isn't
+                    // true of the Thai "or" formats, so we skip the short and narrow Thai "or" formats (which
+                    // work the same way as the "and" formats)
+                    continue;
+                }
+                
+                LocalPointer<ListFormatter> fmt(
+                    ListFormatter::createInstance(locale.c_str(), cas.type, width, status),
+                    status);
+                if (status.errIfFailureAndReset()) {
+                    continue;
+                }
+                UnicodeString message = UnicodeString(u"TestContextual loc=")
+                    + locale.c_str() + u" type="
+                    + Int64ToUnicodeString(cas.type) + u" width="
+                    + Int64ToUnicodeString(width);
+                if (cas.data3 == nullptr) {
+                    const UnicodeString inputs2[] = { cas.data1, cas.data2 };
+                    FormattedList result = fmt->formatStringsToValue(inputs2, UPRV_LENGTHOF(inputs2), status);
+                    assertEquals(message, cas.expected, result.toTempString(status));
+                } else {
+                    const UnicodeString inputs3[] = { cas.data1, cas.data2, cas.data3 };
+                    FormattedList result = fmt->formatStringsToValue(inputs3, UPRV_LENGTHOF(inputs3), status);
+                    assertEquals(message, cas.expected, result.toTempString(status));
+                }
+            }
+        }
     }
 }