void UCAConformanceTest::TestRulesNonIgnorable(/* par */) { if(logKnownIssue("cldrbug:6745", "UCARules.txt has problems")) { return; } initRbUCA(); if(U_SUCCESS(status)) { setCollNonIgnorable(rbUCA); openTestFile("NON_IGNORABLE"); testConformance(rbUCA); } }
void SSearchTest::offsetTest() { const char *test[] = { // The sequence \u0FB3\u0F71\u0F71\u0F80 contains a discontiguous // contraction (\u0FB3\u0F71\u0F80) logically followed by \u0F71. "\\u1E33\\u0FB3\\u0F71\\u0F71\\u0F80\\uD835\\uDF6C\\u01B0", "\\ua191\\u16ef\\u2036\\u017a", #if 0 // This results in a complex interaction between contraction, // expansion and normalization that confuses the backwards offset fixups. "\\u0F7F\\u0F80\\u0F81\\u0F82\\u0F83\\u0F84\\u0F85", #endif "\\u0F80\\u0F81\\u0F82\\u0F83\\u0F84\\u0F85", "\\u07E9\\u07EA\\u07F1\\u07F2\\u07F3", "\\u02FE\\u02FF" "\\u0300\\u0301\\u0302\\u0303\\u0304\\u0305\\u0306\\u0307\\u0308\\u0309\\u030A\\u030B\\u030C\\u030D\\u030E\\u030F" "\\u0310\\u0311\\u0312\\u0313\\u0314\\u0315\\u0316\\u0317\\u0318\\u0319\\u031A\\u031B\\u031C\\u031D\\u031E\\u031F" "\\u0320\\u0321\\u0322\\u0323\\u0324\\u0325\\u0326\\u0327\\u0328\\u0329\\u032A\\u032B\\u032C\\u032D\\u032E\\u032F" "\\u0330\\u0331\\u0332\\u0333\\u0334\\u0335\\u0336\\u0337\\u0338\\u0339\\u033A\\u033B\\u033C\\u033D\\u033E\\u033F" "\\u0340\\u0341\\u0342\\u0343\\u0344\\u0345\\u0346\\u0347\\u0348\\u0349\\u034A\\u034B\\u034C\\u034D\\u034E", // currently not working, see #8081 "\\u02FE\\u02FF\\u0300\\u0301\\u0302\\u0303\\u0316\\u0317\\u0318", // currently not working, see #8081 "a\\u02FF\\u0301\\u0316", // currently not working, see #8081 "a\\u02FF\\u0316\\u0301", "a\\u0430\\u0301\\u0316", "a\\u0430\\u0316\\u0301", "abc\\u0E41\\u0301\\u0316", "abc\\u0E41\\u0316\\u0301", "\\u0E41\\u0301\\u0316", "\\u0E41\\u0316\\u0301", "a\\u0301\\u0316", "a\\u0316\\u0301", "\\uAC52\\uAC53", "\\u34CA\\u34CB", "\\u11ED\\u11EE", "\\u30C3\\u30D0", "p\\u00E9ch\\u00E9", "a\\u0301\\u0325", "a\\u0300\\u0325", "a\\u0325\\u0300", "A\\u0323\\u0300B", "A\\u0300\\u0323B", "A\\u0301\\u0323B", "A\\u0302\\u0301\\u0323B", "abc", "ab\\u0300c", "ab\\u0300\\u0323c", " \\uD800\\uDC00\\uDC00", "a\\uD800\\uDC00\\uDC00", "A\\u0301\\u0301", "A\\u0301\\u0323", "A\\u0301\\u0323B", "B\\u0301\\u0323C", "A\\u0300\\u0323B", "\\u0301A\\u0301\\u0301", "abcd\\r\\u0301", "p\\u00EAche", "pe\\u0302che", }; int32_t testCount = ARRAY_SIZE(test); UErrorCode status = U_ZERO_ERROR; RuleBasedCollator *col = (RuleBasedCollator *) Collator::createInstance(Locale::getEnglish(), status); if (U_FAILURE(status)) { errcheckln(status, "Failed to create collator in offsetTest! - %s", u_errorName(status)); return; } char buffer[4096]; // A bit of a hack... just happens to be long enough for all the test cases... // We could allocate one that's the right size by (CE_count * 10) + 2 // 10 chars is enough room for 8 hex digits plus ", ". 2 extra chars for "[" and "]" col->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status); for(int32_t i = 0; i < testCount; i += 1) { if (i>=4 && i<=6 && logKnownIssue("9156", "was 8081")) { continue; // timebomb until ticket #9156 (was #8081) is resolved } UnicodeString ts = CharsToUnicodeString(test[i]); CollationElementIterator *iter = col->createCollationElementIterator(ts); OrderList forwardList; OrderList backwardList; int32_t order, low, high; do { low = iter->getOffset(); order = iter->next(status); high = iter->getOffset(); forwardList.add(order, low, high); } while (order != CollationElementIterator::NULLORDER); iter->reset(); iter->setOffset(ts.length(), status); backwardList.add(CollationElementIterator::NULLORDER, iter->getOffset(), iter->getOffset()); do { high = iter->getOffset(); order = iter->previous(status); low = iter->getOffset(); if (order == CollationElementIterator::NULLORDER) { break; } backwardList.add(order, low, high); } while (TRUE); backwardList.reverse(); if (forwardList.compare(backwardList)) { logln("Works with \"%s\"", test[i]); logln("Forward offsets: [%s]", printOffsets(buffer, forwardList)); // logln("Backward offsets: [%s]", printOffsets(buffer, backwardList)); logln("Forward CEs: [%s]", printOrders(buffer, forwardList)); // logln("Backward CEs: [%s]", printOrders(buffer, backwardList)); logln(); } else { errln("Fails with \"%s\"", test[i]); infoln("Forward offsets: [%s]", printOffsets(buffer, forwardList)); infoln("Backward offsets: [%s]", printOffsets(buffer, backwardList)); infoln("Forward CEs: [%s]", printOrders(buffer, forwardList)); infoln("Backward CEs: [%s]", printOrders(buffer, backwardList)); infoln(); } delete iter; } delete col; }
void CalendarLimitTest::doLimitsTest(Calendar& cal, const int32_t* fieldsToTest, UDate startDate, int32_t testDuration) { static const int32_t FIELDS[] = { UCAL_ERA, UCAL_YEAR, UCAL_MONTH, UCAL_WEEK_OF_YEAR, UCAL_WEEK_OF_MONTH, UCAL_DAY_OF_MONTH, UCAL_DAY_OF_YEAR, UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_YEAR_WOY, UCAL_EXTENDED_YEAR, -1, }; static const char* FIELD_NAME[] = { "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH", "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR", "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET", "DST_OFFSET", "YEAR_WOY", "DOW_LOCAL", "EXTENDED_YEAR", "JULIAN_DAY", "MILLISECONDS_IN_DAY", "IS_LEAP_MONTH" }; UErrorCode status = U_ZERO_ERROR; int32_t i, j; UnicodeString ymd; GregorianCalendar greg(status); if (failure(status, "new GregorianCalendar")) { return; } greg.setTime(startDate, status); if (failure(status, "GregorianCalendar::setTime")) { return; } logln((UnicodeString)"Start: " + startDate); if (fieldsToTest == NULL) { fieldsToTest = FIELDS; } // Keep a record of minima and maxima that we actually see. // These are kept in an array of arrays of hashes. int32_t limits[UCAL_FIELD_COUNT][4]; for (j = 0; j < UCAL_FIELD_COUNT; j++) { limits[j][0] = INT32_MAX; limits[j][1] = INT32_MIN; limits[j][2] = INT32_MAX; limits[j][3] = INT32_MIN; } // This test can run for a long time; show progress. UDate millis = ucal_getNow(); UDate mark = millis + 5000; // 5 sec millis -= testDuration * 1000; // stop time if testDuration<0 for (i = 0; testDuration > 0 ? i < testDuration : ucal_getNow() < millis; ++i) { if (ucal_getNow() >= mark) { logln((UnicodeString)"(" + i + " days)"); mark += 5000; // 5 sec } UDate testMillis = greg.getTime(status); cal.setTime(testMillis, status); cal.setMinimalDaysInFirstWeek(1); if (failure(status, "Calendar set/getTime")) { return; } for (j = 0; fieldsToTest[j] >= 0; ++j) { UCalendarDateFields f = (UCalendarDateFields)fieldsToTest[j]; int32_t v = cal.get(f, status); int32_t minActual = cal.getActualMinimum(f, status); int32_t maxActual = cal.getActualMaximum(f, status); int32_t minLow = cal.getMinimum(f); int32_t minHigh = cal.getGreatestMinimum(f); int32_t maxLow = cal.getLeastMaximum(f); int32_t maxHigh = cal.getMaximum(f); if (limits[j][0] > minActual) { // the minimum limits[j][0] = minActual; } if (limits[j][1] < minActual) { // the greatest minimum limits[j][1] = minActual; } if (limits[j][2] > maxActual) { // the least maximum limits[j][2] = maxActual; } if (limits[j][3] < maxActual) { // the maximum limits[j][3] = maxActual; } if (minActual < minLow || minActual > minHigh) { errln((UnicodeString)"Fail: [" + cal.getType() + "] " + ymdToString(cal, ymd) + " Range for min of " + FIELD_NAME[f] + "(" + f + ")=" + minLow + ".." + minHigh + ", actual_min=" + minActual); } if (maxActual < maxLow || maxActual > maxHigh) { if ( uprv_strcmp(cal.getType(), "chinese") == 0 && testMillis >= 2842992000000.0 && testMillis <= 2906668800000.0 && logKnownIssue("12620", "chinese calendar failures for some actualMax tests")) { logln((UnicodeString)"KnownFail: [" + cal.getType() + "] " + ymdToString(cal, ymd) + " Range for max of " + FIELD_NAME[f] + "(" + f + ")=" + maxLow + ".." + maxHigh + ", actual_max=" + maxActual); } else { errln((UnicodeString)"Fail: [" + cal.getType() + "] " + ymdToString(cal, ymd) + " Range for max of " + FIELD_NAME[f] + "(" + f + ")=" + maxLow + ".." + maxHigh + ", actual_max=" + maxActual); } } if (v < minActual || v > maxActual) { // timebomb per #9967, fix with #9972 if ( uprv_strcmp(cal.getType(), "dangi") == 0 && testMillis >= 1865635198000.0 && logKnownIssue("9972", "as per #9967")) { // Feb 2029 gregorian, end of dangi 4361 logln((UnicodeString)"KnownFail: [" + cal.getType() + "] " + ymdToString(cal, ymd) + " " + FIELD_NAME[f] + "(" + f + ")=" + v + ", actual=" + minActual + ".." + maxActual + ", allowed=(" + minLow + ".." + minHigh + ")..(" + maxLow + ".." + maxHigh + ")"); } else if ( uprv_strcmp(cal.getType(), "chinese") == 0 && testMillis >= 2842992000000.0 && testMillis <= 2906668800000.0 && logKnownIssue("12620", "chinese calendar failures for some actualMax tests")) { logln((UnicodeString)"KnownFail: [" + cal.getType() + "] " + ymdToString(cal, ymd) + " " + FIELD_NAME[f] + "(" + f + ")=" + v + ", actual=" + minActual + ".." + maxActual + ", allowed=(" + minLow + ".." + minHigh + ")..(" + maxLow + ".." + maxHigh + ")"); } else { errln((UnicodeString)"Fail: [" + cal.getType() + "] " + ymdToString(cal, ymd) + " " + FIELD_NAME[f] + "(" + f + ")=" + v + ", actual=" + minActual + ".." + maxActual + ", allowed=(" + minLow + ".." + minHigh + ")..(" + maxLow + ".." + maxHigh + ")"); } } } greg.add(UCAL_DAY_OF_YEAR, 1, status); if (failure(status, "Calendar::add")) { return; } } // Check actual maxima and minima seen against ranges returned // by API. UnicodeString buf; for (j = 0; fieldsToTest[j] >= 0; ++j) { int32_t rangeLow, rangeHigh; UBool fullRangeSeen = TRUE; UCalendarDateFields f = (UCalendarDateFields)fieldsToTest[j]; buf.remove(); buf.append((UnicodeString)"[" + cal.getType() + "] " + FIELD_NAME[f]); // Minumum rangeLow = cal.getMinimum(f); rangeHigh = cal.getGreatestMinimum(f); if (limits[j][0] != rangeLow || limits[j][1] != rangeHigh) { fullRangeSeen = FALSE; } buf.append((UnicodeString)" minima range=" + rangeLow + ".." + rangeHigh); buf.append((UnicodeString)" minima actual=" + limits[j][0] + ".." + limits[j][1]); // Maximum rangeLow = cal.getLeastMaximum(f); rangeHigh = cal.getMaximum(f); if (limits[j][2] != rangeLow || limits[j][3] != rangeHigh) { fullRangeSeen = FALSE; } buf.append((UnicodeString)" maxima range=" + rangeLow + ".." + rangeHigh); buf.append((UnicodeString)" maxima actual=" + limits[j][2] + ".." + limits[j][3]); if (fullRangeSeen) { logln((UnicodeString)"OK: " + buf); } else { // This may or may not be an error -- if the range of dates // we scan over doesn't happen to contain a minimum or // maximum, it doesn't mean some other range won't. logln((UnicodeString)"Warning: " + buf); } } logln((UnicodeString)"End: " + greg.getTime(status)); }