diff options
Diffstat (limited to 'Build/source/libs/icu/icu-src/source/test/cintltst')
14 files changed, 715 insertions, 50 deletions
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.c index 831236d9dd7..bb49f4d674c 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.c @@ -73,6 +73,7 @@ void addCollAPITest(TestNode** root) /*addTest(root, &TestGetDefaultRules, "tscoll/capitst/TestGetDefaultRules");*/ addTest(root, &TestDecomposition, "tscoll/capitst/TestDecomposition"); addTest(root, &TestSafeClone, "tscoll/capitst/TestSafeClone"); + addTest(root, &TestClone, "tscoll/capitst/TestClone"); addTest(root, &TestCloneBinary, "tscoll/capitst/TestCloneBinary"); addTest(root, &TestGetSetAttr, "tscoll/capitst/TestGetSetAttr"); addTest(root, &TestBounds, "tscoll/capitst/TestBounds"); @@ -806,6 +807,124 @@ void TestSafeClone() { } } +void TestClone() { + UChar test1[6]; + UChar test2[6]; + static const UChar umlautUStr[] = {0x00DC, 0}; + static const UChar oeStr[] = {0x0055, 0x0045, 0}; + UCollator * someCollators [CLONETEST_COLLATOR_COUNT]; + UCollator * someClonedCollators [CLONETEST_COLLATOR_COUNT]; + UCollator * col = NULL; + UErrorCode err = U_ZERO_ERROR; + int8_t idx = 6; /* Leave this here to test buffer alignment in memory*/ + const char sampleRuleChars[] = "&Z < CH"; + UChar sampleRule[sizeof(sampleRuleChars)]; + + u_uastrcpy(test1, "abCda"); + u_uastrcpy(test2, "abcda"); + u_uastrcpy(sampleRule, sampleRuleChars); + + /* one default collator & two complex ones */ + someCollators[0] = ucol_open("en_US", &err); + someCollators[1] = ucol_open("ko", &err); + someCollators[2] = ucol_open("ja_JP", &err); + someCollators[3] = ucol_openRules(sampleRule, -1, UCOL_ON, UCOL_TERTIARY, NULL, &err); + if(U_FAILURE(err)) { + for (idx = 0; idx < CLONETEST_COLLATOR_COUNT; idx++) { + ucol_close(someCollators[idx]); + } + log_data_err("Couldn't open one or more collators\n"); + return; + } + + /* Check the various error & informational states: */ + + /* Null status - just returns NULL */ + if (NULL != ucol_clone(someCollators[0], NULL)) + { + log_err("FAIL: Cloned Collator failed to deal correctly with null status\n"); + } + /* error status - should return 0 & keep error the same */ + err = U_MEMORY_ALLOCATION_ERROR; + if (NULL != ucol_clone(someCollators[0], &err) || err != U_MEMORY_ALLOCATION_ERROR) + { + log_err("FAIL: Cloned Collator failed to deal correctly with incoming error status\n"); + } + err = U_ZERO_ERROR; + + /* Verify we can use this run-time calculated size */ + if (NULL == (col = ucol_clone(someCollators[0], &err)) || U_FAILURE(err)) + { + log_err("FAIL: Collator can't be cloned.\n"); + } + if (col) ucol_close(col); + + if (NULL == (col = ucol_clone(someCollators[0], &err)) || err != U_ZERO_ERROR) + { + log_err("FAIL: Cloned Collator failed to deal correctly\n"); + } + if (col) ucol_close(col); + err = U_ZERO_ERROR; + + /* Null Collator - return NULL & set U_ILLEGAL_ARGUMENT_ERROR */ + if (NULL != ucol_clone(NULL, &err) || err != U_ILLEGAL_ARGUMENT_ERROR) + { + log_err("FAIL: Cloned Collator failed to deal correctly with null Collator pointer\n"); + } + err = U_ZERO_ERROR; + + /* Test that a cloned collator doesn't accidentally use UCA. */ + col=ucol_open("de@collation=phonebook", &err); + someClonedCollators[0] = ucol_clone(col, &err); + doAssert( (ucol_greater(col, umlautUStr, u_strlen(umlautUStr), oeStr, u_strlen(oeStr))), "Original German phonebook collation sorts differently than expected"); + doAssert( (ucol_greater(someClonedCollators[0], umlautUStr, u_strlen(umlautUStr), oeStr, u_strlen(oeStr))), "Cloned German phonebook collation sorts differently than expected"); + if (!ucol_equals(someClonedCollators[0], col)) { + log_err("FAIL: Cloned German phonebook collator is not equal to original.\n"); + } + ucol_close(col); + ucol_close(someClonedCollators[0]); + + err = U_ZERO_ERROR; + + /* change orig & clone & make sure they are independent */ + + for (idx = 0; idx < CLONETEST_COLLATOR_COUNT; idx++) + { + ucol_setStrength(someCollators[idx], UCOL_IDENTICAL); + err = U_ZERO_ERROR; + ucol_close(ucol_clone(someCollators[idx], &err)); + if (err != U_ZERO_ERROR) { + log_err("FAIL: collator number %d was not allocated.\n", idx); + log_err("FAIL: status of Collator[%d] is %d (hex: %x).\n", idx, err, err); + } + + err = U_ZERO_ERROR; + someClonedCollators[idx] = ucol_clone(someCollators[idx], &err); + if (U_FAILURE(err)) { + log_err("FAIL: Unable to clone collator %d - %s\n", idx, u_errorName(err)); + continue; + } + if (!ucol_equals(someClonedCollators[idx], someCollators[idx])) { + log_err("FAIL: Cloned collator is not equal to original at index = %d.\n", idx); + } + + /* Check the usability */ + ucol_setStrength(someCollators[idx], UCOL_PRIMARY); + ucol_setAttribute(someCollators[idx], UCOL_CASE_LEVEL, UCOL_OFF, &err); + + doAssert( (ucol_equal(someCollators[idx], test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"abcda\" == \"abCda\""); + + /* Close the original to make sure that the clone is usable. */ + ucol_close(someCollators[idx]); + + ucol_setStrength(someClonedCollators[idx], UCOL_TERTIARY); + ucol_setAttribute(someClonedCollators[idx], UCOL_CASE_LEVEL, UCOL_OFF, &err); + doAssert( (ucol_greater(someClonedCollators[idx], test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"abCda\" >>> \"abcda\" "); + + ucol_close(someClonedCollators[idx]); + } +} + void TestCloneBinary(){ UErrorCode err = U_ZERO_ERROR; UCollator * col = ucol_open("en_US", &err); diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.h b/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.h index 7f6f558b0d3..5c761fad895 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.h +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.h @@ -75,6 +75,11 @@ void TestSafeClone(void); /** + * Test ucol_clone () + **/ + void TestClone(void); + + /** * Test ucol_cloneBinary(), ucol_openBinary() **/ void TestCloneBinary(void); diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/cbiditst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/cbiditst.c index 6d233130fe0..38be9c50564 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/cbiditst.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/cbiditst.c @@ -4591,6 +4591,15 @@ testClassOverride(void) { ubidi_close(pBiDi); return; } + // Quick callback test (API coverage). + if (ubidi_getCustomizedClass(pBiDi, u'A')!=AL || + ubidi_getCustomizedClass(pBiDi, u'H')!=R || + ubidi_getCustomizedClass(pBiDi, u'^')!=PDF || + ubidi_getCustomizedClass(pBiDi, u'~')!=BN) { + log_err("ubidi_getCustomizedClass() returns different values than " + "expected from overrideBidiClass() customClasses[]\n"); + } + verifyCallbackParams(oldFn, oldContext, NULL, NULL, 0); ubidi_getClassCallback(pBiDi, &oldFn, &oldContext); diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/ccapitst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/ccapitst.c index 50750137908..aee75e6dd9d 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/ccapitst.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/ccapitst.c @@ -64,6 +64,7 @@ static void TestJ1968(void); static void TestLMBCSMaxChar(void); #endif +static void TestConvertClone(void); #if !UCONFIG_NO_LEGACY_CONVERSION static void TestConvertSafeCloneCallback(void); #endif @@ -94,6 +95,7 @@ void addTestConvert(TestNode** root) addTest(root, &TestAlias, "tsconv/ccapitst/TestAlias"); addTest(root, &TestDuplicateAlias, "tsconv/ccapitst/TestDuplicateAlias"); addTest(root, &TestConvertSafeClone, "tsconv/ccapitst/TestConvertSafeClone"); + addTest(root, &TestConvertClone, "tsconv/ccapitst/TestConvertClone"); #if !UCONFIG_NO_LEGACY_CONVERSION addTest(root, &TestConvertSafeCloneCallback,"tsconv/ccapitst/TestConvertSafeCloneCallback"); #endif @@ -1901,6 +1903,138 @@ static void TestConvertSafeClone() } } + +static void TestConvertClone() +{ + /* one 'regular' & all the 'private stateful' converters */ + static const char *const names[] = { +#if !UCONFIG_NO_LEGACY_CONVERSION + "ibm-1047", + "ISO_2022,locale=zh,version=1", +#endif + "SCSU", +#if !UCONFIG_NO_LEGACY_CONVERSION + "HZ", + "lmbcs", + "ISCII,version=0", + "ISO_2022,locale=kr,version=1", + "ISO_2022,locale=jp,version=2", +#endif + "BOCU-1", + "UTF-7", +#if !UCONFIG_NO_LEGACY_CONVERSION + "IMAP-mailbox-name", + "ibm-1047-s390" +#else + "IMAP=mailbox-name" +#endif + }; + + char charBuffer[21]; /* Leave at an odd number for alignment testing */ + UConverter * cnv, *cnv2; + UErrorCode err; + + char *pCharBuffer; + const char *pConstCharBuffer; + const char *charBufferLimit = charBuffer + UPRV_LENGTHOF(charBuffer); + UChar uniBuffer[] = {0x0058, 0x0059, 0x005A}; /* "XYZ" */ + UChar uniCharBuffer[20]; + char charSourceBuffer[] = { 0x1b, 0x24, 0x42 }; + const char *pCharSource = charSourceBuffer; + const char *pCharSourceLimit = charSourceBuffer + sizeof(charSourceBuffer); + UChar *pUCharTarget = uniCharBuffer; + UChar *pUCharTargetLimit = uniCharBuffer + UPRV_LENGTHOF(uniCharBuffer); + const UChar * pUniBuffer; + const UChar *uniBufferLimit = uniBuffer + UPRV_LENGTHOF(uniBuffer); + int32_t idx; + + err = U_ZERO_ERROR; + cnv = ucnv_open(names[0], &err); + if(U_SUCCESS(err)) { + /* Check the various error & informational states: */ + + /* Null status - just returns NULL */ + if (NULL != ucnv_clone(cnv, NULL)) + { + log_err("FAIL: Cloned converter failed to deal correctly with null status\n"); + } + /* error status - should return 0 & keep error the same */ + err = U_MEMORY_ALLOCATION_ERROR; + if (NULL != ucnv_clone(cnv, &err) || err != U_MEMORY_ALLOCATION_ERROR) + { + log_err("FAIL: Cloned converter failed to deal correctly with incoming error status\n"); + } + err = U_ZERO_ERROR; + + /* Null buffer size pointer is ok */ + if (NULL == (cnv2 = ucnv_clone(cnv, &err)) || U_FAILURE(err)) + { + log_err("FAIL: Failed to clone.\n"); + } + ucnv_close(cnv2); + err = U_ZERO_ERROR; + + /* Null converter - return NULL & set U_ILLEGAL_ARGUMENT_ERROR */ + if (NULL != ucnv_clone(NULL, &err) || err != U_ILLEGAL_ARGUMENT_ERROR) + { + log_err("FAIL: Cloned converter failed to deal correctly with null converter pointer\n"); + } + + ucnv_close(cnv); + } + + /* Do these cloned converters work at all - shuffle UChars to chars & back again..*/ + for (idx = 0; idx < UPRV_LENGTHOF(names); idx++) + { + err = U_ZERO_ERROR; + cnv = ucnv_open(names[idx], &err); + if(U_FAILURE(err)) { + log_data_err("ucnv_open(\"%s\") failed - %s\n", names[idx], u_errorName(err)); + continue; + } + + cnv2 = ucnv_clone(cnv, &err); + + /* close the original immediately to make sure that the clone works by itself */ + ucnv_close(cnv); + + pCharBuffer = charBuffer; + pUniBuffer = uniBuffer; + + ucnv_fromUnicode(cnv2, + &pCharBuffer, + charBufferLimit, + &pUniBuffer, + uniBufferLimit, + NULL, + TRUE, + &err); + if(U_FAILURE(err)){ + log_err("FAIL: cloned converter failed to do fromU conversion. Error: %s\n",u_errorName(err)); + } + ucnv_toUnicode(cnv2, + &pUCharTarget, + pUCharTargetLimit, + &pCharSource, + pCharSourceLimit, + NULL, + TRUE, + &err + ); + + if(U_FAILURE(err)){ + log_err("FAIL: cloned converter failed to do toU conversion. Error: %s\n",u_errorName(err)); + } + + pConstCharBuffer = charBuffer; + if (uniBuffer [0] != ucnv_getNextUChar(cnv2, &pConstCharBuffer, pCharBuffer, &err)) + { + log_err("FAIL: Cloned converter failed to do conversion. Error: %s\n",u_errorName(err)); + } + ucnv_close(cnv2); + } +} + static void TestCCSID() { #if !UCONFIG_NO_LEGACY_CONVERSION UConverter *cnv; diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/cdateintervalformattest.c b/Build/source/libs/icu/icu-src/source/test/cintltst/cdateintervalformattest.c index 513989ac6bb..8f157d2f5d4 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/cdateintervalformattest.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/cdateintervalformattest.c @@ -368,23 +368,23 @@ static void TestFormatToResult() { { const char* message = "Field position test 1"; - const UChar* expectedString = u"27. September 2010, 15:00 – 2. März 2011, 18:30"; + const UChar* expectedString = u"27. September 2010 um 15:00 – 2. März 2011 um 18:30"; udtitvfmt_formatToResult(fmt, Date201009270800, Date201103021030, fdi, &ec); assertSuccess("Formatting", &ec); static const UFieldPositionWithCategory expectedFieldPositions[] = { // category, field, begin index, end index - {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 25}, + {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 27}, {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 0, 2}, {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 4, 13}, {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 14, 18}, - {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 20, 22}, - {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 23, 25}, - {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 28, 47}, - {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 28, 29}, - {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 31, 35}, - {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 36, 40}, - {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 42, 44}, - {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 45, 47}}; + {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 22, 24}, + {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 25, 27}, + {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 30, 51}, + {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 30, 31}, + {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 33, 37}, + {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 38, 42}, + {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 46, 48}, + {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 49, 51}}; checkMixedFormattedValue( message, udtitvfmt_resultAsValue(fdi, &ec), @@ -438,23 +438,23 @@ static void TestFormatCalendarToResult() { { const char* message = "Field position test 1"; - const UChar* expectedString = u"27. September 2010, 15:00 – 2. März 2011, 18:30"; + const UChar* expectedString = u"27. September 2010 um 15:00 – 2. März 2011 um 18:30"; udtitvfmt_formatCalendarToResult(fmt, ucal1, ucal2, fdi, &ec); assertSuccess("Formatting", &ec); static const UFieldPositionWithCategory expectedFieldPositions[] = { // category, field, begin index, end index - {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 25}, + {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 27}, {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 0, 2}, {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 4, 13}, {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 14, 18}, - {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 20, 22}, - {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 23, 25}, - {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 28, 47}, - {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 28, 29}, - {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 31, 35}, - {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 36, 40}, - {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 42, 44}, - {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 45, 47}}; + {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 22, 24}, + {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 25, 27}, + {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 30, 51}, + {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 30, 31}, + {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 33, 37}, + {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 38, 42}, + {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 46, 48}, + {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 49, 51}}; checkMixedFormattedValue( message, udtitvfmt_resultAsValue(fdi, &ec), @@ -493,23 +493,23 @@ static void TestFormatCalendarToResult() { ucal_setMillis(ucal5, Date158210160000, &ec); // 1 2 3 4 // 012345678901234567890123456789012345678901234567890 - const UChar* expectedString = u"4. Oktober 1582, 00:00 – 16. Oktober 1582, 00:00"; + const UChar* expectedString = u"4. Oktober 1582 um 00:00 – 16. Oktober 1582 um 00:00"; udtitvfmt_formatCalendarToResult(fmt, ucal4, ucal5, fdi, &ec); assertSuccess("Formatting", &ec); static const UFieldPositionWithCategory expectedFieldPositions[] = { // category, field, begin index, end index - {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 22}, + {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 24}, {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 0, 1}, {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 3, 10}, {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 11, 15}, - {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 17, 19}, - {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 20, 22}, - {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 25, 48}, - {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 25, 27}, - {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 29, 36}, - {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 37, 41}, - {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 43, 45}, - {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 46, 48}}; + {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 19, 21}, + {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 22, 24}, + {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 27, 52}, + {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 27, 29}, + {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 31, 38}, + {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 39, 43}, + {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 47, 49}, + {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 50, 52}}; checkMixedFormattedValue( message, udtitvfmt_resultAsValue(fdi, &ec), @@ -527,23 +527,23 @@ static void TestFormatCalendarToResult() { const char* message = "Field position test 4"; // 1 2 3 4 // 012345678901234567890123456789012345678901234567890 - const UChar* expectedString = u"14. Oktober 1582, 00:00 – 16. Oktober 1582, 00:00"; + const UChar* expectedString = u"14. Oktober 1582 um 00:00 – 16. Oktober 1582 um 00:00"; udtitvfmt_formatCalendarToResult(fmt, ucal4, ucal5, fdi, &ec); assertSuccess("Formatting", &ec); static const UFieldPositionWithCategory expectedFieldPositions[] = { // category, field, begin index, end index - {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 23}, + {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 25}, {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 0, 2}, {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 4, 11}, {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 12, 16}, - {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 18, 20}, - {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 21, 23}, - {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 26, 49}, - {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 26, 28}, - {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 30, 37}, - {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 38, 42}, - {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 44, 46}, - {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 47, 49}}; + {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 20, 22}, + {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 23, 25}, + {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 28, 53}, + {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 28, 30}, + {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 32, 39}, + {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 40, 44}, + {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 48, 50}, + {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 51, 53}}; checkMixedFormattedValue( message, udtitvfmt_resultAsValue(fdi, &ec), diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/cdattst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/cdattst.c index 00b2d6a01a1..2c5d51c64b2 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/cdattst.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/cdattst.c @@ -45,6 +45,7 @@ static void TestFormatForFields(void); static void TestForceGannenNumbering(void); static void TestMapDateToCalFields(void); static void TestNarrowQuarters(void); +static void TestExtraneousCharacters(void); void addDateForTest(TestNode** root); @@ -67,6 +68,7 @@ void addDateForTest(TestNode** root) TESTCASE(TestForceGannenNumbering); TESTCASE(TestMapDateToCalFields); TESTCASE(TestNarrowQuarters); + TESTCASE(TestExtraneousCharacters); } /* Testing the DateFormat API */ static void TestDateFormat() @@ -2017,4 +2019,24 @@ static void TestNarrowQuarters(void) { } } +static void TestExtraneousCharacters(void) { + // regression test for ICU-21802 + UErrorCode err = U_ZERO_ERROR; + UCalendar* cal = ucal_open(u"UTC", -1, "en_US", UCAL_GREGORIAN, &err); + UDateFormat* df = udat_open(UDAT_PATTERN, UDAT_PATTERN, "en_US", u"UTC", -1, u"yyyyMMdd", -1, &err); + + if (assertSuccess("Failed to create date formatter and calendar", &err)) { + udat_setLenient(df, false); + + udat_parseCalendar(df, cal, u"2021", -1, NULL, &err); + assertTrue("Success parsing '2021'", err == U_PARSE_ERROR); + + err = U_ZERO_ERROR; + udat_parseCalendar(df, cal, u"2021-", -1, NULL, &err); + assertTrue("Success parsing '2021-'", err == U_PARSE_ERROR); + } + udat_close(df); + ucal_close(cal); +} + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/cldrtest.c b/Build/source/libs/icu/icu-src/source/test/cintltst/cldrtest.c index 7767cf9f097..f83a6f142d8 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/cldrtest.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/cldrtest.c @@ -1002,6 +1002,10 @@ static void VerifyTranslation(void) { log_knownIssue("cldrbug:14995", "mai/sd_Deva day names use chars not in exemplars")) { end = 0; } + if (uprv_strncmp(currLoc,"ks_Deva",7) == 0 && + log_knownIssue("cldrbug:15355", "ks_Deva day names use chars not in exemplars")) { + end = 0; + } for (idx = 0; idx < end; idx++) { const UChar *fromBundleStr = ures_getStringByIndex(resArray, idx, &langSize, &errorCode); @@ -1035,6 +1039,10 @@ static void VerifyTranslation(void) { log_knownIssue("cldrbug:14995", "sd_Deva month names use chars not in exemplars")) { end = 0; } + if (uprv_strncmp(currLoc,"ks_Deva",7) == 0 && + log_knownIssue("cldrbug:15355", "ks_Deva month names use chars not in exemplars")) { + end = 0; + } for (idx = 0; idx < end; idx++) { const UChar *fromBundleStr = ures_getStringByIndex(resArray, idx, &langSize, &errorCode); diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/cloctst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/cloctst.c index 8707babbbee..606e0a2794b 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/cloctst.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/cloctst.c @@ -1552,18 +1552,18 @@ static void TestSimpleDisplayNames() static void TestUninstalledISO3Names() { /* This test checks to make sure getISO3Language and getISO3Country work right - even for locales that are not installed. */ + even for locales that are not installed (and some installed ones). */ static const char iso2Languages [][4] = { "am", "ba", "fy", "mr", "rn", - "ss", "tw", "zu" }; + "ss", "tw", "zu", "sr" }; static const char iso3Languages [][5] = { "amh", "bak", "fry", "mar", "run", - "ssw", "twi", "zul" }; + "ssw", "twi", "zul", "srp" }; static const char iso2Countries [][6] = { "am_AF", "ba_BW", "fy_KZ", "mr_MO", "rn_MN", - "ss_SB", "tw_TC", "zu_ZW" }; + "ss_SB", "tw_TC", "zu_ZW", "sr_XK" }; static const char iso3Countries [][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG", - "SLB", "TCA", "ZWE" }; + "SLB", "TCA", "ZWE", "XKK" }; int32_t i; - for (i = 0; i < 8; i++) { + for (i = 0; i < 9; i++) { UErrorCode err = U_ZERO_ERROR; const char *test; test = uloc_getISO3Language(iso2Languages[i]); @@ -1571,7 +1571,7 @@ static void TestUninstalledISO3Names() log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n", iso2Languages[i], iso3Languages[i], test, myErrorName(err)); } - for (i = 0; i < 8; i++) { + for (i = 0; i < 9; i++) { UErrorCode err = U_ZERO_ERROR; const char *test; test = uloc_getISO3Country(iso2Countries[i]); @@ -3207,6 +3207,18 @@ static void TestAcceptLanguage(void) { } } } + + // API coverage + status = U_ZERO_ERROR; + static const char *const supported[] = { "en-US", "en-GB", "de-DE", "ja-JP" }; + const char * desired[] = { "de-LI", "en-IN", "zu", "fr" }; + available = uenum_openCharStringsEnumeration(supported, UPRV_LENGTHOF(supported), &status); + tmp[0]=0; + rc = uloc_acceptLanguage(tmp, 199, &outResult, desired, UPRV_LENGTHOF(desired), available, &status); + if (U_FAILURE(status) || rc != 5 || uprv_strcmp(tmp, "de_DE") != 0 || outResult == ULOC_ACCEPT_FAILED) { + log_err("uloc_acceptLanguage() failed to do a simple match\n"); + } + uenum_close(available); } static const char* LOCALE_ALIAS[][2] = { @@ -7053,6 +7065,14 @@ static void TestUldnNameVariants() { u_errorName(status) ); continue; } + // API coverage: Expect to get back the dialect handling which is + // the first item in the displayOptions test data. + UDialectHandling dh = uldn_getDialectHandling(uldn); + UDisplayContext dhContext = (UDisplayContext)dh; // same numeric values + if (dhContext != uloPtr->displayOptions[0]) { + log_err("uldn_getDialectHandling()=%03X != expected UDisplayContext %03X\n", + dhContext, uloPtr->displayOptions[0]); + } const UldnItem * itemPtr = uloPtr->testItems; int32_t itemCount = uloPtr->countItems; for (; itemCount-- > 0; itemPtr++) { diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/cnormtst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/cnormtst.c index c16f8a62846..c7830073b23 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/cnormtst.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/cnormtst.c @@ -65,6 +65,7 @@ TestGetRawDecomposition(void); static void TestAppendRestoreMiddle(void); static void TestGetEasyToUseInstance(void); +static void TestAPICoverage(void); static const char* const canonTests[][3] = { /* Input*/ /*Decomposed*/ /*Composed*/ @@ -156,6 +157,7 @@ void addNormTest(TestNode** root) addTest(root, &TestGetRawDecomposition, "tsnorm/cnormtst/TestGetRawDecomposition"); addTest(root, &TestAppendRestoreMiddle, "tsnorm/cnormtst/TestAppendRestoreMiddle"); addTest(root, &TestGetEasyToUseInstance, "tsnorm/cnormtst/TestGetEasyToUseInstance"); + addTest(root, &TestAPICoverage, "tsnorm/cnormtst/TestAPICoverage"); } static const char* const modeStrings[]={ @@ -1698,4 +1700,55 @@ TestGetEasyToUseInstance() { } } +static void +TestAPICoverage() { + UErrorCode errorCode = U_ZERO_ERROR; + const UNormalizer2 *n2 = unorm2_getNFDInstance(&errorCode); + if (U_FAILURE(errorCode)) { + log_err_status(errorCode, "unorm2_getNFDInstance() failed: %s\n", u_errorName(errorCode)); + return; + } + + if (!unorm2_hasBoundaryBefore(n2, u'C') || unorm2_hasBoundaryBefore(n2, 0x300)) { + log_err("unorm2_hasBoundaryBefore() returns unexpected results\n"); + } + + if (!unorm2_hasBoundaryAfter(n2, u'C') || unorm2_hasBoundaryAfter(n2, 0x300)) { + log_err("unorm2_hasBoundaryAfter() returns unexpected results\n"); + } + + if (!unorm2_isInert(n2, 0x50005) || unorm2_isInert(n2, 0x300)) { + log_err("unorm2_isInert() returns unexpected results\n"); + } + + errorCode = U_ZERO_ERROR; + if (!unorm2_isNormalized(n2, u"c\u0327\u0300", 3, &errorCode) || + unorm2_isNormalized(n2, u"c\u0300\u0327", 3, &errorCode) || + U_FAILURE(errorCode)) { + log_err("unorm2_isNormalized() returns unexpected results\n"); + } + + errorCode = U_ZERO_ERROR; + if (unorm2_quickCheck(n2, u"c\u0327\u0300", 3, &errorCode) == UNORM_NO || + unorm2_quickCheck(n2, u"c\u0300\u0327", 3, &errorCode) == UNORM_YES || + U_FAILURE(errorCode)) { + log_err("unorm2_quickCheck() returns unexpected results\n"); + } + + errorCode = U_ZERO_ERROR; + if (unorm2_spanQuickCheckYes(n2, u"c\u0327\u0300", 3, &errorCode) != 3 || + unorm2_spanQuickCheckYes(n2, u"c\u0300\u0327", 3, &errorCode) != 1 || + U_FAILURE(errorCode)) { + log_err("unorm2_spanQuickCheckYes() returns unexpected results\n"); + } + + errorCode = U_ZERO_ERROR; + UChar first[10] = { u'c', 0x300, 0, 0, 0, 0, 0, 0, 0, 0 }; + int32_t length = unorm2_normalizeSecondAndAppend( + n2, first, 2, UPRV_LENGTHOF(first), u"\u0327d", 2, &errorCode); + if (U_FAILURE(errorCode) || length != 4 || u_strcmp(first, u"c\u0327\u0300d") != 0) { + log_err("unorm2_normalizeSecondAndAppend() returns unexpected results\n"); + } +} + #endif /* #if !UCONFIG_NO_NORMALIZATION */ diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/creststn.c b/Build/source/libs/icu/icu-src/source/test/cintltst/creststn.c index f8c50cb1a82..c61f063a950 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/creststn.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/creststn.c @@ -2180,7 +2180,7 @@ static void TestFallback() UResourceBundle* myResB = ures_open(NULL,"no_NO_NY",&err); UResourceBundle* resLocID = ures_getByKey(myResB, "Version", NULL, &err); const UChar* version = NULL; - static const UChar versionStr[] = u"40"; // 40 in nn_NO or in a parent bundle/root + static const UChar versionStr[] = u"41"; // 41 in nn_NO or in a parent bundle/root if(U_FAILURE(err)) { log_data_err("Expected success when trying to test no_NO_NY aliased to nn_NO for Version " diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/ucsdetst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/ucsdetst.c index f65f8d79aa4..b8d3b5f20b8 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/ucsdetst.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/ucsdetst.c @@ -402,6 +402,7 @@ static void TestBufferOverflow(void) { } for (idx = 0; idx < UPRV_LENGTHOF(testStrings); idx++) { + status = U_ZERO_ERROR; ucsdet_setText(csd, testStrings[idx], -1, &status); match = ucsdet_detect(csd, &status); diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/udatpg_test.c b/Build/source/libs/icu/icu-src/source/test/cintltst/udatpg_test.c index 5f15577b264..66cfb41d47f 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/udatpg_test.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/udatpg_test.c @@ -46,6 +46,7 @@ static void TestGetFieldDisplayNames(void); static void TestGetDefaultHourCycle(void); static void TestGetDefaultHourCycleOnEmptyInstance(void); static void TestEras(void); +static void TestDateTimePatterns(void); void addDateTimePatternGeneratorTest(TestNode** root) { TESTCASE(TestOpenClose); @@ -56,6 +57,7 @@ void addDateTimePatternGeneratorTest(TestNode** root) { TESTCASE(TestGetDefaultHourCycle); TESTCASE(TestGetDefaultHourCycleOnEmptyInstance); TESTCASE(TestEras); + TESTCASE(TestDateTimePatterns); } /* @@ -614,4 +616,178 @@ static void TestEras(void) { } } +enum { kNumDateTimePatterns = 4 }; + +typedef struct { + const char* localeID; + const UChar* expectPat[kNumDateTimePatterns]; +} DTPLocaleAndResults; + +static void doDTPatternTest(UDateTimePatternGenerator* udtpg, + const UChar** skeletons, + DTPLocaleAndResults* localeAndResultsPtr); + +static void TestDateTimePatterns(void) { + const UChar* skeletons[kNumDateTimePatterns] = { + u"yMMMMEEEEdjmm", // full date, short time + u"yMMMMdjmm", // long date, short time + u"yMMMdjmm", // medium date, short time + u"yMdjmm" // short date, short time + }; + // The following tests some locales in which there are differences between the + // DateTimePatterns of various length styles. + DTPLocaleAndResults localeAndResults[] = { + { "en", { u"EEEE, MMMM d, y 'at' h:mm a", // long != medium + u"MMMM d, y 'at' h:mm a", + u"MMM d, y, h:mm a", + u"M/d/y, h:mm a" } }, + { "fr", { u"EEEE d MMMM y 'à' HH:mm", // medium != short + u"d MMMM y 'à' HH:mm", + u"d MMM y, HH:mm", + u"dd/MM/y HH:mm" } }, + { "ha", { u"EEEE d MMMM, y HH:mm", // full != long + u"d MMMM, y 'da' HH:mm", + u"d MMM, y, HH:mm", + u"y-MM-dd, HH:mm" } }, + { NULL, { NULL, NULL, NULL, NULL } } // terminator + }; + + const UChar* enDTPatterns[kNumDateTimePatterns] = { + u"{1} 'at' {0}", + u"{1} 'at' {0}", + u"{1}, {0}", + u"{1}, {0}" + }; + const UChar* modDTPatterns[kNumDateTimePatterns] = { + u"{1} _0_ {0}", + u"{1} _1_ {0}", + u"{1} _2_ {0}", + u"{1} _3_ {0}" + }; + DTPLocaleAndResults enModResults = { "en", { u"EEEE, MMMM d, y _0_ h:mm a", + u"MMMM d, y _1_ h:mm a", + u"MMM d, y _2_ h:mm a", + u"M/d/y _3_ h:mm a" } + }; + + // Test various locales with standard data + UErrorCode status; + UDateTimePatternGenerator* udtpg; + DTPLocaleAndResults* localeAndResultsPtr = localeAndResults; + for (; localeAndResultsPtr->localeID != NULL; localeAndResultsPtr++) { + status = U_ZERO_ERROR; + udtpg = udatpg_open(localeAndResultsPtr->localeID, &status); + if (U_FAILURE(status)) { + log_data_err("FAIL: udatpg_open for locale %s: %s", localeAndResultsPtr->localeID, myErrorName(status)); + } else { + doDTPatternTest(udtpg, skeletons, localeAndResultsPtr); + udatpg_close(udtpg); + } + } + // Test getting and modifying date-time combining patterns + status = U_ZERO_ERROR; + udtpg = udatpg_open("en", &status); + if (U_FAILURE(status)) { + log_data_err("FAIL: udatpg_open #2 for locale en: %s", myErrorName(status)); + } else { + char bExpect[64]; + char bGet[64]; + const UChar* uGet; + int32_t uGetLen, uExpectLen; + + // Test error: style out of range + status = U_ZERO_ERROR; + uGet = udatpg_getDateTimeFormatForStyle(udtpg, UDAT_NONE, &uGetLen, &status); + if (status != U_ILLEGAL_ARGUMENT_ERROR || uGetLen != 0 || uGet==NULL || *uGet!= 0) { + if (uGet==NULL) { + log_err("FAIL: udatpg_getDateTimeFormatForStyle with invalid style, expected U_ILLEGAL_ARGUMENT_ERROR " + "and ptr to empty string but got %s, len %d, ptr = NULL\n", myErrorName(status), uGetLen); + } else { + log_err("FAIL: udatpg_getDateTimeFormatForStyle with invalid style, expected U_ILLEGAL_ARGUMENT_ERROR " + "and ptr to empty string but got %s, len %d, *ptr = %04X\n", myErrorName(status), uGetLen, *uGet); + } + } + + // Test normal getting and setting + for (int32_t patStyle = 0; patStyle < kNumDateTimePatterns; patStyle++) { + status = U_ZERO_ERROR; + uExpectLen = u_strlen(enDTPatterns[patStyle]); + uGet = udatpg_getDateTimeFormatForStyle(udtpg, patStyle, &uGetLen, &status); + if (U_FAILURE(status)) { + log_err("FAIL udatpg_getDateTimeFormatForStyle %d (en before mod), get %s\n", patStyle, myErrorName(status)); + } else if (uGetLen != uExpectLen || u_strncmp(uGet, enDTPatterns[patStyle], uExpectLen) != 0) { + u_austrcpy(bExpect, enDTPatterns[patStyle]); + u_austrcpy(bGet, uGet); + log_err("ERROR udatpg_getDateTimeFormatForStyle %d (en before mod), expect %d:\"%s\", get %d:\"%s\"\n", + patStyle, uExpectLen, bExpect, uGetLen, bGet); + } + status = U_ZERO_ERROR; + udatpg_setDateTimeFormatForStyle(udtpg, patStyle, modDTPatterns[patStyle], -1, &status); + if (U_FAILURE(status)) { + log_err("FAIL udatpg_setDateTimeFormatForStyle %d (en), get %s\n", patStyle, myErrorName(status)); + } else { + uExpectLen = u_strlen(modDTPatterns[patStyle]); + uGet = udatpg_getDateTimeFormatForStyle(udtpg, patStyle, &uGetLen, &status); + if (U_FAILURE(status)) { + log_err("FAIL udatpg_getDateTimeFormatForStyle %d (en after mod), get %s\n", patStyle, myErrorName(status)); + } else if (uGetLen != uExpectLen || u_strncmp(uGet, modDTPatterns[patStyle], uExpectLen) != 0) { + u_austrcpy(bExpect, modDTPatterns[patStyle]); + u_austrcpy(bGet, uGet); + log_err("ERROR udatpg_getDateTimeFormatForStyle %d (en after mod), expect %d:\"%s\", get %d:\"%s\"\n", + patStyle, uExpectLen, bExpect, uGetLen, bGet); + } + } + } + // Test result of setting + doDTPatternTest(udtpg, skeletons, &enModResults); + // Test old get/set functions + uExpectLen = u_strlen(modDTPatterns[UDAT_MEDIUM]); + uGet = udatpg_getDateTimeFormat(udtpg, &uGetLen); + if (uGetLen != uExpectLen || u_strncmp(uGet, modDTPatterns[UDAT_MEDIUM], uExpectLen) != 0) { + u_austrcpy(bExpect, modDTPatterns[UDAT_MEDIUM]); + u_austrcpy(bGet, uGet); + log_err("ERROR udatpg_getDateTimeFormat (en after mod), expect %d:\"%s\", get %d:\"%s\"\n", + uExpectLen, bExpect, uGetLen, bGet); + } + udatpg_setDateTimeFormat(udtpg, modDTPatterns[UDAT_SHORT], -1); // set all dateTimePatterns to the short format + uExpectLen = u_strlen(modDTPatterns[UDAT_SHORT]); + u_austrcpy(bExpect, modDTPatterns[UDAT_SHORT]); + for (int32_t patStyle = 0; patStyle < kNumDateTimePatterns; patStyle++) { + status = U_ZERO_ERROR; + uGet = udatpg_getDateTimeFormatForStyle(udtpg, patStyle, &uGetLen, &status); + if (U_FAILURE(status)) { + log_err("FAIL udatpg_getDateTimeFormatForStyle %d (en after second mod), get %s\n", patStyle, myErrorName(status)); + } else if (uGetLen != uExpectLen || u_strncmp(uGet, modDTPatterns[UDAT_SHORT], uExpectLen) != 0) { + u_austrcpy(bGet, uGet); + log_err("ERROR udatpg_getDateTimeFormatForStyle %d (en after second mod), expect %d:\"%s\", get %d:\"%s\"\n", + patStyle, uExpectLen, bExpect, uGetLen, bGet); + } + } + + udatpg_close(udtpg); + } +} + +static void doDTPatternTest(UDateTimePatternGenerator* udtpg, + const UChar** skeletons, + DTPLocaleAndResults* localeAndResultsPtr) { + for (int32_t patStyle = 0; patStyle < kNumDateTimePatterns; patStyle++) { + UChar uGet[64]; + int32_t uGetLen, uExpectLen; + UErrorCode status = U_ZERO_ERROR; + uExpectLen = u_strlen(localeAndResultsPtr->expectPat[patStyle]); + uGetLen = udatpg_getBestPattern(udtpg, skeletons[patStyle], -1, uGet, 64, &status); + if (U_FAILURE(status)) { + log_err("FAIL udatpg_getBestPattern locale %s style %d: %s\n", localeAndResultsPtr->localeID, patStyle, myErrorName(status)); + } else if (uGetLen != uExpectLen || u_strncmp(uGet, localeAndResultsPtr->expectPat[patStyle], uExpectLen) != 0) { + char bExpect[64]; + char bGet[64]; + u_austrcpy(bExpect, localeAndResultsPtr->expectPat[patStyle]); + u_austrcpy(bGet, uGet); + log_err("ERROR udatpg_getBestPattern locale %s style %d, expect %d:\"%s\", get %d:\"%s\"\n", + localeAndResultsPtr->localeID, patStyle, uExpectLen, bExpect, uGetLen, bGet); + } + } +} + #endif diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/ulistfmttest.c b/Build/source/libs/icu/icu-src/source/test/cintltst/ulistfmttest.c index 7fe549f43ba..b0a1f6bc349 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/ulistfmttest.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/ulistfmttest.c @@ -20,6 +20,8 @@ static void TestUListFmt(void); static void TestUListFmtToValue(void); static void TestUListOpenStyled(void); +static void TestUList21871_A(void); +static void TestUList21871_B(void); void addUListFmtTest(TestNode** root); @@ -30,6 +32,8 @@ void addUListFmtTest(TestNode** root) TESTCASE(TestUListFmt); TESTCASE(TestUListFmtToValue); TESTCASE(TestUListOpenStyled); + TESTCASE(TestUList21871_A); + TESTCASE(TestUList21871_B); } static const UChar str0[] = { 0x41,0 }; /* "A" */ @@ -250,5 +254,103 @@ static void TestUListOpenStyled() { ulistfmt_closeResult(fl); } +#include <stdio.h> + +static void TestUList21871_A() { + UErrorCode status = U_ZERO_ERROR; + UListFormatter *fmt = ulistfmt_openForType("en", ULISTFMT_TYPE_AND, ULISTFMT_WIDTH_WIDE, &status); + assertSuccess("ulistfmt_openForType", &status); + + const UChar *strs[] = {u"A", u""}; + const int32_t lens[] = {1, 0}; + + UFormattedList *fl = ulistfmt_openResult(&status); + assertSuccess("ulistfmt_openResult", &status); + + ulistfmt_formatStringsToResult(fmt, strs, lens, 2, fl, &status); + assertSuccess("ulistfmt_formatStringsToResult", &status); + + const UFormattedValue *value = ulistfmt_resultAsValue(fl, &status); + assertSuccess("ulistfmt_resultAsValue", &status); + + { + int32_t len; + const UChar *str = ufmtval_getString(value, &len, &status); + assertUEquals("TEST ufmtval_getString", u"A and ", str); + } + + UConstrainedFieldPosition *fpos = ucfpos_open(&status); + assertSuccess("ucfpos_open", &status); + + ucfpos_constrainField(fpos, UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, &status); + assertSuccess("ucfpos_constrainField", &status); + + bool hasMore = ufmtval_nextPosition(value, fpos, &status); + assertSuccess("ufmtval_nextPosition", &status); + assertTrue("hasMore 1", hasMore); + + int32_t beginIndex, endIndex; + ucfpos_getIndexes(fpos, &beginIndex, &endIndex, &status); + assertSuccess("ufmtval_nextPosition", &status); + assertIntEquals("TEST beginIndex", 0, beginIndex); + assertIntEquals("TEST endIndex", 1, endIndex); + + hasMore = ufmtval_nextPosition(value, fpos, &status); + assertSuccess("ufmtval_nextPosition", &status); + assertTrue("hasMore 2", !hasMore); + + ucfpos_close(fpos); + ulistfmt_closeResult(fl); + ulistfmt_close(fmt); +} + +static void TestUList21871_B() { + UErrorCode status = U_ZERO_ERROR; + UListFormatter *fmt = ulistfmt_openForType("en", ULISTFMT_TYPE_AND, ULISTFMT_WIDTH_WIDE, &status); + assertSuccess("ulistfmt_openForType", &status); + + const UChar *strs[] = {u"", u"B"}; + const int32_t lens[] = {0, 1}; + + UFormattedList *fl = ulistfmt_openResult(&status); + assertSuccess("ulistfmt_openResult", &status); + + ulistfmt_formatStringsToResult(fmt, strs, lens, 2, fl, &status); + assertSuccess("ulistfmt_formatStringsToResult", &status); + + const UFormattedValue *value = ulistfmt_resultAsValue(fl, &status); + assertSuccess("ulistfmt_resultAsValue", &status); + + { + int32_t len; + const UChar *str = ufmtval_getString(value, &len, &status); + assertUEquals("TEST ufmtval_getString", u" and B", str); + } + + UConstrainedFieldPosition *fpos = ucfpos_open(&status); + assertSuccess("ucfpos_open", &status); + + ucfpos_constrainField(fpos, UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, &status); + assertSuccess("ucfpos_constrainField", &status); + + bool hasMore = ufmtval_nextPosition(value, fpos, &status); + assertSuccess("ufmtval_nextPosition", &status); + assertTrue("hasMore 1", hasMore); + + int32_t beginIndex, endIndex; + ucfpos_getIndexes(fpos, &beginIndex, &endIndex, &status); + assertSuccess("ucfpos_getIndexes", &status); + assertIntEquals("TEST beginIndex", 5, beginIndex); + assertIntEquals("TEST endIndex", 6, endIndex); + + hasMore = ufmtval_nextPosition(value, fpos, &status); + assertSuccess("ufmtval_nextPosition", &status); + assertTrue("hasMore 2", !hasMore); + + ucfpos_close(fpos); + ulistfmt_closeResult(fl); + ulistfmt_close(fmt); +} + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/utexttst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/utexttst.c index 8f3974c9041..6ee85c7057d 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/utexttst.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/utexttst.c @@ -292,6 +292,22 @@ static void TestAPI(void) { utext_close(uta); } - + { + // utext_equals() checks for the same type of text provider, + // same string pointer(!), and same index. + status = U_ZERO_ERROR; + const UChar *s = u"aßカ🚲"; + UText *ut1 = utext_openUChars(NULL, s, -1, &status); + UText *ut2 = utext_openUChars(NULL, s, 5, &status); + TEST_SUCCESS(status); + TEST_ASSERT(utext_equals(ut1, ut2)); + UChar32 c = utext_next32(ut1); + TEST_ASSERT(c == u'a'); + TEST_ASSERT(!utext_equals(ut1, ut2)); // indexes out of sync + c = utext_next32(ut2); + TEST_ASSERT(c == u'a'); + TEST_ASSERT(utext_equals(ut1, ut2)); // back in sync + utext_close(ut1); + utext_close(ut2); + } } - |