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
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)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
TestTransliteratorErrors()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
TestUnicodeSetErrors()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
TestRBTErrors()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:
StubTransliterator()264 StubTransliterator(): Transliterator(UNICODE_STRING_SIMPLE("Any-Null"), 0) {}
handleTransliterate(Replaceable &,UTransPosition & offsets,UBool) const265 virtual void handleTransliterate(Replaceable& ,UTransPosition& offsets,UBool) const {
266 offsets.start = offsets.limit;
267 }
268
getDynamicClassID() const269 virtual UClassID getDynamicClassID() const{
270 static char classID = 0;
271 return (UClassID)&classID;
272 }
273 };
274
TestCoverage()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