+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
/********************************************************************
- * COPYRIGHT:
- * Copyright (c) 1997-2003, International Business Machines Corporation and
+ * COPYRIGHT:
+ * Copyright (c) 1997-2016, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
#if !UCONFIG_NO_COLLATION
#include "unicode/coll.h"
+#include "unicode/localpointer.h"
#include "unicode/tblcoll.h"
#include "unicode/unistr.h"
#include "unicode/sortkey.h"
#include "regcoll.h"
#include "sfwdchit.h"
-
-#define ARRAY_LENGTH(array) ((int32_t)(sizeof array / sizeof array[0]))
+#include "testutil.h"
+#include "cmemory.h"
CollationRegressionTest::CollationRegressionTest()
{
if(U_FAILURE(status)) {
delete en_us;
en_us = 0;
- errln("Collator creation failed with %s", u_errorName(status));
+ errcheckln(status, "Collator creation failed with %s", u_errorName(status));
return;
}
}
//
void CollationRegressionTest::Test4051866(/* char* par */)
{
-/*
- RuleBasedCollator c1 = new RuleBasedCollator("< o "
- +"& oe ,o\u3080"
- +"& oe ,\u1530 ,O"
- +"& OE ,O\u3080"
- +"& OE ,\u1520"
- +"< p ,P");
-*/
-
UnicodeString rules;
UErrorCode status = U_ZERO_ERROR;
- rules += "< o ";
+ rules += "&n < o ";
rules += "& oe ,o";
rules += (UChar)0x3080;
rules += "& oe ,";
rules += "< p ,P";
// Build a collator containing expanding characters
- RuleBasedCollator *c1 = new RuleBasedCollator(rules, status);
+ LocalPointer<RuleBasedCollator> c1(new RuleBasedCollator(rules, status), status);
+ if (U_FAILURE(status)) {
+ errln("RuleBasedCollator(rule string) failed - %s", u_errorName(status));
+ return;
+ }
// Build another using the rules from the first
- RuleBasedCollator *c2 = new RuleBasedCollator(c1->getRules(), status);
+ LocalPointer<RuleBasedCollator> c2(new RuleBasedCollator(c1->getRules(), status), status);
+ if (U_FAILURE(status)) {
+ errln("RuleBasedCollator(rule string from other RBC) failed - %s", u_errorName(status));
+ return;
+ }
// Make sure they're the same
if (!(c1->getRules() == c2->getRules()))
{
errln("Rules are not equal");
}
-
- delete c2;
- delete c1;
}
// @bug 4053636
"A\u0001", ">", "~\u0002", // Ensure A and ~ are not compared bitwise
"\u00C0", "=", "A\u0300" // Decomp should make these equal
};
-
+
String[] nodecomp = {
"\u00C0", ">", "A\u0300" // A-grave vs. A combining-grave
};
{0x00c0, 0}, {0x3d, 0}, {0x41, 0x0300, 0}
};
-
+
UErrorCode status = U_ZERO_ERROR;
RuleBasedCollator *c = (RuleBasedCollator *) en_us->clone();
c->setStrength(Collator::IDENTICAL);
c->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
- compareArray(*c, decomp, ARRAY_LENGTH(decomp));
+ compareArray(*c, decomp, UPRV_LENGTHOF(decomp));
delete c;
}
{0xFB4F, 0}, {0x3d, 0}, {0x05D0, 0x05DC} // Alef-Lamed vs. Alef, Lamed
};
- compareArray(*c, tests, ARRAY_LENGTH(tests));
+ compareArray(*c, tests, UPRV_LENGTHOF(tests));
delete c;
}
// @bug 4058613
//
-// Collator::createInstance() causes an ArrayIndexOutofBoundsException for Korean
+// Collator::createInstance() causes an ArrayIndexOutofBoundsException for Korean
//
void CollationRegressionTest::Test4058613(/* char* par */)
{
// Creating a default collator doesn't work when Korean is the default
// locale
-
+
Locale oldDefault = Locale::getDefault();
UErrorCode status = U_ZERO_ERROR;
-
+
Locale::setDefault(Locale::getKorean(), status);
if (U_FAILURE(status))
}
Collator *c = NULL;
-
+
c = Collator::createInstance("en_US", status);
if (c == NULL || U_FAILURE(status))
delete c;
return;
}
-
+
// Since the fix to this bug was to turn off decomposition for Korean collators,
// ensure that's what we got
if (c->getAttribute(UCOL_NORMALIZATION_MODE, status) != UCOL_OFF)
UErrorCode status = U_ZERO_ERROR;
RuleBasedCollator *c = NULL;
- UnicodeString rules = "< a < b , c/a < d < z";
-
+ UnicodeString rules = "&9 < a < b , c/a < d < z";
+
c = new RuleBasedCollator(rules, status);
if (c == NULL || U_FAILURE(status))
UErrorCode status = U_ZERO_ERROR;
UnicodeString rules;
- rules += "< g, G < h, H < i, I < j, J";
+ rules += "&f < g, G < h, H < i, I < j, J";
rules += " & H < ";
rules += (UChar)0x0131;
rules += ", ";
rules += ", i, I";
RuleBasedCollator *c = NULL;
-
+
c = new RuleBasedCollator(rules, status);
if (c == NULL || U_FAILURE(status))
};
c->setStrength(Collator::TERTIARY);
- compareArray(*c, tertiary, ARRAY_LENGTH(tertiary));
+ compareArray(*c, tertiary, UPRV_LENGTHOF(tertiary));
/*
String[] secondary = {
};
c->setStrength(Collator::PRIMARY);
- compareArray(*c, secondary, ARRAY_LENGTH(secondary));
+ compareArray(*c, secondary, UPRV_LENGTHOF(secondary));
delete c;
}
UErrorCode status = U_ZERO_ERROR;
RuleBasedCollator *c = NULL;
-
- c = (RuleBasedCollator *) Collator::createInstance(Locale::getFrance(), status);
+
+ c = (RuleBasedCollator *) Collator::createInstance(Locale::getCanadaFrench(), status);
if (c == NULL || U_FAILURE(status))
{
- errln("Failed to create collator for Locale::getFrance()");
+ errln("Failed to create collator for Locale::getCanadaFrench()");
delete c;
return;
}
{0x70, 0x00EA, 0x63, 0x68, 0x65, 0}, {0x3c, 0}, {0x70, 0x00E9, 0x63, 0x68, 0x00E9, 0}
};
- compareArray(*c, tests, ARRAY_LENGTH(tests));
+ compareArray(*c, tests, UPRV_LENGTHOF(tests));
delete c;
}
{
UErrorCode status = U_ZERO_ERROR;
RuleBasedCollator *c = NULL;
-
- c = (RuleBasedCollator *)Collator::createInstance(Locale::getFrance(), status);
+
+ c = (RuleBasedCollator *)Collator::createInstance(Locale::getCanadaFrench(), status);
if (c == NULL || U_FAILURE(status))
{
- errln("Failure creating collator for Locale::getFrance()");
+ errln("Failure creating collator for Locale::getCanadaFrench()");
delete c;
return;
}
{0x00E0, 0}, {0x3e, 0}, {0x01FA, 0}
};
- compareArray(*c, tests, ARRAY_LENGTH(tests));
+ compareArray(*c, tests, UPRV_LENGTHOF(tests));
delete c;
}
void CollationRegressionTest::Test4078588(/* char *par */)
{
UErrorCode status = U_ZERO_ERROR;
- RuleBasedCollator *rbc = new RuleBasedCollator((UnicodeString)"< a < bb", status);
+ RuleBasedCollator *rbc = new RuleBasedCollator("&9 < a < bb", status);
if (rbc == NULL || U_FAILURE(status))
{
UErrorCode status = U_ZERO_ERROR;
RuleBasedCollator *c = (RuleBasedCollator *) en_us->clone();
c->setStrength(Collator::TERTIARY);
-
+
// Now that the default collators are set to NO_DECOMPOSITION
// (as a result of fixing bug 4114077), we must set it explicitly
// when we're testing reordering behavior. -- lwerner, 5/5/98
UErrorCode status = U_ZERO_ERROR;
Locale da_DK("da", "DK");
RuleBasedCollator *c = NULL;
-
+
c = (RuleBasedCollator *) Collator::createInstance(da_DK, status);
if (c == NULL || U_FAILURE(status))
static const UChar tests[][CollationRegressionTest::MAX_TOKEN_LEN] =
{
{0x7a, 0}, {0x3c, 0}, {0x00E6, 0}, // z < ae
- {0x61, 0x0308, 0}, {0x3c, 0}, {0x61, 0x030A, 0}, // a-unlaut < a-ring
+ {0x61, 0x0308, 0}, {0x3c, 0}, {0x61, 0x030A, 0}, // a-umlaut < a-ring
{0x59, 0}, {0x3c, 0}, {0x75, 0x0308, 0}, // Y < u-umlaut
};
- compareArray(*c, tests, ARRAY_LENGTH(tests));
+ compareArray(*c, tests, UPRV_LENGTHOF(tests));
delete c;
}
{0x31, 0x32, 0x33, 0}, {0x3d, 0}, {0x31, 0x32, 0x33, 0x0001, 0} // 1 2 3 = 1 2 3 ctrl-A
};
- compareArray(*c, tests, ARRAY_LENGTH(tests));
+ compareArray(*c, tests, UPRV_LENGTHOF(tests));
delete c;
}
UErrorCode status = U_ZERO_ERROR;
Locale el("el", "");
Collator *c = NULL;
-
+
c = Collator::createInstance(el, status);
if (c == NULL || U_FAILURE(status))
{0x00B5, 0}, {0x3d, 0}, {0x03BC, 0}
};
- compareArray(*c, tests, ARRAY_LENGTH(tests));
+ compareArray(*c, tests, UPRV_LENGTHOF(tests));
delete c;
}
{0x03D4, 0}, {0x3d, 0}, {0x03AB, 0}
};
- compareArray(*c, tests, ARRAY_LENGTH(tests));
+ compareArray(*c, tests, UPRV_LENGTHOF(tests));
delete c;
}
{
UErrorCode status = U_ZERO_ERROR;
RuleBasedCollator *c = NULL;
- UnicodeString rules = "< a < b";
+ UnicodeString rules = "&9 < a < b";
UnicodeString nothing = "";
-
+
c = new RuleBasedCollator(rules, status);
if (c == NULL || U_FAILURE(status))
{0x66, 0x69, 0x6c, 0x65, 0}, {0x3c, 0}, {0x66, 0x69, 0x6c, 0x65, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0}
};
- compareArray(*c, tests, ARRAY_LENGTH(tests));
+ compareArray(*c, tests, UPRV_LENGTHOF(tests));
delete c;
}
};
c->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
- compareArray(*c, test1, ARRAY_LENGTH(test1));
+ compareArray(*c, test1, UPRV_LENGTHOF(test1));
// From UTR #15:
// *In earlier versions of Unicode, jamo characters like ksf
- // had compatibility mappings to kf + sf. These mappings were
+ // had compatibility mappings to kf + sf. These mappings were
// removed in Unicode 2.1.9 to ensure that Hangul syllables are maintained.)
// That is, the following test is obsolete as of 2.1.9
//obsolete- };
//obsolete-
//obsolete- c->setDecomposition(Normalizer::DECOMP_COMPAT);
-//obsolete- compareArray(*c, test2, ARRAY_LENGTH(test2));
+//obsolete- compareArray(*c, test2, UPRV_LENGTHOF(test2));
delete c;
}
{
UErrorCode status = U_ZERO_ERROR;
Collator *coll = NULL;
-
+
coll = Collator::createInstance(Locale::getJapan(), status);
-
+
if (coll == NULL || U_FAILURE(status))
{
errln("Failed to create collator for Locale::JAPAN");
static const UChar test[] = {0x41, 0x0308, 0x62, 0x63, 0};
CollationKey key;
-
+
coll->getCollationKey(test, key, status);
if (key.isBogus() || U_FAILURE(status))
UErrorCode status = U_ZERO_ERROR;
Collator *c = NULL;
-
- c = Collator::createInstance(Locale::getFrance(), status);
+
+ c = Collator::createInstance(Locale::getCanadaFrench(), status);
c->setStrength(Collator::TERTIARY);
-
+
if (c == NULL || U_FAILURE(status))
{
- errln("Failed to create a collator for Locale::getFrance()");
+ errln("Failed to create a collator for Locale::getCanadaFrench()");
delete c;
return;
}
{0x65, 0x0300, 0x0301, 0}, {0x3c, 0}, {0x65, 0x0301, 0x0300, 0}
};
- compareArray(*c, test1, ARRAY_LENGTH(test1));
+ compareArray(*c, test1, UPRV_LENGTHOF(test1));
delete c;
}
{0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0}, {0x3c, 0}, {0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0}
};
- compareArray(*en_us, test1, ARRAY_LENGTH(test1));
+ compareArray(*en_us, test1, UPRV_LENGTHOF(test1));
}
// @bug 4114077
//
-// Collation with decomposition off doesn't work for Europe
+// Collation with decomposition off doesn't work for Europe
//
void CollationRegressionTest::Test4114077(/* char* par */)
{
// Ensure that we get the same results with decomposition off
// as we do with it on....
-
+
UErrorCode status = U_ZERO_ERROR;
RuleBasedCollator *c = (RuleBasedCollator *) en_us->clone();
c->setStrength(Collator::TERTIARY);
-
+
static const UChar test1[][CollationRegressionTest::MAX_TOKEN_LEN] =
{
{0x00C0, 0}, {0x3d, 0}, {0x41, 0x0300, 0}, // Should be equivalent
};
c->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status);
- compareArray(*c, test1, ARRAY_LENGTH(test1));
+ compareArray(*c, test1, UPRV_LENGTHOF(test1));
static const UChar test2[][CollationRegressionTest::MAX_TOKEN_LEN] =
{
};
c->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
- compareArray(*c, test2, ARRAY_LENGTH(test2));
+ compareArray(*c, test2, UPRV_LENGTHOF(test2));
delete c;
}
// @bug 4141640
//
-// Support for Swedish gone in 1.1.6 (Can't create Swedish collator)
+// Support for Swedish gone in 1.1.6 (Can't create Swedish collator)
//
void CollationRegressionTest::Test4141640(/* char* par */)
{
UErrorCode status = U_ZERO_ERROR;
int32_t i, localeCount;
const Locale *locales = Locale::getAvailableLocales(localeCount);
-
+
for (i = 0; i < localeCount; i += 1)
{
Collator *c = NULL;
// @bug 4139572
//
-// getCollationKey throws exception for spanish text
+// getCollationKey throws exception for spanish text
// Cannot reproduce this bug on 1.2, however it DOES fail on 1.1.6
//
void CollationRegressionTest::Test4139572(/* char* par */)
UErrorCode status = U_ZERO_ERROR;
Locale l("es", "es");
Collator *col = NULL;
-
+
col = Collator::createInstance(l, status);
if (col == NULL || U_FAILURE(status))
}
/* HSYS : RuleBasedCollator::compare() performance enhancements
compare() does not create CollationElementIterator() anymore.*/
-
+
class My4146160Collator : public RuleBasedCollator
{
public:
CollationElementIterator *createCollationElementIterator(const UnicodeString &text) const;
CollationElementIterator *createCollationElementIterator(const CharacterIterator &text) const;
-
+
static int32_t count;
};
My4146160Collator::count = 0;
My4146160Collator *mc = NULL;
-
+
mc = new My4146160Collator(*en_us, status);
if (mc == NULL || U_FAILURE(status))
delete mc;
#endif
}
+
+void CollationRegressionTest::Test4179216() {
+ // you can position a CollationElementIterator in the middle of
+ // a contracting character sequence, yielding a bogus collation
+ // element
+ IcuTestErrorCode errorCode(*this, "Test4179216");
+ RuleBasedCollator coll(en_us->getRules() + " & C < ch , cH , Ch , CH < cat < crunchy", errorCode);
+ UnicodeString testText = "church church catcatcher runcrunchynchy";
+ CollationElementIterator *iter = coll.createCollationElementIterator(testText);
+
+ // test that the "ch" combination works properly
+ iter->setOffset(4, errorCode);
+ int32_t elt4 = CollationElementIterator::primaryOrder(iter->next(errorCode));
+
+ iter->reset();
+ int32_t elt0 = CollationElementIterator::primaryOrder(iter->next(errorCode));
+
+ iter->setOffset(5, errorCode);
+ int32_t elt5 = CollationElementIterator::primaryOrder(iter->next(errorCode));
+
+ // Compares and prints only 16-bit primary weights.
+ if (elt4 != elt0 || elt5 != elt0) {
+ errln("The collation elements at positions 0 (0x%04x), "
+ "4 (0x%04x), and 5 (0x%04x) don't match.",
+ elt0, elt4, elt5);
+ }
+
+ // test that the "cat" combination works properly
+ iter->setOffset(14, errorCode);
+ int32_t elt14 = CollationElementIterator::primaryOrder(iter->next(errorCode));
+
+ iter->setOffset(15, errorCode);
+ int32_t elt15 = CollationElementIterator::primaryOrder(iter->next(errorCode));
+
+ iter->setOffset(16, errorCode);
+ int32_t elt16 = CollationElementIterator::primaryOrder(iter->next(errorCode));
+
+ iter->setOffset(17, errorCode);
+ int32_t elt17 = CollationElementIterator::primaryOrder(iter->next(errorCode));
+
+ iter->setOffset(18, errorCode);
+ int32_t elt18 = CollationElementIterator::primaryOrder(iter->next(errorCode));
+
+ iter->setOffset(19, errorCode);
+ int32_t elt19 = CollationElementIterator::primaryOrder(iter->next(errorCode));
+
+ // Compares and prints only 16-bit primary weights.
+ if (elt14 != elt15 || elt14 != elt16 || elt14 != elt17
+ || elt14 != elt18 || elt14 != elt19) {
+ errln("\"cat\" elements don't match: elt14 = 0x%04x, "
+ "elt15 = 0x%04x, elt16 = 0x%04x, elt17 = 0x%04x, "
+ "elt18 = 0x%04x, elt19 = 0x%04x",
+ elt14, elt15, elt16, elt17, elt18, elt19);
+ }
+
+ // now generate a complete list of the collation elements,
+ // first using next() and then using setOffset(), and
+ // make sure both interfaces return the same set of elements
+ iter->reset();
+
+ int32_t elt = iter->next(errorCode);
+ int32_t count = 0;
+ while (elt != CollationElementIterator::NULLORDER) {
+ ++count;
+ elt = iter->next(errorCode);
+ }
+
+ LocalArray<UnicodeString> nextElements(new UnicodeString[count]);
+ LocalArray<UnicodeString> setOffsetElements(new UnicodeString[count]);
+ int32_t lastPos = 0;
+
+ iter->reset();
+ elt = iter->next(errorCode);
+ count = 0;
+ while (elt != CollationElementIterator::NULLORDER) {
+ nextElements[count++] = testText.tempSubStringBetween(lastPos, iter->getOffset());
+ lastPos = iter->getOffset();
+ elt = iter->next(errorCode);
+ }
+ int32_t nextElementsLength = count;
+ count = 0;
+ for (int32_t i = 0; i < testText.length(); ) {
+ iter->setOffset(i, errorCode);
+ lastPos = iter->getOffset();
+ elt = iter->next(errorCode);
+ setOffsetElements[count++] = testText.tempSubStringBetween(lastPos, iter->getOffset());
+ i = iter->getOffset();
+ }
+ for (int32_t i = 0; i < nextElementsLength; i++) {
+ if (nextElements[i] == setOffsetElements[i]) {
+ logln(nextElements[i]);
+ } else {
+ errln(UnicodeString("Error: next() yielded ") + nextElements[i] +
+ ", but setOffset() yielded " + setOffsetElements[i]);
+ }
+ }
+ delete iter;
+}
+
+// Ticket 7189
+//
+// nextSortKeyPart incorrect for EO_S1 collation
+static int32_t calcKeyIncremental(UCollator *coll, const UChar* text, int32_t len, uint8_t *keyBuf, int32_t /*keyBufLen*/, UErrorCode& status) {
+ UCharIterator uiter;
+ uint32_t state[2] = { 0, 0 };
+ int32_t keyLen;
+ int32_t count = 8;
+
+ uiter_setString(&uiter, text, len);
+ keyLen = 0;
+ while (TRUE) {
+ int32_t keyPartLen = ucol_nextSortKeyPart(coll, &uiter, state, &keyBuf[keyLen], count, &status);
+ if (U_FAILURE(status)) {
+ return -1;
+ }
+ if (keyPartLen == 0) {
+ break;
+ }
+ keyLen += keyPartLen;
+ }
+ return keyLen;
+}
+
+void CollationRegressionTest::TestT7189() {
+ UErrorCode status = U_ZERO_ERROR;
+ UCollator *coll;
+ uint32_t i;
+
+ static const UChar text1[][CollationRegressionTest::MAX_TOKEN_LEN] = {
+ // "Achter De Hoven"
+ { 0x41, 0x63, 0x68, 0x74, 0x65, 0x72, 0x20, 0x44, 0x65, 0x20, 0x48, 0x6F, 0x76, 0x65, 0x6E, 0x00 },
+ // "ABC"
+ { 0x41, 0x42, 0x43, 0x00 },
+ // "HELLO world!"
+ { 0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x00 }
+ };
+
+ static const UChar text2[][CollationRegressionTest::MAX_TOKEN_LEN] = {
+ // "Achter de Hoven"
+ { 0x41, 0x63, 0x68, 0x74, 0x65, 0x72, 0x20, 0x64, 0x65, 0x20, 0x48, 0x6F, 0x76, 0x65, 0x6E, 0x00 },
+ // "abc"
+ { 0x61, 0x62, 0x63, 0x00 },
+ // "hello world!"
+ { 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x00 }
+ };
+
+ // Open the collator
+ coll = ucol_openFromShortString("EO_S1", FALSE, NULL, &status);
+ if (U_FAILURE(status)) {
+ errln("Failed to create a collator for short string EO_S1");
+ return;
+ }
+
+ for (i = 0; i < UPRV_LENGTHOF(text1); i++) {
+ uint8_t key1[100], key2[100];
+ int32_t len1, len2;
+
+ len1 = calcKeyIncremental(coll, text1[i], -1, key1, sizeof(key1), status);
+ if (U_FAILURE(status)) {
+ errln(UnicodeString("Failed to get a partial collation key for ") + text1[i]);
+ break;
+ }
+ len2 = calcKeyIncremental(coll, text2[i], -1, key2, sizeof(key2), status);
+ if (U_FAILURE(status)) {
+ errln(UnicodeString("Failed to get a partial collation key for ") + text2[i]);
+ break;
+ }
+
+ if (len1 == len2 && uprv_memcmp(key1, key2, len1) == 0) {
+ errln(UnicodeString("Failed: Identical key\n") + " text1: " + text1[i] + "\n" + " text2: " + text2[i] + "\n" + " key : " + TestUtility::hex(key1, len1));
+ } else {
+ logln(UnicodeString("Keys produced -\n") + " text1: " + text1[i] + "\n" + " key1 : " + TestUtility::hex(key1, len1) + "\n" + " text2: " + text2[i] + "\n" + " key2 : "
+ + TestUtility::hex(key2, len2));
+ }
+ }
+ ucol_close(coll);
+}
+
+void CollationRegressionTest::TestCaseFirstCompression() {
+ RuleBasedCollator *col = (RuleBasedCollator *) en_us->clone();
+ UErrorCode status = U_ZERO_ERROR;
+
+ // default
+ caseFirstCompressionSub(col, "default");
+
+ // Upper first
+ col->setAttribute(UCOL_CASE_FIRST, UCOL_UPPER_FIRST, status);
+ if (U_FAILURE(status)) {
+ errln("Failed to set UCOL_UPPER_FIRST");
+ return;
+ }
+ caseFirstCompressionSub(col, "upper first");
+
+ // Lower first
+ col->setAttribute(UCOL_CASE_FIRST, UCOL_LOWER_FIRST, status);
+ if (U_FAILURE(status)) {
+ errln("Failed to set UCOL_LOWER_FIRST");
+ return;
+ }
+ caseFirstCompressionSub(col, "lower first");
+
+ delete col;
+}
+
+void CollationRegressionTest::caseFirstCompressionSub(Collator *col, UnicodeString opt) {
+ const int32_t maxLength = 50;
+
+ UChar str1[maxLength];
+ UChar str2[maxLength];
+
+ CollationKey key1, key2;
+
+ for (int32_t len = 1; len <= maxLength; len++) {
+ int32_t i = 0;
+ for (; i < len - 1; i++) {
+ str1[i] = str2[i] = (UChar)0x61; // 'a'
+ }
+ str1[i] = (UChar)0x41; // 'A'
+ str2[i] = (UChar)0x61; // 'a'
+
+ UErrorCode status = U_ZERO_ERROR;
+ col->getCollationKey(str1, len, key1, status);
+ col->getCollationKey(str2, len, key2, status);
+
+ UCollationResult cmpKey = key1.compareTo(key2, status);
+ UCollationResult cmpCol = col->compare(str1, len, str2, len, status);
+
+ if (U_FAILURE(status)) {
+ errln("Error in caseFirstCompressionSub");
+ } else if (cmpKey != cmpCol) {
+ errln((UnicodeString)"Inconsistent comparison(" + opt
+ + "): str1=" + UnicodeString(str1, len) + ", str2=" + UnicodeString(str2, len)
+ + ", cmpKey=" + cmpKey + ", cmpCol=" + cmpCol);
+ }
+ }
+}
+
+void CollationRegressionTest::TestTrailingComment() {
+ // ICU ticket #8070:
+ // Check that the rule parser handles a comment without terminating end-of-line.
+ IcuTestErrorCode errorCode(*this, "TestTrailingComment");
+ RuleBasedCollator coll(UNICODE_STRING_SIMPLE("&c<b#comment1\n<a#comment2"), errorCode);
+ UnicodeString a((UChar)0x61), b((UChar)0x62), c((UChar)0x63);
+ assertTrue("c<b", coll.compare(c, b) < 0);
+ assertTrue("b<a", coll.compare(b, a) < 0);
+}
+
+void CollationRegressionTest::TestBeforeWithTooStrongAfter() {
+ // ICU ticket #9959:
+ // Forbid rules with a before-reset followed by a stronger relation.
+ IcuTestErrorCode errorCode(*this, "TestBeforeWithTooStrongAfter");
+ RuleBasedCollator before2(UNICODE_STRING_SIMPLE("&[before 2]x<<q<p"), errorCode);
+ if(errorCode.isSuccess()) {
+ errln("should forbid before-2-reset followed by primary relation");
+ } else {
+ errorCode.reset();
+ }
+ RuleBasedCollator before3(UNICODE_STRING_SIMPLE("&[before 3]x<<<q<<s<p"), errorCode);
+ if(errorCode.isSuccess()) {
+ errln("should forbid before-3-reset followed by primary or secondary relation");
+ } else {
+ errorCode.reset();
+ }
+}
+
void CollationRegressionTest::compareArray(Collator &c,
const UChar tests[][CollationRegressionTest::MAX_TOKEN_LEN],
int32_t testCount)
if (c1 != c2)
{
UnicodeString msg, msg1(" ");
-
+
msg += msg1 + count;
msg += ": strength(0x";
appendHex(c1, 8, msg);
logln("Collation Regression Tests: ");
}
- if(en_us) {
- switch (index)
- {
- case 0: name = "Test4048446"; if (exec) Test4048446(/* par */); break;
- case 1: name = "Test4051866"; if (exec) Test4051866(/* par */); break;
- case 2: name = "Test4053636"; if (exec) Test4053636(/* par */); break;
- case 3: name = "Test4054238"; if (exec) Test4054238(/* par */); break;
- case 4: name = "Test4054734"; if (exec) Test4054734(/* par */); break;
- case 5: name = "Test4054736"; if (exec) Test4054736(/* par */); break;
- case 6: name = "Test4058613"; if (exec) Test4058613(/* par */); break;
- case 7: name = "Test4059820"; if (exec) Test4059820(/* par */); break;
- case 8: name = "Test4060154"; if (exec) Test4060154(/* par */); break;
- case 9: name = "Test4062418"; if (exec) Test4062418(/* par */); break;
- case 10: name = "Test4065540"; if (exec) Test4065540(/* par */); break;
- case 11: name = "Test4066189"; if (exec) Test4066189(/* par */); break;
- case 12: name = "Test4066696"; if (exec) Test4066696(/* par */); break;
- case 13: name = "Test4076676"; if (exec) Test4076676(/* par */); break;
- case 14: name = "Test4078588"; if (exec) Test4078588(/* par */); break;
- case 15: name = "Test4079231"; if (exec) Test4079231(/* par */); break;
- case 16: name = "Test4081866"; if (exec) Test4081866(/* par */); break;
- case 17: name = "Test4087241"; if (exec) Test4087241(/* par */); break;
- case 18: name = "Test4087243"; if (exec) Test4087243(/* par */); break;
- case 19: name = "Test4092260"; if (exec) Test4092260(/* par */); break;
- case 20: name = "Test4095316"; if (exec) Test4095316(/* par */); break;
- case 21: name = "Test4101940"; if (exec) Test4101940(/* par */); break;
- case 22: name = "Test4103436"; if (exec) Test4103436(/* par */); break;
- case 23: name = "Test4114076"; if (exec) Test4114076(/* par */); break;
- case 24: name = "Test4114077"; if (exec) Test4114077(/* par */); break;
- case 25: name = "Test4124632"; if (exec) Test4124632(/* par */); break;
- case 26: name = "Test4132736"; if (exec) Test4132736(/* par */); break;
- case 27: name = "Test4133509"; if (exec) Test4133509(/* par */); break;
- case 28: name = "Test4139572"; if (exec) Test4139572(/* par */); break;
- case 29: name = "Test4141640"; if (exec) Test4141640(/* par */); break;
- case 30: name = "Test4146160"; if (exec) Test4146160(/* par */); break;
- default: name = ""; break;
- }
- } else {
- errln("Class collator not instantiated");
- name = "";
+ if(en_us == NULL) {
+ dataerrln("Class collator not instantiated");
+ name = "";
+ return;
}
+ TESTCASE_AUTO_BEGIN;
+ TESTCASE_AUTO(Test4048446);
+ TESTCASE_AUTO(Test4051866);
+ TESTCASE_AUTO(Test4053636);
+ TESTCASE_AUTO(Test4054238);
+ TESTCASE_AUTO(Test4054734);
+ TESTCASE_AUTO(Test4054736);
+ TESTCASE_AUTO(Test4058613);
+ TESTCASE_AUTO(Test4059820);
+ TESTCASE_AUTO(Test4060154);
+ TESTCASE_AUTO(Test4062418);
+ TESTCASE_AUTO(Test4065540);
+ TESTCASE_AUTO(Test4066189);
+ TESTCASE_AUTO(Test4066696);
+ TESTCASE_AUTO(Test4076676);
+ TESTCASE_AUTO(Test4078588);
+ TESTCASE_AUTO(Test4079231);
+ TESTCASE_AUTO(Test4081866);
+ TESTCASE_AUTO(Test4087241);
+ TESTCASE_AUTO(Test4087243);
+ TESTCASE_AUTO(Test4092260);
+ TESTCASE_AUTO(Test4095316);
+ TESTCASE_AUTO(Test4101940);
+ TESTCASE_AUTO(Test4103436);
+ TESTCASE_AUTO(Test4114076);
+ TESTCASE_AUTO(Test4114077);
+ TESTCASE_AUTO(Test4124632);
+ TESTCASE_AUTO(Test4132736);
+ TESTCASE_AUTO(Test4133509);
+ TESTCASE_AUTO(Test4139572);
+ TESTCASE_AUTO(Test4141640);
+ TESTCASE_AUTO(Test4146160);
+ TESTCASE_AUTO(Test4179216);
+ TESTCASE_AUTO(TestT7189);
+ TESTCASE_AUTO(TestCaseFirstCompression);
+ TESTCASE_AUTO(TestTrailingComment);
+ TESTCASE_AUTO(TestBeforeWithTooStrongAfter);
+ TESTCASE_AUTO_END;
}
#endif /* #if !UCONFIG_NO_COLLATION */