b02865cecf
X-SVN-Rev: 23784
291 lines
8.2 KiB
C++
291 lines
8.2 KiB
C++
/********************************************************************
|
|
* COPYRIGHT:
|
|
* Copyright (c) 1997-2008, International Business Machines Corporation and
|
|
* others. All Rights Reserved.
|
|
********************************************************************/
|
|
|
|
/**
|
|
* IntlTestCollator is the medium level test class for everything in the directory "collate".
|
|
*/
|
|
|
|
/***********************************************************************
|
|
* Modification history
|
|
* Date Name Description
|
|
* 02/14/2001 synwee Compare with cintltst and commented away tests
|
|
* that are not run.
|
|
***********************************************************************/
|
|
|
|
#include "unicode/utypes.h"
|
|
|
|
#if !UCONFIG_NO_COLLATION
|
|
|
|
#include "unicode/uchar.h"
|
|
#include "unicode/tstdtmod.h"
|
|
#include "cstring.h"
|
|
#include "ucol_tok.h"
|
|
#include "tscoll.h"
|
|
#include "dadrcoll.h"
|
|
|
|
U_CDECL_BEGIN
|
|
static void U_CALLCONV deleteSeqElement(void *elem) {
|
|
delete((SeqElement *)elem);
|
|
}
|
|
U_CDECL_END
|
|
|
|
DataDrivenCollatorTest::DataDrivenCollatorTest()
|
|
: seq(StringCharacterIterator("")),
|
|
status(U_ZERO_ERROR),
|
|
sequences(status)
|
|
{
|
|
driver = TestDataModule::getTestDataModule("DataDrivenCollationTest", *this, status);
|
|
sequences.setDeleter(deleteSeqElement);
|
|
UCA = (RuleBasedCollator*)Collator::createInstance("root", status);
|
|
}
|
|
|
|
DataDrivenCollatorTest::~DataDrivenCollatorTest()
|
|
{
|
|
delete driver;
|
|
delete UCA;
|
|
}
|
|
|
|
void DataDrivenCollatorTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par */)
|
|
{
|
|
if(driver != NULL) {
|
|
if (exec)
|
|
{
|
|
logln("TestSuite Collator: ");
|
|
}
|
|
const DataMap *info = NULL;
|
|
TestData *testData = driver->createTestData(index, status);
|
|
if(U_SUCCESS(status)) {
|
|
name = testData->getName();
|
|
if(testData->getInfo(info, status)) {
|
|
log(info->getString("Description", status));
|
|
}
|
|
if(exec) {
|
|
log(name);
|
|
logln("---");
|
|
logln("");
|
|
processTest(testData);
|
|
}
|
|
delete testData;
|
|
} else {
|
|
name = "";
|
|
}
|
|
} else {
|
|
dataerrln("[DATA] collate/DataDrivenTest data not initialized!");
|
|
name = "";
|
|
}
|
|
|
|
|
|
}
|
|
|
|
UBool
|
|
DataDrivenCollatorTest::setTestSequence(const UnicodeString &setSequence, SeqElement &el) {
|
|
seq.setText(setSequence);
|
|
return getNextInSequence(el);
|
|
}
|
|
|
|
// Parses the sequence to be tested
|
|
UBool
|
|
DataDrivenCollatorTest::getNextInSequence(SeqElement &el) {
|
|
el.source.truncate(0);
|
|
UBool quoted = FALSE;
|
|
UBool quotedsingle = FALSE;
|
|
UChar32 currChar = 0;
|
|
|
|
while(currChar != CharacterIterator::DONE) {
|
|
currChar= seq.next32PostInc();
|
|
if(!quoted) {
|
|
if(u_isWhitespace(currChar)) {
|
|
continue;
|
|
}
|
|
switch(currChar) {
|
|
case CharacterIterator::DONE:
|
|
break;
|
|
case 0x003C /* < */:
|
|
el.relation = Collator::LESS;
|
|
currChar = CharacterIterator::DONE;
|
|
break;
|
|
case 0x003D /* = */:
|
|
el.relation = Collator::EQUAL;
|
|
currChar = CharacterIterator::DONE;
|
|
break;
|
|
case 0x003E /* > */:
|
|
el.relation = Collator::GREATER;
|
|
currChar = CharacterIterator::DONE;
|
|
break;
|
|
case 0x0027 /* ' */: /* very basic quoting */
|
|
quoted = TRUE;
|
|
quotedsingle = FALSE;
|
|
break;
|
|
case 0x005c /* \ */: /* single quote */
|
|
quoted = TRUE;
|
|
quotedsingle = TRUE;
|
|
break;
|
|
default:
|
|
el.source.append(currChar);
|
|
}
|
|
} else {
|
|
if(currChar == CharacterIterator::DONE) {
|
|
status = U_ILLEGAL_ARGUMENT_ERROR;
|
|
errln("Quote in sequence not closed!");
|
|
return FALSE;
|
|
} else if(currChar == 0x0027) {
|
|
quoted = FALSE;
|
|
} else {
|
|
el.source.append(currChar);
|
|
}
|
|
if(quotedsingle) {
|
|
quoted = FALSE;
|
|
}
|
|
}
|
|
}
|
|
return seq.hasNext();
|
|
}
|
|
|
|
// Reads the options string and sets appropriate attributes in collator
|
|
void
|
|
DataDrivenCollatorTest::processArguments(Collator *col, const UChar *start, int32_t optLen) {
|
|
const UChar *end = start+optLen;
|
|
UColAttribute attrib;
|
|
UColAttributeValue value;
|
|
|
|
if(optLen == 0) {
|
|
return;
|
|
}
|
|
|
|
start = ucol_tok_getNextArgument(start, end, &attrib, &value, &status);
|
|
while(start != NULL) {
|
|
if(U_SUCCESS(status)) {
|
|
col->setAttribute(attrib, value, status);
|
|
}
|
|
start = ucol_tok_getNextArgument(start, end, &attrib, &value, &status);
|
|
}
|
|
}
|
|
|
|
void
|
|
DataDrivenCollatorTest::processTest(TestData *testData) {
|
|
Collator *col = NULL;
|
|
const UChar *arguments = NULL;
|
|
int32_t argLen = 0;
|
|
const DataMap *settings = NULL;
|
|
const DataMap *currentCase = NULL;
|
|
UErrorCode intStatus = U_ZERO_ERROR;
|
|
UnicodeString testSetting;
|
|
while(testData->nextSettings(settings, status)) {
|
|
intStatus = U_ZERO_ERROR;
|
|
// try to get a locale
|
|
testSetting = settings->getString("TestLocale", intStatus);
|
|
if(U_SUCCESS(intStatus)) {
|
|
char localeName[256];
|
|
testSetting.extract(0, testSetting.length(), localeName, "");
|
|
col = Collator::createInstance(localeName, status);
|
|
if(U_SUCCESS(status)) {
|
|
logln("Testing collator for locale "+testSetting);
|
|
} else {
|
|
errln("Unable to instantiate collator for locale "+testSetting);
|
|
return;
|
|
}
|
|
} else {
|
|
// if no locale, try from rules
|
|
intStatus = U_ZERO_ERROR;
|
|
testSetting = settings->getString("Rules", intStatus);
|
|
if(U_SUCCESS(intStatus)) {
|
|
col = new RuleBasedCollator(testSetting, status);
|
|
if(U_SUCCESS(status)) {
|
|
logln("Testing collator for rules "+testSetting);
|
|
} else {
|
|
errln("Unable to instantiate collator for rules "+testSetting);
|
|
return;
|
|
}
|
|
} else {
|
|
errln("No collator definition!");
|
|
}
|
|
}
|
|
|
|
int32_t cloneSize = 0;
|
|
uint8_t* cloneBuf = NULL;
|
|
RuleBasedCollator* clone = NULL;
|
|
if(col != NULL){
|
|
RuleBasedCollator* rbc = (RuleBasedCollator*)col;
|
|
cloneSize = rbc->cloneBinary(NULL, 0, intStatus);
|
|
intStatus = U_ZERO_ERROR;
|
|
cloneBuf = (uint8_t*) malloc(cloneSize);
|
|
cloneSize = rbc->cloneBinary(cloneBuf, cloneSize, intStatus);
|
|
clone = new RuleBasedCollator(cloneBuf, cloneSize, UCA, intStatus);
|
|
if(U_FAILURE(intStatus)){
|
|
errln("Could not clone the RuleBasedCollator. Error: %s", u_errorName(intStatus));
|
|
intStatus= U_ZERO_ERROR;
|
|
}
|
|
// get attributes
|
|
testSetting = settings->getString("Arguments", intStatus);
|
|
if(U_SUCCESS(intStatus)) {
|
|
logln("Arguments: "+testSetting);
|
|
argLen = testSetting.length();
|
|
arguments = testSetting.getBuffer();
|
|
processArguments(col, arguments, argLen);
|
|
if(clone != NULL){
|
|
processArguments(clone, arguments, argLen);
|
|
}
|
|
if(U_FAILURE(status)) {
|
|
errln("Couldn't process arguments");
|
|
break;
|
|
}
|
|
} else {
|
|
intStatus = U_ZERO_ERROR;
|
|
}
|
|
// Start the processing
|
|
while(testData->nextCase(currentCase, status)) {
|
|
UnicodeString sequence = currentCase->getString("sequence", status);
|
|
if(U_SUCCESS(status)) {
|
|
processSequence(col, sequence);
|
|
if(clone != NULL){
|
|
processSequence(clone, sequence);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
errln("Couldn't instantiate a collator!");
|
|
}
|
|
delete clone;
|
|
free(cloneBuf);
|
|
delete col;
|
|
col = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
DataDrivenCollatorTest::processSequence(Collator* col, const UnicodeString &sequence) {
|
|
Collator::EComparisonResult relation = Collator::EQUAL;
|
|
UBool hasNext;
|
|
SeqElement *source = NULL;
|
|
SeqElement *target = NULL;
|
|
int32_t j = 0;
|
|
|
|
sequences.removeAllElements();
|
|
|
|
target = new SeqElement();
|
|
|
|
setTestSequence(sequence, *target);
|
|
sequences.addElement(target, status);
|
|
|
|
do {
|
|
relation = Collator::EQUAL;
|
|
target = new SeqElement();
|
|
hasNext = getNextInSequence(*target);
|
|
for(j = sequences.size(); j > 0; j--) {
|
|
source = (SeqElement *)sequences.elementAt(j-1);
|
|
if(relation == Collator::EQUAL && source->relation != Collator::EQUAL) {
|
|
relation = source->relation;
|
|
}
|
|
doTest(col, source->source, target->source, relation);
|
|
}
|
|
sequences.addElement(target, status);
|
|
source = target;
|
|
} while(hasNext);
|
|
}
|
|
|
|
#endif /* #if !UCONFIG_NO_COLLATION */
|