]>
Commit | Line | Data |
---|---|---|
b75a7d8f A |
1 | /******************************************************************** |
2 | * COPYRIGHT: | |
729e4ab9 | 3 | * Copyright (c) 1997-2010, International Business Machines Corporation and |
b75a7d8f A |
4 | * others. All Rights Reserved. |
5 | ********************************************************************/ | |
6 | ||
7 | /** | |
8 | * IntlTestCollator is the medium level test class for everything in the directory "collate". | |
9 | */ | |
10 | ||
11 | /*********************************************************************** | |
12 | * Modification history | |
13 | * Date Name Description | |
14 | * 02/14/2001 synwee Compare with cintltst and commented away tests | |
15 | * that are not run. | |
16 | ***********************************************************************/ | |
17 | ||
18 | #include "unicode/utypes.h" | |
19 | ||
729e4ab9 | 20 | #if !UCONFIG_NO_COLLATION && !UCONFIG_NO_FILE_IO |
b75a7d8f A |
21 | |
22 | #include "unicode/uchar.h" | |
374ca955 | 23 | #include "unicode/tstdtmod.h" |
b75a7d8f A |
24 | #include "cstring.h" |
25 | #include "ucol_tok.h" | |
b75a7d8f | 26 | #include "tscoll.h" |
b75a7d8f A |
27 | #include "dadrcoll.h" |
28 | ||
29 | U_CDECL_BEGIN | |
30 | static void U_CALLCONV deleteSeqElement(void *elem) { | |
31 | delete((SeqElement *)elem); | |
32 | } | |
33 | U_CDECL_END | |
34 | ||
35 | DataDrivenCollatorTest::DataDrivenCollatorTest() | |
36 | : seq(StringCharacterIterator("")), | |
37 | status(U_ZERO_ERROR), | |
38 | sequences(status) | |
39 | { | |
374ca955 | 40 | driver = TestDataModule::getTestDataModule("DataDrivenCollationTest", *this, status); |
b75a7d8f | 41 | sequences.setDeleter(deleteSeqElement); |
73c04bcf | 42 | UCA = (RuleBasedCollator*)Collator::createInstance("root", status); |
b75a7d8f A |
43 | } |
44 | ||
45 | DataDrivenCollatorTest::~DataDrivenCollatorTest() | |
46 | { | |
47 | delete driver; | |
73c04bcf | 48 | delete UCA; |
b75a7d8f A |
49 | } |
50 | ||
51 | void DataDrivenCollatorTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par */) | |
52 | { | |
53 | if(driver != NULL) { | |
54 | if (exec) | |
55 | { | |
56 | logln("TestSuite Collator: "); | |
57 | } | |
58 | const DataMap *info = NULL; | |
59 | TestData *testData = driver->createTestData(index, status); | |
60 | if(U_SUCCESS(status)) { | |
61 | name = testData->getName(); | |
62 | if(testData->getInfo(info, status)) { | |
63 | log(info->getString("Description", status)); | |
64 | } | |
65 | if(exec) { | |
66 | log(name); | |
67 | logln("---"); | |
68 | logln(""); | |
69 | processTest(testData); | |
70 | } | |
71 | delete testData; | |
72 | } else { | |
73 | name = ""; | |
74 | } | |
75 | } else { | |
729e4ab9 | 76 | dataerrln("collate/DataDrivenTest data not initialized!"); |
b75a7d8f A |
77 | name = ""; |
78 | } | |
79 | ||
80 | ||
81 | } | |
82 | ||
83 | UBool | |
84 | DataDrivenCollatorTest::setTestSequence(const UnicodeString &setSequence, SeqElement &el) { | |
85 | seq.setText(setSequence); | |
86 | return getNextInSequence(el); | |
87 | } | |
88 | ||
89 | // Parses the sequence to be tested | |
90 | UBool | |
91 | DataDrivenCollatorTest::getNextInSequence(SeqElement &el) { | |
92 | el.source.truncate(0); | |
93 | UBool quoted = FALSE; | |
94 | UBool quotedsingle = FALSE; | |
95 | UChar32 currChar = 0; | |
96 | ||
97 | while(currChar != CharacterIterator::DONE) { | |
98 | currChar= seq.next32PostInc(); | |
99 | if(!quoted) { | |
100 | if(u_isWhitespace(currChar)) { | |
101 | continue; | |
102 | } | |
103 | switch(currChar) { | |
104 | case CharacterIterator::DONE: | |
105 | break; | |
106 | case 0x003C /* < */: | |
107 | el.relation = Collator::LESS; | |
108 | currChar = CharacterIterator::DONE; | |
109 | break; | |
110 | case 0x003D /* = */: | |
111 | el.relation = Collator::EQUAL; | |
112 | currChar = CharacterIterator::DONE; | |
113 | break; | |
114 | case 0x003E /* > */: | |
115 | el.relation = Collator::GREATER; | |
116 | currChar = CharacterIterator::DONE; | |
117 | break; | |
118 | case 0x0027 /* ' */: /* very basic quoting */ | |
119 | quoted = TRUE; | |
120 | quotedsingle = FALSE; | |
121 | break; | |
122 | case 0x005c /* \ */: /* single quote */ | |
123 | quoted = TRUE; | |
124 | quotedsingle = TRUE; | |
125 | break; | |
126 | default: | |
127 | el.source.append(currChar); | |
128 | } | |
129 | } else { | |
130 | if(currChar == CharacterIterator::DONE) { | |
131 | status = U_ILLEGAL_ARGUMENT_ERROR; | |
132 | errln("Quote in sequence not closed!"); | |
133 | return FALSE; | |
134 | } else if(currChar == 0x0027) { | |
135 | quoted = FALSE; | |
136 | } else { | |
137 | el.source.append(currChar); | |
138 | } | |
139 | if(quotedsingle) { | |
140 | quoted = FALSE; | |
141 | } | |
142 | } | |
143 | } | |
144 | return seq.hasNext(); | |
145 | } | |
146 | ||
147 | // Reads the options string and sets appropriate attributes in collator | |
148 | void | |
149 | DataDrivenCollatorTest::processArguments(Collator *col, const UChar *start, int32_t optLen) { | |
150 | const UChar *end = start+optLen; | |
151 | UColAttribute attrib; | |
152 | UColAttributeValue value; | |
153 | ||
154 | if(optLen == 0) { | |
155 | return; | |
156 | } | |
157 | ||
158 | start = ucol_tok_getNextArgument(start, end, &attrib, &value, &status); | |
159 | while(start != NULL) { | |
160 | if(U_SUCCESS(status)) { | |
161 | col->setAttribute(attrib, value, status); | |
162 | } | |
163 | start = ucol_tok_getNextArgument(start, end, &attrib, &value, &status); | |
164 | } | |
165 | } | |
166 | ||
73c04bcf | 167 | void |
b75a7d8f A |
168 | DataDrivenCollatorTest::processTest(TestData *testData) { |
169 | Collator *col = NULL; | |
170 | const UChar *arguments = NULL; | |
171 | int32_t argLen = 0; | |
172 | const DataMap *settings = NULL; | |
173 | const DataMap *currentCase = NULL; | |
174 | UErrorCode intStatus = U_ZERO_ERROR; | |
175 | UnicodeString testSetting; | |
176 | while(testData->nextSettings(settings, status)) { | |
177 | intStatus = U_ZERO_ERROR; | |
178 | // try to get a locale | |
179 | testSetting = settings->getString("TestLocale", intStatus); | |
180 | if(U_SUCCESS(intStatus)) { | |
181 | char localeName[256]; | |
182 | testSetting.extract(0, testSetting.length(), localeName, ""); | |
183 | col = Collator::createInstance(localeName, status); | |
184 | if(U_SUCCESS(status)) { | |
185 | logln("Testing collator for locale "+testSetting); | |
186 | } else { | |
187 | errln("Unable to instantiate collator for locale "+testSetting); | |
188 | return; | |
189 | } | |
190 | } else { | |
191 | // if no locale, try from rules | |
192 | intStatus = U_ZERO_ERROR; | |
193 | testSetting = settings->getString("Rules", intStatus); | |
194 | if(U_SUCCESS(intStatus)) { | |
195 | col = new RuleBasedCollator(testSetting, status); | |
196 | if(U_SUCCESS(status)) { | |
197 | logln("Testing collator for rules "+testSetting); | |
198 | } else { | |
729e4ab9 | 199 | errln("Unable to instantiate collator for rules "+testSetting+" - "+u_errorName(status)); |
b75a7d8f A |
200 | return; |
201 | } | |
202 | } else { | |
203 | errln("No collator definition!"); | |
729e4ab9 | 204 | return; |
b75a7d8f A |
205 | } |
206 | } | |
73c04bcf A |
207 | |
208 | int32_t cloneSize = 0; | |
209 | uint8_t* cloneBuf = NULL; | |
210 | RuleBasedCollator* clone = NULL; | |
211 | if(col != NULL){ | |
212 | RuleBasedCollator* rbc = (RuleBasedCollator*)col; | |
213 | cloneSize = rbc->cloneBinary(NULL, 0, intStatus); | |
214 | intStatus = U_ZERO_ERROR; | |
215 | cloneBuf = (uint8_t*) malloc(cloneSize); | |
216 | cloneSize = rbc->cloneBinary(cloneBuf, cloneSize, intStatus); | |
217 | clone = new RuleBasedCollator(cloneBuf, cloneSize, UCA, intStatus); | |
218 | if(U_FAILURE(intStatus)){ | |
219 | errln("Could not clone the RuleBasedCollator. Error: %s", u_errorName(intStatus)); | |
220 | intStatus= U_ZERO_ERROR; | |
221 | } | |
b75a7d8f A |
222 | // get attributes |
223 | testSetting = settings->getString("Arguments", intStatus); | |
224 | if(U_SUCCESS(intStatus)) { | |
225 | logln("Arguments: "+testSetting); | |
226 | argLen = testSetting.length(); | |
227 | arguments = testSetting.getBuffer(); | |
228 | processArguments(col, arguments, argLen); | |
73c04bcf A |
229 | if(clone != NULL){ |
230 | processArguments(clone, arguments, argLen); | |
231 | } | |
b75a7d8f A |
232 | if(U_FAILURE(status)) { |
233 | errln("Couldn't process arguments"); | |
234 | break; | |
235 | } | |
236 | } else { | |
237 | intStatus = U_ZERO_ERROR; | |
238 | } | |
239 | // Start the processing | |
240 | while(testData->nextCase(currentCase, status)) { | |
241 | UnicodeString sequence = currentCase->getString("sequence", status); | |
242 | if(U_SUCCESS(status)) { | |
243 | processSequence(col, sequence); | |
73c04bcf A |
244 | if(clone != NULL){ |
245 | processSequence(clone, sequence); | |
246 | } | |
b75a7d8f A |
247 | } |
248 | } | |
249 | } else { | |
250 | errln("Couldn't instantiate a collator!"); | |
251 | } | |
73c04bcf A |
252 | delete clone; |
253 | free(cloneBuf); | |
b75a7d8f A |
254 | delete col; |
255 | col = NULL; | |
256 | } | |
257 | } | |
258 | ||
73c04bcf | 259 | |
b75a7d8f A |
260 | void |
261 | DataDrivenCollatorTest::processSequence(Collator* col, const UnicodeString &sequence) { | |
262 | Collator::EComparisonResult relation = Collator::EQUAL; | |
263 | UBool hasNext; | |
264 | SeqElement *source = NULL; | |
265 | SeqElement *target = NULL; | |
266 | int32_t j = 0; | |
267 | ||
268 | sequences.removeAllElements(); | |
269 | ||
270 | target = new SeqElement(); | |
271 | ||
272 | setTestSequence(sequence, *target); | |
273 | sequences.addElement(target, status); | |
274 | ||
275 | do { | |
276 | relation = Collator::EQUAL; | |
277 | target = new SeqElement(); | |
278 | hasNext = getNextInSequence(*target); | |
279 | for(j = sequences.size(); j > 0; j--) { | |
280 | source = (SeqElement *)sequences.elementAt(j-1); | |
281 | if(relation == Collator::EQUAL && source->relation != Collator::EQUAL) { | |
282 | relation = source->relation; | |
283 | } | |
284 | doTest(col, source->source, target->source, relation); | |
285 | } | |
286 | sequences.addElement(target, status); | |
287 | source = target; | |
288 | } while(hasNext); | |
289 | } | |
290 | ||
291 | #endif /* #if !UCONFIG_NO_COLLATION */ |