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