// Copyright (C) 2016 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html /******************************************************************** * COPYRIGHT: * Copyright (c) 1997-2009, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ #include "unicode/utypes.h" #if !UCONFIG_NO_COLLATION #include "unicode/coll.h" #include "unicode/tblcoll.h" #include "unicode/unistr.h" #include "unicode/sortkey.h" #include "mnkytst.h" #include "sfwdchit.h" #include #include #include #ifndef MIN #define MIN(x,y) ((x) < (y) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) ((x) > (y) ? (x) : (y)) #endif CollationMonkeyTest::CollationMonkeyTest() : source("-abcdefghijklmnopqrstuvwxyz#&^$@", ""), myCollator(0) { UErrorCode status = U_ZERO_ERROR; myCollator = Collator::createInstance("en_US", status); } CollationMonkeyTest::~CollationMonkeyTest() { delete myCollator; } void CollationMonkeyTest::report(UnicodeString& s, UnicodeString& t, int32_t result, int32_t revResult) { if (revResult != -result) { UnicodeString msg; msg += s; msg += " and "; msg += t; msg += " round trip comparison failed"; msg += (UnicodeString) " (result " + result + ", reverse Result " + revResult + ")"; errln(msg); } } int32_t CollationMonkeyTest::checkValue(int32_t value) { if (value < 0) { return -value; } return value; } void CollationMonkeyTest::TestCollationKey(/* char* par */) { if(source.length() == 0) { errln(UNICODE_STRING("CollationMonkeyTest::TestCollationKey(): source is empty - ICU_DATA not set or data missing?", 92)); return; } srand( (unsigned)time( NULL ) ); int32_t s = checkValue(rand() % source.length()); int32_t t = checkValue(rand() % source.length()); int32_t slen = checkValue((rand() - source.length()) % source.length()); int32_t tlen = checkValue((rand() - source.length()) % source.length()); UnicodeString subs, subt; source.extract(MIN(s, slen), MAX(s, slen), subs); source.extract(MIN(t, tlen), MAX(t, tlen), subt); CollationKey collationKey1, collationKey2; UErrorCode status1 = U_ZERO_ERROR, status2= U_ZERO_ERROR; myCollator->setStrength(Collator::TERTIARY); myCollator->getCollationKey(subs, collationKey1, status1); myCollator->getCollationKey(subt, collationKey2, status2); int32_t result = collationKey1.compareTo(collationKey2); // Tertiary int32_t revResult = collationKey2.compareTo(collationKey1); // Tertiary report( subs, subt, result, revResult); myCollator->setStrength(Collator::SECONDARY); myCollator->getCollationKey(subs, collationKey1, status1); myCollator->getCollationKey(subt, collationKey2, status2); result = collationKey1.compareTo(collationKey2); // Secondary revResult = collationKey2.compareTo(collationKey1); // Secondary report( subs, subt, result, revResult); myCollator->setStrength(Collator::PRIMARY); myCollator->getCollationKey(subs, collationKey1, status1); myCollator->getCollationKey(subt, collationKey2, status2); result = collationKey1.compareTo(collationKey2); // Primary revResult = collationKey2.compareTo(collationKey1); // Primary report(subs, subt, result, revResult); UnicodeString msg; UnicodeString addOne(subs); addOne += (UChar32)0xE000; myCollator->getCollationKey(subs, collationKey1, status1); myCollator->getCollationKey(addOne, collationKey2, status2); result = collationKey1.compareTo(collationKey2); if (result != -1) { msg += "CollationKey("; msg += subs; msg += ") .LT. CollationKey("; msg += addOne; msg += ") Failed."; errln(msg); } msg.remove(); result = collationKey2.compareTo(collationKey1); if (result != 1) { msg += "CollationKey("; msg += addOne; msg += ") .GT. CollationKey("; msg += subs; msg += ") Failed."; errln(msg); } } void CollationMonkeyTest::TestCompare(/* char* par */) { if(source.length() == 0) { errln(UNICODE_STRING("CollationMonkeyTest::TestCompare(): source is empty - ICU_DATA not set or data missing?", 87)); return; } /* Seed the random-number generator with current time so that * the numbers will be different every time we run. */ srand( (unsigned)time( NULL ) ); int32_t s = checkValue(rand() % source.length()); int32_t t = checkValue(rand() % source.length()); int32_t slen = checkValue((rand() - source.length()) % source.length()); int32_t tlen = checkValue((rand() - source.length()) % source.length()); UnicodeString subs, subt; source.extract(MIN(s, slen), MAX(s, slen), subs); source.extract(MIN(t, tlen), MAX(t, tlen), subt); myCollator->setStrength(Collator::TERTIARY); int32_t result = myCollator->compare(subs, subt); // Tertiary int32_t revResult = myCollator->compare(subt, subs); // Tertiary report(subs, subt, result, revResult); myCollator->setStrength(Collator::SECONDARY); result = myCollator->compare(subs, subt); // Secondary revResult = myCollator->compare(subt, subs); // Secondary report(subs, subt, result, revResult); myCollator->setStrength(Collator::PRIMARY); result = myCollator->compare(subs, subt); // Primary revResult = myCollator->compare(subt, subs); // Primary report(subs, subt, result, revResult); UnicodeString msg; UnicodeString addOne(subs); addOne += (UChar32)0xE000; result = myCollator->compare(subs, addOne); if (result != -1) { msg += "Test : "; msg += subs; msg += " .LT. "; msg += addOne; msg += " Failed."; errln(msg); } msg.remove(); result = myCollator->compare(addOne, subs); if (result != 1) { msg += "Test : "; msg += addOne; msg += " .GT. "; msg += subs; msg += " Failed."; errln(msg); } } void CollationMonkeyTest::TestRules(/* char* par */){ UChar testSourceCases[][10] = { {0x0061, 0x0062, 0x007a, 0}, {0x0061, 0x0062, 0x007a, 0}, }; UChar testTargetCases[][10] = { {0x0061, 0x0062, 0x00e4, 0}, {0x0061, 0x0062, 0x0061, 0x0308, 0}, }; int i=0; logln("Demo Test 1 : Create a new table collation with rules \"& z < 0x00e4\""); UErrorCode status = U_ZERO_ERROR; Collator *col = Collator::createInstance("en_US", status); const UnicodeString baseRules = ((RuleBasedCollator*)col)->getRules(); UnicodeString newRules(" & z < "); newRules.append((UChar)0x00e4); newRules.insert(0, baseRules); RuleBasedCollator *myCollation = new RuleBasedCollator(newRules, status); if (U_FAILURE(status)) { errln( "Demo Test 1 Table Collation object creation failed."); return; } for(i=0; i<2; i++){ doTest(myCollation, testSourceCases[i], testTargetCases[i], Collator::LESS); } delete myCollation; logln("Demo Test 2 : Create a new table collation with rules \"& z < a 0x0308\""); newRules.remove(); newRules.append(" & z < a"); newRules.append((UChar)0x0308); newRules.insert(0, baseRules); myCollation = new RuleBasedCollator(newRules, status); if (U_FAILURE(status)) { errln( "Demo Test 1 Table Collation object creation failed."); return; } for(i=0; i<2; i++){ doTest(myCollation, testSourceCases[i], testTargetCases[i], Collator::LESS); } delete myCollation; delete col; } void CollationMonkeyTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) { if (exec) logln("TestSuite CollationMonkeyTest: "); if(myCollator) { switch (index) { case 0: name = "TestCompare"; if (exec) TestCompare(/* par */); break; case 1: name = "TestCollationKey"; if (exec) TestCollationKey(/* par */); break; case 2: name = "TestRules"; if (exec) TestRules(/* par */); break; default: name = ""; break; } } else { dataerrln("Class collator not instantiated"); name = ""; } } #endif /* #if !UCONFIG_NO_COLLATION */