1 /********************************************************************
3 * Copyright (c) 1997-2010, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
8 * IntlTestCollator is the medium level test class for everything in the directory "collate".
11 /***********************************************************************
12 * Modification history
13 * Date Name Description
14 * 02/14/2001 synwee Compare with cintltst and commented away tests
16 ***********************************************************************/
18 #include "unicode/utypes.h"
20 #if !UCONFIG_NO_COLLATION && !UCONFIG_NO_FILE_IO
22 #include "unicode/uchar.h"
23 #include "unicode/tstdtmod.h"
30 static void U_CALLCONV
deleteSeqElement(void *elem
) {
31 delete((SeqElement
*)elem
);
35 DataDrivenCollatorTest::DataDrivenCollatorTest()
36 : seq(StringCharacterIterator("")),
40 driver
= TestDataModule::getTestDataModule("DataDrivenCollationTest", *this, status
);
41 sequences
.setDeleter(deleteSeqElement
);
42 UCA
= (RuleBasedCollator
*)Collator::createInstance("root", status
);
45 DataDrivenCollatorTest::~DataDrivenCollatorTest()
51 void DataDrivenCollatorTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par */)
56 logln("TestSuite Collator: ");
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
));
69 processTest(testData
);
76 dataerrln("collate/DataDrivenTest data not initialized!");
84 DataDrivenCollatorTest::setTestSequence(const UnicodeString
&setSequence
, SeqElement
&el
) {
85 seq
.setText(setSequence
);
86 return getNextInSequence(el
);
89 // Parses the sequence to be tested
91 DataDrivenCollatorTest::getNextInSequence(SeqElement
&el
) {
92 el
.source
.truncate(0);
94 UBool quotedsingle
= FALSE
;
97 while(currChar
!= CharacterIterator::DONE
) {
98 currChar
= seq
.next32PostInc();
100 if(u_isWhitespace(currChar
)) {
104 case CharacterIterator::DONE
:
107 el
.relation
= Collator::LESS
;
108 currChar
= CharacterIterator::DONE
;
111 el
.relation
= Collator::EQUAL
;
112 currChar
= CharacterIterator::DONE
;
115 el
.relation
= Collator::GREATER
;
116 currChar
= CharacterIterator::DONE
;
118 case 0x0027 /* ' */: /* very basic quoting */
120 quotedsingle
= FALSE
;
122 case 0x005c /* \ */: /* single quote */
127 el
.source
.append(currChar
);
130 if(currChar
== CharacterIterator::DONE
) {
131 status
= U_ILLEGAL_ARGUMENT_ERROR
;
132 errln("Quote in sequence not closed!");
134 } else if(currChar
== 0x0027) {
137 el
.source
.append(currChar
);
144 return seq
.hasNext();
147 // Reads the options string and sets appropriate attributes in collator
149 DataDrivenCollatorTest::processArguments(Collator
*col
, const UChar
*start
, int32_t optLen
) {
150 const UChar
*end
= start
+optLen
;
151 UColAttribute attrib
;
152 UColAttributeValue value
;
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
);
163 start
= ucol_tok_getNextArgument(start
, end
, &attrib
, &value
, &status
);
168 DataDrivenCollatorTest::processTest(TestData
*testData
) {
169 Collator
*col
= NULL
;
170 const UChar
*arguments
= NULL
;
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
);
187 errln("Unable to instantiate collator for locale "+testSetting
);
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
);
199 errln("Unable to instantiate collator for rules "+testSetting
+" - "+u_errorName(status
));
203 errln("No collator definition!");
208 int32_t cloneSize
= 0;
209 uint8_t* cloneBuf
= NULL
;
210 RuleBasedCollator
* clone
= 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
;
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
);
230 processArguments(clone
, arguments
, argLen
);
232 if(U_FAILURE(status
)) {
233 errln("Couldn't process arguments");
237 intStatus
= U_ZERO_ERROR
;
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
);
245 processSequence(clone
, sequence
);
250 errln("Couldn't instantiate a collator!");
261 DataDrivenCollatorTest::processSequence(Collator
* col
, const UnicodeString
&sequence
) {
262 Collator::EComparisonResult relation
= Collator::EQUAL
;
264 SeqElement
*source
= NULL
;
265 SeqElement
*target
= NULL
;
268 sequences
.removeAllElements();
270 target
= new SeqElement();
272 setTestSequence(sequence
, *target
);
273 sequences
.addElement(target
, status
);
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
;
284 doTest(col
, source
->source
, target
->source
, relation
);
286 sequences
.addElement(target
, status
);
291 #endif /* #if !UCONFIG_NO_COLLATION */