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 35void 36TransliteratorErrorTest::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 51void 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 167void 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 212void 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 262class StubTransliterator: public Transliterator{ 263public: 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 275void 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