Home | History | Annotate | Download | only in intltest
      1 // Copyright (C) 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /********************************************************************
      4  * Copyright (c) 2001-2009, International Business Machines
      5  * Corporation and others. All Rights Reserved.
      6  *********************************************************************
      7  *   This test program is intended for testing error conditions of the
      8  *   transliterator APIs to make sure the exceptions are raised where
      9  *   necessary.
     10  *
     11  *   Date        Name        Description
     12  *   11/14/2001  hshih       Creation.
     13  *
     14  ********************************************************************/
     15 
     16 #include "unicode/utypes.h"
     17 
     18 #if !UCONFIG_NO_TRANSLITERATION
     19 
     20 #include "ittrans.h"
     21 #include "trnserr.h"
     22 #include "unicode/utypes.h"
     23 #include "unicode/translit.h"
     24 #include "unicode/uniset.h"
     25 #include "unicode/unifilt.h"
     26 #include "cpdtrans.h"
     27 #include <string.h>
     28 #include <stdio.h>
     29 #include <stdlib.h>
     30 #include "unicode/rep.h"
     31 #include "unicode/locid.h"
     32 
     33 //---------------------------------------------
     34 // runIndexedTest
     35 //---------------------------------------------
     36 
     37 void
     38 TransliteratorErrorTest::runIndexedTest(int32_t index, UBool exec,
     39                                       const char* &name, char* /*par*/) {
     40     switch (index) {
     41         TESTCASE(0,TestTransliteratorErrors);
     42         TESTCASE(1, TestUnicodeSetErrors);
     43         TESTCASE(2, TestRBTErrors);
     44         TESTCASE(3, TestCoverage);
     45         //TESTCASE(3, TestUniToHexErrors);
     46         //TESTCASE(4, TestHexToUniErrors);
     47         // TODO: Add a subclass to test clone().
     48         default: name = ""; break;
     49     }
     50 }
     51 
     52 
     53 void TransliteratorErrorTest::TestTransliteratorErrors() {
     54     UnicodeString trans="Latin-Greek";
     55     UnicodeString bogusID="LATINGREEK-GREEKLATIN";
     56     UnicodeString newID="Bogus-Latin";
     57     UnicodeString newIDRules="zzz > Z; f <> ph";
     58     UnicodeString bogusRules="a } [b-g m-p ";
     59     UParseError parseError;
     60     UErrorCode status = U_ZERO_ERROR;
     61     UnicodeString testString="A quick fox jumped over the lazy dog.";
     62     UnicodeString insertString="cats and dogs";
     63     int32_t stoppedAt = 0, len;
     64     UTransPosition pos;
     65 
     66     Transliterator* t= Transliterator::createInstance(trans, UTRANS_FORWARD, parseError, status);
     67     if(t==0 || U_FAILURE(status)){
     68         dataerrln("FAIL: construction of Latin-Greek - %s", u_errorName(status));
     69         return;
     70     }
     71     pos.contextLimit = 0;
     72     pos.contextStart = 0;
     73     pos.limit = 0;
     74     pos.start = 0;
     75     len = testString.length();
     76     stoppedAt = t->transliterate(testString, 0, 100);
     77     if (stoppedAt != -1) {
     78         errln("FAIL: Out of bounds check failed (1).");
     79     } else if (testString.length() != len) {
     80         testString="A quick fox jumped over the lazy dog.";
     81         errln("FAIL: Transliterate fails and the target string was modified.");
     82     }
     83     stoppedAt = t->transliterate(testString, 100, testString.length()-1);
     84     if (stoppedAt != -1)
     85         errln("FAIL: Out of bounds check failed (2).");
     86     else if (testString.length() != len) {
     87         testString="A quick fox jumped over the lazy dog.";
     88         errln("FAIL: Transliterate fails and the target string was modified.");
     89     }
     90     pos.start = 100;
     91     pos.limit = testString.length();
     92     t->transliterate(testString, pos, status);
     93     if (U_SUCCESS(status)) {
     94         errln("FAIL: Start offset is out of bounds, error not reported.\n");
     95     }
     96     status = U_ZERO_ERROR;
     97     pos.limit = 100;
     98     pos.start = 0;
     99     t->transliterate(testString, pos, status);
    100     if (U_SUCCESS(status)) {
    101         errln("FAIL: Limit offset is out of bounds, error not reported.\n");
    102     }
    103     status = U_ZERO_ERROR;
    104     len = pos.contextLimit = testString.length();
    105     pos.contextStart = 0;
    106     pos.limit = len - 1;
    107     pos.start = 5;
    108     t->transliterate(testString, pos, insertString, status);
    109     if (len == pos.limit) {
    110         errln("FAIL: Test insertion with string: the transliteration position limit didn't change as expected.");
    111         if (U_SUCCESS(status)) {
    112             errln("FAIL: Error code wasn't set either.");
    113         }
    114     }
    115     status = U_ZERO_ERROR;
    116     pos.contextStart = 0;
    117     pos.contextLimit = testString.length();
    118     pos.limit = testString.length() -1;
    119     pos.start = 5;
    120     t->transliterate(testString, pos, (UChar32)0x0061, status);
    121     if (len == pos.limit) {
    122         errln("FAIL: Test insertion with character: the transliteration position limit didn't change as expected.");
    123         if (U_SUCCESS(status)) {
    124             errln("FAIL: Error code wasn't set either.");
    125         }
    126     }
    127     status = U_ZERO_ERROR;
    128     len = pos.limit = testString.length();
    129     pos.contextStart = 0;
    130     pos.contextLimit = testString.length() - 1;
    131     pos.start = 5;
    132     t->transliterate(testString, pos, insertString, status);
    133     if (U_SUCCESS(status)) {
    134         errln("FAIL: Out of bounds check failed (3).");
    135         if (testString.length() != len)
    136             errln("FAIL: The input string was modified though the offsets were out of bounds.");
    137     }
    138     Transliterator* t1= Transliterator::createInstance(bogusID, UTRANS_FORWARD, parseError, status);
    139     if(t1!=0 || U_SUCCESS(status)){
    140         delete t1;
    141         errln("FAIL: construction of bogus ID \"LATINGREEK-GREEKLATIN\"");
    142     }
    143     status = U_ZERO_ERROR;
    144     Transliterator* t2 = Transliterator::createFromRules(newID, newIDRules, UTRANS_FORWARD, parseError, status);
    145     if (U_SUCCESS(status)) {
    146         Transliterator* t3 = t2->createInverse(status);
    147         if (U_SUCCESS(status)) {
    148             delete t3;
    149             errln("FAIL: The newID transliterator was not registered so createInverse should fail.");
    150         } else {
    151             delete t3;
    152         }
    153     }
    154     status = U_ZERO_ERROR;
    155     Transliterator* t4 = Transliterator::createFromRules(newID, bogusRules, UTRANS_FORWARD, parseError, status);
    156     if (t4 != NULL || U_SUCCESS(status)) {
    157         errln("FAIL: The rules is malformed but error was not reported.");
    158         if (parseError.offset != -1) {
    159             errln("FAIL: The parse error offset isn't set correctly when fails.");
    160         } else if (parseError.postContext[0] == 0 || parseError.preContext[0] == 0) {
    161             errln("FAIL: The parse error pre/post context isn't reset properly.");
    162         }
    163         delete t4;
    164     }
    165     delete t;
    166     delete t2;
    167 }
    168 
    169 void TransliteratorErrorTest::TestUnicodeSetErrors() {
    170     UnicodeString badPattern="[[:L:]-[0x0300-0x0400]";
    171     UnicodeSet set;
    172     UErrorCode status = U_ZERO_ERROR;
    173     UnicodeString result;
    174 
    175     if (!set.isEmpty()) {
    176         errln("FAIL: The default ctor of UnicodeSet created a non-empty object.");
    177     }
    178     set.applyPattern(badPattern, status);
    179     if (U_SUCCESS(status)) {
    180         errln("FAIL: Applied a bad pattern to the UnicodeSet object okay.");
    181     }
    182     status = U_ZERO_ERROR;
    183     UnicodeSet *set1 = new UnicodeSet(badPattern, status);
    184     if (U_SUCCESS(status)) {
    185         errln("FAIL: Created a UnicodeSet based on bad patterns.");
    186     }
    187     delete set1;
    188 }
    189 
    190 //void TransliteratorErrorTest::TestUniToHexErrors() {
    191 //    UErrorCode status = U_ZERO_ERROR;
    192 //    Transliterator *t = new UnicodeToHexTransliterator("", TRUE, NULL, status);
    193 //    if (U_SUCCESS(status)) {
    194 //        errln("FAIL: Created a UnicodeToHexTransliterator with an empty pattern.");
    195 //    }
    196 //    delete t;
    197 //
    198 //    status = U_ZERO_ERROR;
    199 //    t = new UnicodeToHexTransliterator("\\x", TRUE, NULL, status);
    200 //    if (U_SUCCESS(status)) {
    201 //        errln("FAIL: Created a UnicodeToHexTransliterator with a bad pattern.");
    202 //    }
    203 //    delete t;
    204 //
    205 //    status = U_ZERO_ERROR;
    206 //    t = new UnicodeToHexTransliterator();
    207 //    ((UnicodeToHexTransliterator*)t)->applyPattern("\\x", status);
    208 //    if (U_SUCCESS(status)) {
    209 //        errln("FAIL: UnicodeToHexTransliterator::applyPattern succeeded with a bad pattern.");
    210 //    }
    211 //    delete t;
    212 //}
    213 
    214 void TransliteratorErrorTest::TestRBTErrors() {
    215 
    216     UnicodeString rules="ab>y";
    217     UnicodeString id="MyRandom-YReverse";
    218     //UnicodeString goodPattern="[[:L:]&[\\u0000-\\uFFFF]]"; /* all BMP letters */
    219     UErrorCode status = U_ZERO_ERROR;
    220     UParseError parseErr;
    221     /*UnicodeSet *set = new UnicodeSet(goodPattern, status);
    222     if (U_FAILURE(status)) {
    223         errln("FAIL: Was not able to create a good UnicodeSet based on valid patterns.");
    224         return;
    225     }*/
    226     Transliterator *t = Transliterator::createFromRules(id, rules, UTRANS_REVERSE, parseErr, status);
    227     if (U_FAILURE(status)) {
    228         errln("FAIL: Was not able to create a good RBT to test registration.");
    229         //delete set;
    230         return;
    231     }
    232     Transliterator::registerInstance(t);
    233     Transliterator::unregister(id);
    234     status = U_ZERO_ERROR;
    235     Transliterator* t1= Transliterator::createInstance(id, UTRANS_REVERSE, parseErr, status);
    236     if(U_SUCCESS(status)){
    237         delete t1;
    238         errln("FAIL: construction of unregistered ID failed.");
    239     }
    240 }
    241 
    242 //void TransliteratorErrorTest::TestHexToUniErrors() {
    243 //    UErrorCode status = U_ZERO_ERROR;
    244 //    Transliterator *t = new HexToUnicodeTransliterator("", NULL, status);
    245 //    if (U_FAILURE(status)) {
    246 //        errln("FAIL: Could not create a HexToUnicodeTransliterator with an empty pattern.");
    247 //    }
    248 //    delete t;
    249 //    status = U_ZERO_ERROR;
    250 //    t = new HexToUnicodeTransliterator("\\x", NULL, status);
    251 //    if (U_SUCCESS(status)) {
    252 //        errln("FAIL: Created a HexToUnicodeTransliterator with a bad pattern.");
    253 //    }
    254 //    delete t;
    255 //    status = U_ZERO_ERROR;
    256 //    t = new HexToUnicodeTransliterator();
    257 //    ((HexToUnicodeTransliterator*)t)->applyPattern("\\x", status);
    258 //    if (U_SUCCESS(status)) {
    259 //        errln("FAIL: HexToUnicodeTransliterator::applyPattern succeeded with a bad pattern.");
    260 //    }
    261 //    delete t;
    262 //}
    263 
    264 class StubTransliterator: public Transliterator{
    265 public:
    266     StubTransliterator(): Transliterator(UNICODE_STRING_SIMPLE("Any-Null"), 0) {}
    267     virtual void handleTransliterate(Replaceable& ,UTransPosition& offsets,UBool) const {
    268         offsets.start = offsets.limit;
    269     }
    270 
    271     virtual UClassID getDynamicClassID() const{
    272         static char classID = 0;
    273         return (UClassID)&classID;
    274     }
    275 };
    276 
    277 void TransliteratorErrorTest::TestCoverage() {
    278     StubTransliterator stub;
    279 
    280     if (stub.clone() != NULL){
    281         errln("FAIL: default Transliterator::clone() should return NULL");
    282     }
    283 }
    284 
    285 #endif /* #if !UCONFIG_NO_TRANSLITERATION */
    286