| /******************************************************************** |
| * COPYRIGHT: |
| * Copyright (c) 1997-2001, 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" |
| #include "unicode/uchar.h" |
| |
| #include "cstring.h" |
| #include "ucol_tok.h" |
| |
| #include "tscoll.h" |
| |
| #include "dadrcoll.h" |
| |
| DataDrivenCollatorTest::DataDrivenCollatorTest() |
| : seq(StringCharacterIterator("")) |
| { |
| UErrorCode status = U_ZERO_ERROR; |
| TestLog testLog; |
| |
| driver = TestDataModule::getTestDataModule("DataDrivenCollationTest", testLog, status); |
| } |
| |
| DataDrivenCollatorTest::~DataDrivenCollatorTest() |
| { |
| delete driver; |
| } |
| |
| void DataDrivenCollatorTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par */) |
| { |
| if(driver != NULL) { |
| if (exec) |
| { |
| logln("TestSuite Collator: "); |
| } |
| UErrorCode status = U_ZERO_ERROR; |
| 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, status); |
| } |
| delete testData; |
| } else { |
| name = ""; |
| } |
| } else { |
| errln("collate/DataDrivenTest data not initialized!"); |
| name = ""; |
| } |
| |
| |
| } |
| |
| UBool |
| DataDrivenCollatorTest::setTestSequence(const UnicodeString &setSequence, UnicodeString &source, Collator::EComparisonResult &relation, UErrorCode &status) { |
| seq.setText(setSequence); |
| return getNextInSequence(source, relation, status); |
| } |
| |
| // Parses the sequence to be tested |
| UBool |
| DataDrivenCollatorTest::getNextInSequence(UnicodeString &source, Collator::EComparisonResult &relation, UErrorCode &status) { |
| source.truncate(0); |
| // TODO: add quoting support - will need it pretty soon! |
| 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 /* < */: |
| relation = Collator::LESS; |
| currChar = CharacterIterator::DONE; |
| break; |
| case 0x003D /* = */: |
| relation = Collator::EQUAL; |
| currChar = CharacterIterator::DONE; |
| break; |
| case 0x003E /* > */: |
| 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: |
| 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 { |
| 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, UErrorCode &status) { |
| 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, UErrorCode &status) { |
| Collator *col = NULL; |
| /* |
| UnicodeString testInit[256]; |
| const char **testNames = new const char*[256]; |
| int32_t settingsSetSize = 0; |
| const UChar *arguments = NULL; |
| int32_t argLen = 0; |
| int32_t i = 0; |
| while(settingsSetSize = driver->getNextSettingsSet(testNames, testInit, 256, status)) { |
| argLen = 0; |
| for(i = 0; i < settingsSetSize; i++) { |
| if(strcmp(testNames[i], "Locale") == 0) { // Make the locale dependent collator |
| if(col == NULL) { |
| char localeName[256]; |
| testInit[i].extract(0, testInit[i].length(), localeName, ""); |
| col = Collator::createInstance(localeName, status); |
| if(U_SUCCESS(status)) { |
| logln("Testing collator for locale "+testInit[i]); |
| } else { |
| errln("Unable to instantiate collator for locale "+testInit[i]); |
| return; |
| } |
| } else { |
| errln("Collator defined more than once!"); |
| return; |
| } |
| } else if(strcmp(testNames[i], "Rules") == 0) { |
| if(col == NULL) { |
| col = new RuleBasedCollator(testInit[i], status); |
| if(U_SUCCESS(status)) { |
| logln("Testing collator for rules "+UnicodeString(testInit[i])); |
| } else { |
| errln("Unable to instantiate collator for rules "+UnicodeString(testInit[i])); |
| return; |
| } |
| } else { |
| errln("Collator defined more than once!"); |
| return; |
| } |
| } else if(strcmp(testNames[i], "Attributes") == 0) { |
| logln("Arguments: "+testInit[i]); |
| argLen = testInit[i].length(); |
| arguments = testInit[i].getBuffer(); |
| } else { |
| errln("I don't understand the setting "+UnicodeString(testNames[i])); |
| } |
| } |
| if(col != NULL) { |
| if(argLen > 0) { |
| processArguments(col, arguments, argLen, status); |
| if(U_SUCCESS(status)) { |
| UnicodeString sequence[1]; |
| while(driver->getNextTestCase(sequence, 1, status)) { |
| processSequence(col, *sequence, status); |
| } |
| } else { |
| errln("Couldn't process arguments"); |
| } |
| } |
| } else { |
| errln("Couldn't instantiate a collator!"); |
| } |
| delete col; |
| } |
| delete testNames; |
| */ |
| 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); |
| UCollator *ucol = ucol_openRules(testSetting.getBuffer(), testSetting.length(), UCOL_DEFAULT, UCOL_DEFAULT, NULL, &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!"); |
| } |
| } |
| if(col != NULL) { |
| // get attributes |
| testSetting = settings->getString("Arguments", intStatus); |
| if(U_SUCCESS(intStatus)) { |
| logln("Arguments: "+testSetting); |
| argLen = testSetting.length(); |
| arguments = testSetting.getBuffer(); |
| processArguments(col, arguments, argLen, intStatus); |
| if(U_FAILURE(intStatus)) { |
| 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, status); |
| } |
| } |
| } else { |
| errln("Couldn't instantiate a collator!"); |
| } |
| delete col; |
| col = NULL; |
| } |
| } |
| |
| void |
| DataDrivenCollatorTest::processSequence(Collator* col, const UnicodeString &sequence, UErrorCode &status) { |
| UnicodeString source; |
| UnicodeString target; |
| UnicodeString temp; |
| Collator::EComparisonResult relation = Collator::EQUAL; |
| Collator::EComparisonResult nextRelation = Collator::EQUAL; |
| UBool hasNext; |
| |
| setTestSequence(sequence, source, relation, status); |
| |
| // TODO: have a smarter tester that remembers the sequence and ensures that |
| // the complete sequence is in order. That is why I have made a constraint |
| // in the sequence format. |
| do { |
| hasNext = getNextInSequence(target, nextRelation, status); |
| doTest(col, source, target, relation); |
| source = target; |
| relation = nextRelation; |
| } while(hasNext); |
| } |
| |