]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/intltest/dadrcoll.cpp
ICU-461.18.tar.gz
[apple/icu.git] / icuSources / test / intltest / dadrcoll.cpp
1 /********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2010, International Business Machines Corporation and
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
20 #if !UCONFIG_NO_COLLATION && !UCONFIG_NO_FILE_IO
21
22 #include "unicode/uchar.h"
23 #include "unicode/tstdtmod.h"
24 #include "cstring.h"
25 #include "ucol_tok.h"
26 #include "tscoll.h"
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 {
40 driver = TestDataModule::getTestDataModule("DataDrivenCollationTest", *this, status);
41 sequences.setDeleter(deleteSeqElement);
42 UCA = (RuleBasedCollator*)Collator::createInstance("root", status);
43 }
44
45 DataDrivenCollatorTest::~DataDrivenCollatorTest()
46 {
47 delete driver;
48 delete UCA;
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 {
76 dataerrln("collate/DataDrivenTest data not initialized!");
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
167 void
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 {
199 errln("Unable to instantiate collator for rules "+testSetting+" - "+u_errorName(status));
200 return;
201 }
202 } else {
203 errln("No collator definition!");
204 return;
205 }
206 }
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 }
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);
229 if(clone != NULL){
230 processArguments(clone, arguments, argLen);
231 }
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);
244 if(clone != NULL){
245 processSequence(clone, sequence);
246 }
247 }
248 }
249 } else {
250 errln("Couldn't instantiate a collator!");
251 }
252 delete clone;
253 free(cloneBuf);
254 delete col;
255 col = NULL;
256 }
257 }
258
259
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 */