]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/intltest/transtst.cpp
ICU-66108.tar.gz
[apple/icu.git] / icuSources / test / intltest / transtst.cpp
index 33f54a7e93bf4072e5c4bddf1ecdf7c7bd643903..6b263a988deb553e0ea9f8fedf5f438c58b27b1e 100644 (file)
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 1999-2014, International Business Machines
+*   Copyright (C) 1999-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   Date        Name        Description
@@ -194,6 +196,7 @@ TransliteratorTest::runIndexedTest(int32_t index, UBool exec,
         TESTCASE(82,TestHalfwidthFullwidth);
         TESTCASE(83,TestThai);
         TESTCASE(84,TestAny);
+        TESTCASE(85,TestHansHant);
         default: name = ""; break;
     }
 }
@@ -241,7 +244,8 @@ void TransliteratorTest::TestInstantiation() {
         if (t == 0) {
 #if UCONFIG_NO_BREAK_ITERATION
             // If UCONFIG_NO_BREAK_ITERATION is on, then only Thai should fail.
-            if (id.compare((UnicodeString)"Thai-Latin") != 0)
+            if (id.compare((UnicodeString)"Thai-Latn") != 0 &&
+                id.compare((UnicodeString)"Thai-Latin") != 0)
 #endif
                 dataerrln(UnicodeString("FAIL: Couldn't create ") + id +
                       /*", parse error " + parseError.code +*/
@@ -409,7 +413,7 @@ void TransliteratorTest::TestRuleBasedInverse(void) {
         "caccb", "xyzzy",
     };
 
-    int32_t DATA_length = (int32_t)(sizeof(DATA) / sizeof(DATA[0]));
+    int32_t DATA_length = UPRV_LENGTHOF(DATA);
 
     UErrorCode status = U_ZERO_ERROR;
     UParseError parseError;
@@ -457,7 +461,7 @@ void TransliteratorTest::TestKeyboard(void) {
         0, "AycAY", // null means finishKeyboardTransliteration
     };
 
-    keyboardAux(*t, DATA, (int32_t)(sizeof(DATA)/sizeof(DATA[0])));
+    keyboardAux(*t, DATA, UPRV_LENGTHOF(DATA));
     delete t;
 }
 
@@ -492,7 +496,7 @@ void TransliteratorTest::TestKeyboard2(void) {
         0, "AycAY", // null means finishKeyboardTransliteration
     };
 
-    keyboardAux(*t, DATA, (int32_t)(sizeof(DATA)/sizeof(DATA[0])));
+    keyboardAux(*t, DATA, UPRV_LENGTHOF(DATA));
     delete t;
 }
 
@@ -526,7 +530,7 @@ void TransliteratorTest::TestKeyboard3(void) {
         errln("FAIL: RBT constructor failed");
         return;
     }
-    keyboardAux(*t, DATA, (int32_t)(sizeof(DATA)/sizeof(DATA[0])));
+    keyboardAux(*t, DATA, UPRV_LENGTHOF(DATA));
     delete t;
 }
 
@@ -654,7 +658,7 @@ int gTestFilterClassID = 0;
  * Used by TestFiltering().
  */
 class TestFilter : public UnicodeFilter {
-    virtual UnicodeFunctor* clone() const {
+    virtual TestFilter* clone() const {
         return new TestFilter(*this);
     }
     virtual UBool contains(UChar32 c) const {
@@ -877,7 +881,7 @@ void TransliteratorTest::TestJ329(void) {
         { FALSE, "a > b; c > d" },
         { TRUE,  "a > b; no operator; c > d" },
     };
-    int32_t DATA_length = (int32_t)(sizeof(DATA) / sizeof(DATA[0]));
+    int32_t DATA_length = UPRV_LENGTHOF(DATA);
 
     for (int32_t i=0; i<DATA_length; ++i) {
         UErrorCode status = U_ZERO_ERROR;
@@ -921,7 +925,7 @@ void TransliteratorTest::TestSegments(void) {
         "a1 b2",
         "a1.a.1 b2.b.2",
     };
-    int32_t DATA_length = (int32_t)(sizeof(DATA)/sizeof(*DATA));
+    int32_t DATA_length = UPRV_LENGTHOF(DATA);
 
     for (int32_t i=0; i<DATA_length; i+=3) {
         logln("Pattern: " + prettify(DATA[i]));
@@ -953,7 +957,7 @@ void TransliteratorTest::TestCursorOffset(void) {
 
         "prbetaxyz preBETApost",
     };
-    int32_t DATA_length = (int32_t)(sizeof(DATA)/sizeof(*DATA));
+    int32_t DATA_length = UPRV_LENGTHOF(DATA);
 
     for (int32_t i=0; i<DATA_length; i+=3) {
         logln("Pattern: " + prettify(DATA[i]));
@@ -994,7 +998,7 @@ void TransliteratorTest::TestArbitraryVariableValues(void) {
         "ab xYzxyz stY78",
         "ABE ENDEND 1129",
     };
-    int32_t DATA_length = (int32_t)(sizeof(DATA)/sizeof(*DATA));
+    int32_t DATA_length = UPRV_LENGTHOF(DATA);
 
     for (int32_t i=0; i<DATA_length; i+=3) {
         logln("Pattern: " + prettify(DATA[i]));
@@ -1039,7 +1043,7 @@ void TransliteratorTest::TestPositionHandling(void) {
         3, 8, 3, 8,
     };
 
-    int32_t n = (int32_t)(sizeof(DATA) / sizeof(DATA[0])) / 3;
+    int32_t n = UPRV_LENGTHOF(DATA) / 3;
     for (int32_t i=0; i<n; i++) {
         UErrorCode status = U_ZERO_ERROR;
         UParseError parseError;
@@ -1097,7 +1101,7 @@ void TransliteratorTest::TestHiraganaKatakana(void) {
         "\\u307C\\u3051\\u3060\\u3042\\u3093\\u30FC",
         "\\u30DC\\u30F6\\u30C0\\u30FC\\u30F3\\u30FC",
     };
-    int32_t DATA_length = (int32_t)(sizeof(DATA) / sizeof(DATA[0]));
+    int32_t DATA_length = UPRV_LENGTHOF(DATA);
 
     for (int32_t i=0; i<DATA_length; i+=3) {
         UnicodeString h = CharsToUnicodeString(DATA[i+1]);
@@ -1189,7 +1193,7 @@ void TransliteratorTest::TestFilterIDs(void) {
         "xyz",
         "xyz",
     };
-    enum { DATA_length = sizeof(DATA) / sizeof(DATA[0]) };
+    enum { DATA_length = UPRV_LENGTHOF(DATA) };
 
     for (int i=0; i<DATA_length; i+=4) {
         UnicodeString ID(DATA[i], "");
@@ -1313,7 +1317,7 @@ void TransliteratorTest::TestLiberalizedID(void) {
         " Latin[a-z]-Greek  ", "[a-z]Latin-Greek", "inline filter",
         "  null  ; latin-greek  ", NULL /*"Null;Latin-Greek"*/, "compound whitespace",
     };
-    const int32_t DATA_length = sizeof(DATA)/sizeof(DATA[0]);
+    const int32_t DATA_length = UPRV_LENGTHOF(DATA);
     UParseError parseError;
     UErrorCode status= U_ZERO_ERROR;
     for (int32_t i=0; i<DATA_length; i+=3) {
@@ -1728,7 +1732,7 @@ void TransliteratorTest::TestToRules(void) {
         "([AEIOUYaeiouy]\\u0304[[:M:]-[\\u0304\\u0345]]*)i > | $1 \\u0345;",
         "([AEIOUYaeiouy]\\u0304[[:M:]-[\\u0304\\u0345]]*)i > | $1 \\u0345;",
     };
-    static const int32_t DATA_length = (int32_t)(sizeof(DATA) / sizeof(DATA[0]));
+    static const int32_t DATA_length = UPRV_LENGTHOF(DATA);
 
     for (int32_t d=0; d < DATA_length; d+=3) {
         if (DATA[d] == RBT) {
@@ -1944,7 +1948,7 @@ class TestTrans : public Transliterator {
 public:
     TestTrans(const UnicodeString& id) : Transliterator(id, 0) {
     }
-    virtual Transliterator* clone(void) const {
+    virtual TestTrans* clone(void) const {
         return new TestTrans(getID());
     }
     virtual void handleTransliterate(Replaceable& /*text*/, UTransPosition& offsets,
@@ -2337,17 +2341,17 @@ void TransliteratorTest::TestCompoundFilterID(void) {
             exp = CharsToUnicodeString(DATA[i+3]);
         }
         UBool expOk = (DATA[i+1] != NULL);
-        Transliterator* t = NULL;
+        LocalPointer<Transliterator> t;
         UParseError pe;
         UErrorCode ec = U_ZERO_ERROR;
         if (id.charAt(0) == 0x23/*#*/) {
-            t = Transliterator::createFromRules("ID", id, direction, pe, ec);
+            t.adoptInstead(Transliterator::createFromRules("ID", id, direction, pe, ec));
         } else {
-            t = Transliterator::createInstance(id, direction, pe, ec);
+            t.adoptInstead(Transliterator::createInstance(id, direction, pe, ec));
         }
-        UBool ok = (t != NULL && U_SUCCESS(ec));
+        UBool ok = (t.isValid() && U_SUCCESS(ec));
         UnicodeString transID;
-        if (t!=0) {
+        if (t.isValid()) {
             transID = t->getID();
         }
         else {
@@ -2359,7 +2363,6 @@ void TransliteratorTest::TestCompoundFilterID(void) {
             if (source.length() != 0) {
                 expect(*t, source, exp);
             }
-            delete t;
         } else {
             dataerrln((UnicodeString)"FAIL: " + id + " => " + transID + ", " +
                   u_errorName(ec));
@@ -2786,7 +2789,7 @@ void TransliteratorTest::TestCompoundLatinRT(){
         "kimakurvata",
         "san\\u0304java"
     };
-    const int MAX_LEN = sizeof(source)/sizeof(source[0]);
+    const int MAX_LEN = UPRV_LENGTHOF(source);
     const char* const expected[MAX_LEN] = {
         "\\u0930\\u094D\\u092E\\u094D\\u0915\\u094D\\u0937\\u0947\\u0924\\u094D",
         "\\u0936\\u094d\\u0930\\u0940\\u092e\\u0926\\u094d",
@@ -2806,7 +2809,7 @@ void TransliteratorTest::TestCompoundLatinRT(){
         "\\u0915\\u093f\\u092e\\u0915\\u0941\\u0930\\u094d\\u0935\\u0924",
         "\\u0938\\u0902\\u091c\\u0935"
     };
-    if(MAX_LEN != sizeof(expected)/sizeof(expected[0])) {
+    if(MAX_LEN != UPRV_LENGTHOF(expected)) {
         errln("error in TestCompoundLatinRT: source[] and expected[] have different lengths!");
         return;
     }
@@ -2932,7 +2935,7 @@ void TransliteratorTest::TestLocaleResource() {
         "el-Latin",              "\\u03B2",         "v",
         "Greek-Latin",           "\\u03B2",         "b",
     };
-    const int32_t DATA_length = sizeof(DATA) / sizeof(DATA[0]);
+    const int32_t DATA_length = UPRV_LENGTHOF(DATA);
     for (int32_t i=0; i<DATA_length; i+=3) {
         UParseError pe;
         UErrorCode ec = U_ZERO_ERROR;
@@ -3072,7 +3075,7 @@ void TransliteratorTest::TestIDForms() {
         "-", NULL, NULL,
         "/", NULL, NULL,
     };
-    const int32_t DATA_length = sizeof(DATA)/sizeof(DATA[0]);
+    const int32_t DATA_length = UPRV_LENGTHOF(DATA);
     
     for (int32_t i=0; i<DATA_length; i+=3) {
         const char* ID = DATA[i];
@@ -3173,12 +3176,12 @@ void TransliteratorTest::TestToRulesMark() {
     
     UParseError pe;
     UErrorCode ec = U_ZERO_ERROR;
-    Transliterator *t2 = Transliterator::createFromRules("source-target", UnicodeString(testRules, -1, US_INV), UTRANS_FORWARD, pe, ec);
-    Transliterator *t3 = Transliterator::createFromRules("target-source", UnicodeString(testRules, -1, US_INV), UTRANS_REVERSE, pe, ec);
+    LocalPointer<Transliterator> t2(
+            Transliterator::createFromRules("source-target", UnicodeString(testRules, -1, US_INV), UTRANS_FORWARD, pe, ec));
+    LocalPointer<Transliterator> t3(
+            Transliterator::createFromRules("target-source", UnicodeString(testRules, -1, US_INV), UTRANS_REVERSE, pe, ec));
 
     if (U_FAILURE(ec)) {
-        delete t2;
-        delete t3;
         dataerrln((UnicodeString)"FAIL: createFromRules => " + u_errorName(ec));
         return;
     }
@@ -3188,9 +3191,6 @@ void TransliteratorTest::TestToRulesMark() {
     
     checkRules("Failed toRules FORWARD", *t2, UnicodeString(testRulesForward, -1, US_INV));
     checkRules("Failed toRules BACKWARD", *t3, UnicodeString(testRulesBackward, -1, US_INV));
-
-    delete t2;
-    delete t3;
 }
 
 /**
@@ -3288,7 +3288,7 @@ void TransliteratorTest::TestDisplayName() {
         "NFC", "Any to NFC", "Any to NFD",
     };
 
-    int32_t DATA_length = sizeof(DATA) / sizeof(DATA[0]);
+    int32_t DATA_length = UPRV_LENGTHOF(DATA);
     
     Locale US("en", "US");
     
@@ -3572,12 +3572,24 @@ void TransliteratorTest::TestIncrementalProgress(void) {
                 _trans(*t, test, rev);
                 Transliterator *inv = t->createInverse(status);
                 if (U_FAILURE(status)) {
+                    // The following are forward-only, it is OK that creating an inverse will not work:
+                    // 1. Devanagari-Arabic
+                    // 2. Any-*/BGN
+                    // 2a. Any-*/BGN_1981
+                    // 3. Any-*/UNGEGN
+                    // 4. Any-*/MNS
+                    // If UCONFIG_NO_BREAK_ITERATION is on, Latin-Thai is also not expected to work.
+                    if (    id.compare((UnicodeString)"Devanagari-Arabic/") != 0
+                         && !(id.startsWith((UnicodeString)"Any-") &&
+                                (id.endsWith((UnicodeString)"/BGN") || id.endsWith((UnicodeString)"/BGN_1981") || id.endsWith((UnicodeString)"/UNGEGN") || id.endsWith((UnicodeString)"/MNS"))
+                             )
 #if UCONFIG_NO_BREAK_ITERATION
-                    // If UCONFIG_NO_BREAK_ITERATION is on, then only Thai should fail.
-                    if (id.compare((UnicodeString)"Latin-Thai/") != 0)
+                         && id.compare((UnicodeString)"Latin-Thai/") != 0
 #endif
+                       )
+                    {
                         errln((UnicodeString)"FAIL: Could not create inverse of " + id);
-
+                    }
                     delete t;
                     delete inv;
                     continue;
@@ -3862,6 +3874,21 @@ void TransliteratorTest::TestAnyX(void) {
            CharsToUnicodeString("greek:abkABK hiragana:abuku cyrillic:abc"));
 
     delete anyLatin;
+
+    status = U_ZERO_ERROR;
+    Transliterator* anyASCII =
+        Transliterator::createInstance("Any-Latin;Latin-ASCII", UTRANS_FORWARD, parseError, status);
+    if (U_FAILURE(status) || anyASCII==0) {
+        dataerrln("FAIL: createInstance returned NULL and/or set status %s", u_errorName(status));
+        delete anyASCII;
+        return;
+    }
+
+    expect(*anyASCII,
+           CharsToUnicodeString("ArabicDigits:\\u0660\\u0661\\u0664\\u0669 PersianDigits:\\u06F0\\u06F1\\u06F4\\u06F9"),
+           CharsToUnicodeString("ArabicDigits:0149 PersianDigits:0149"));
+
+    delete anyASCII;
 }
 
 /**
@@ -4051,7 +4078,7 @@ void TransliteratorTest::TestAllCodepoints(){
 
 } 
 
-#define TEST_TRANSLIT_ID(id, cls) { \
+#define TEST_TRANSLIT_ID(id, cls) UPRV_BLOCK_MACRO_BEGIN { \
   UErrorCode ec = U_ZERO_ERROR; \
   Transliterator* t = Transliterator::createInstance(id, UTRANS_FORWARD, ec); \
   if (U_FAILURE(ec)) { \
@@ -4063,9 +4090,9 @@ void TransliteratorTest::TestAllCodepoints(){
     /* *t = *t; */ /*can't do this: coverage test for assignment op*/ \
   } \
   delete t; \
-}
+} UPRV_BLOCK_MACRO_END
 
-#define TEST_TRANSLIT_RULE(rule, cls) { \
+#define TEST_TRANSLIT_RULE(rule, cls) UPRV_BLOCK_MACRO_BEGIN { \
   UErrorCode ec = U_ZERO_ERROR; \
   UParseError pe; \
   Transliterator* t = Transliterator::createFromRules("_", rule, UTRANS_FORWARD, pe, ec); \
@@ -4078,7 +4105,7 @@ void TransliteratorTest::TestAllCodepoints(){
     /* *t = *t; */ /*can't do this: coverage test for assignment op*/ \
   } \
   delete t; \
-}
+} UPRV_BLOCK_MACRO_END
 
 void TransliteratorTest::TestBoilerplate() {
     TEST_TRANSLIT_ID("Any-Latin", AnyTransliterator);
@@ -4305,7 +4332,7 @@ static const char* BOGUS_BEGIN_END_RULES[] = {
     "::Upper;"
     "::END;"
 };
-static const int32_t BOGUS_BEGIN_END_RULES_length = (int32_t)(sizeof(BOGUS_BEGIN_END_RULES) / sizeof(BOGUS_BEGIN_END_RULES[0]));
+static const int32_t BOGUS_BEGIN_END_RULES_length = UPRV_LENGTHOF(BOGUS_BEGIN_END_RULES);
 */
 
 static const char* BEGIN_END_TEST_CASES[] = {
@@ -4335,7 +4362,7 @@ static const char* BEGIN_END_TEST_CASES[] = {
 //    BEGIN_END_RULES[16], "abc xy ababc xyz aba", "XY xy ABXY xyz YZ",
     BEGIN_END_RULES[17], "abc xy ababc xyz aba", "XY xy ABXY xyz YZ"
 };
-static const int32_t BEGIN_END_TEST_CASES_length = (int32_t)(sizeof(BEGIN_END_TEST_CASES) / sizeof(BEGIN_END_TEST_CASES[0]));
+static const int32_t BEGIN_END_TEST_CASES_length = UPRV_LENGTHOF(BEGIN_END_TEST_CASES);
 
 void TransliteratorTest::TestBeginEnd() {
     // run through the list of test cases above
@@ -4522,9 +4549,9 @@ void TransliteratorTest::TestRuleStripping() {
     static const UChar expectedRule[] = {
         0xE001,0x003E,0x0C01,0x003B,0
     };
-    UChar result[sizeof(rule)/sizeof(rule[0])];
+    UChar result[UPRV_LENGTHOF(rule)];
     UErrorCode status = U_ZERO_ERROR;
-    int32_t len = utrans_stripRules(rule, (int32_t)(sizeof(rule)/sizeof(rule[0])), result, &status);
+    int32_t len = utrans_stripRules(rule, UPRV_LENGTHOF(rule), result, &status);
     if (len != u_strlen(expectedRule)) {
         errln("utrans_stripRules return len = %d", len);
     }
@@ -4558,7 +4585,7 @@ void TransliteratorTest::TestHalfwidthFullwidth(void) {
         "\\uFFE9\\uFFEA\\uFFEB\\uFFEC\\u0061\\uFF71\\u00AF\\u0020",
         "\\u2190\\u2191\\u2192\\u2193\\uFF41\\u30A2\\uFFE3\\u3000",
     };
-    int32_t DATA_length = (int32_t)(sizeof(DATA) / sizeof(DATA[0]));
+    int32_t DATA_length = UPRV_LENGTHOF(DATA);
 
     for (int32_t i=0; i<DATA_length; i+=3) {
         UnicodeString h = CharsToUnicodeString(DATA[i+1]);
@@ -4664,6 +4691,32 @@ void TransliteratorTest::TestThai(void) {
 #endif
 }
 
+/**
+ * Test for rdar://problem/61817095 (and maybe eventually other Hans-Hant errors)
+ * Apple-only
+ * ICU4C only
+ */
+void TransliteratorTest::TestHansHant(void) {
+    UParseError parseError;
+    UErrorCode status = U_ZERO_ERROR;
+    Transliterator* tr = Transliterator::createInstance("Hans-Hant", UTRANS_FORWARD, parseError, status);
+    if (U_FAILURE(status)) {
+        errln("FAIL: createInstance failed with %s", u_errorName(status));
+        return;
+    }
+    
+    const char* _sourceText =     "\\u810f \\u5185\\u810f \\u810f\\u5668 \\u4e94\\u810f \\u5fc3\\u810f \\u809d\\u810f \\u813e\\u810f \\u80c3\\u810f \\u80be\\u810f \\u80f0\\u810f \\u810f\\u8151 \\u80ba\\u810f";
+    const char* _expectedResult = "\\u9ad2 \\u5167\\u81df \\u81df\\u5668 \\u4e94\\u81df \\u5fc3\\u81df \\u809d\\u81df \\u813e\\u81df \\u80c3\\u81df \\u814e\\u81df \\u80f0\\u81df \\u81df\\u8151 \\u80ba\\u81df";
+    
+    UnicodeString sourceText(_sourceText);
+    UnicodeString expectedResult(_expectedResult);
+    sourceText = sourceText.unescape();
+    expectedResult = expectedResult.unescape();
+    
+    expect(*tr, sourceText, expectedResult);
+    delete tr;
+}
+
 
 //======================================================================
 // Support methods