X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b331163bffd790ced0e88b73f44f86d49ccc48a5..4f1e1a09ce4daed860e35d359ce2fceccb0764e8:/icuSources/test/intltest/tmsgfmt.cpp diff --git a/icuSources/test/intltest/tmsgfmt.cpp b/icuSources/test/intltest/tmsgfmt.cpp index 939de8c6..2a8107b3 100644 --- a/icuSources/test/intltest/tmsgfmt.cpp +++ b/icuSources/test/intltest/tmsgfmt.cpp @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************** * COPYRIGHT: - * Copyright (c) 1997-2014, International Business Machines Corporation and + * Copyright (c) 1997-2016, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************** * File TMSGFMT.CPP @@ -30,6 +32,7 @@ #include "unicode/messagepattern.h" #include "unicode/selfmt.h" #include "unicode/gregocal.h" +#include "unicode/strenum.h" #include void @@ -67,6 +70,8 @@ TestMessageFormat::runIndexedTest(int32_t index, UBool exec, TESTCASE_AUTO(TestTrimArgumentName); TESTCASE_AUTO(TestSelectOrdinal); TESTCASE_AUTO(TestDecimals); + TESTCASE_AUTO(TestArgIsPrefixOfAnother); + TESTCASE_AUTO(TestMessageFormatNumberSkeleton); TESTCASE_AUTO_END; } @@ -138,7 +143,7 @@ void TestMessageFormat::testBug3() continue; } Formattable result; - FieldPosition pos(0); + FieldPosition pos(FieldPosition::DONT_CARE); buffer.remove(); form->format(myNumber, buffer, pos); success = U_ZERO_ERROR; @@ -160,7 +165,7 @@ void TestMessageFormat::testBug1() "1.0<=Arg<2.0", "2.0<-Arg"}; ChoiceFormat *cf = new ChoiceFormat(limit, formats, 3); - FieldPosition status(0); + FieldPosition status(FieldPosition::DONT_CARE); UnicodeString toAppendTo; cf->format((int32_t)1, toAppendTo, status); if (toAppendTo != "1.0<=Arg<2.0") { @@ -190,7 +195,7 @@ void TestMessageFormat::testBug2() } #if 0 -#if defined(_DEBUG) && U_IOSTREAM_SOURCE >= 199711 +#if defined(_DEBUG) //---------------------------------------------------- // console I/O //---------------------------------------------------- @@ -241,7 +246,7 @@ operator<<( IntlTest& stream, } return stream; } -#endif /* defined(_DEBUG) && U_IOSTREAM_SOURCE >= 199711 */ +#endif /* defined(_DEBUG) */ #endif void TestMessageFormat::PatternTest() @@ -318,7 +323,7 @@ void TestMessageFormat::PatternTest() //it_out << "Pat out: " << form->toPattern(buffer)); UnicodeString result; int32_t count = 4; - FieldPosition fieldpos(0); + FieldPosition fieldpos(FieldPosition::DONT_CARE); form->format(testArgs, count, result, fieldpos, success); if (U_FAILURE(success)) { dataerrln("MessageFormat failed test #3 - %s", u_errorName(success)); @@ -378,7 +383,7 @@ void TestMessageFormat::sample() UnicodeString abc("abc"); UnicodeString def("def"); Formattable testArgs1[] = { abc, def }; - FieldPosition fieldpos(0); + FieldPosition fieldpos(FieldPosition::DONT_CARE); assertEquals("format", "There are abc files on def", form->format(testArgs1, 2, buffer2, fieldpos, success)); @@ -777,6 +782,7 @@ void TestMessageFormat::testMsgFormatSelect(/* char* par */) err = U_ZERO_ERROR; //Create the MessageFormat with Plural format with embedded select format(nested pattern) MessageFormat* msgFmt5 = internalCreate(t5.unescape(), Locale("fr"),err,(char*)"From TestMessageFormat::TestSelectFormat create t5"); + // with no data the above should fail but it seems to construct an invalid MessageFormat with no reported error. See #13079 if (!U_FAILURE(err)) { //Arguments Formattable testArgs10[] = {"Kirti",(int32_t)6,"female"}; @@ -999,7 +1005,7 @@ void TestMessageFormat::testSetLocale() MessageFormat msg( formatStr, err); result = ""; - FieldPosition pos(0); + FieldPosition pos(FieldPosition::DONT_CARE); result = msg.format( arguments, 3, @@ -1058,7 +1064,7 @@ void TestMessageFormat::testFormat() { Formattable( UDate(8.71068e+011), Formattable::kIsDate ) }; - const int32_t ft_cnt = sizeof(ftarray) / sizeof(Formattable); + const int32_t ft_cnt = UPRV_LENGTHOF(ftarray); Formattable ft_arr( ftarray, ft_cnt ); Formattable* fmt = new Formattable(UDate(8.71068e+011), Formattable::kIsDate); @@ -1071,7 +1077,7 @@ void TestMessageFormat::testFormat() err = U_ZERO_ERROR; MessageFormat msg( formatStr, err); - FieldPosition fp(0); + FieldPosition fp(FieldPosition::DONT_CARE); result = ""; fp = 0; @@ -1403,7 +1409,7 @@ static void _testCopyConstructor2() UnicodeString formatStr("Hello World on {0,date,full}", ""); UnicodeString resultStr(" ", ""); UnicodeString result; - FieldPosition fp(0); + FieldPosition fp(FieldPosition::DONT_CARE); UDate d = Calendar::getNow(); const Formattable fargs( d, Formattable::kIsDate ); @@ -1486,7 +1492,7 @@ void TestMessageFormat::TestUnlimitedArgsAndSubformats() { Formattable("of course"), Formattable("Horace"), }; - const int32_t ARGS_LENGTH = sizeof(ARGS) / sizeof(ARGS[0]); + const int32_t ARGS_LENGTH = UPRV_LENGTHOF(ARGS); Formattable ARGS_OBJ(ARGS, ARGS_LENGTH); UnicodeString expected = @@ -1519,17 +1525,17 @@ void TestMessageFormat::TestRBNF(void) { // do not always parse, so do not include them "0", "1", "12", "100", "123", "1001", "123,456", "-17", }; - int32_t values_count = sizeof(values)/sizeof(values[0]); + int32_t values_count = UPRV_LENGTHOF(values); UnicodeString formats[] = { "There are {0,spellout} files to search.", "There are {0,spellout,%simplified} files to search.", "The bogus spellout {0,spellout,%BOGUS} files behaves like the default.", - "This is the {0,ordinal} file to search.", // TODO fix bug, ordinal does not parse + "This is the {0,ordinal} file to search.", "Searching this file will take {0,duration} to complete.", "Searching this file will take {0,duration,%with-words} to complete.", }; - int32_t formats_count = sizeof(formats)/sizeof(formats[0]); + int32_t formats_count = UPRV_LENGTHOF(formats); Formattable args[1]; @@ -1549,21 +1555,19 @@ void TestMessageFormat::TestRBNF(void) { if (U_FAILURE(ec)) { errln((UnicodeString)"Failed to parse test argument " + values[j]); } else { - FieldPosition fp(0); + FieldPosition fp(FieldPosition::DONT_CARE); UnicodeString result; fmt->format(args, 1, result, fp, ec); logln((UnicodeString)"value: " + toString(args[0]) + " --> " + result + UnicodeString(" ec: ") + u_errorName(ec)); - if (i != 3) { // TODO: fix this, for now skip ordinal parsing (format string at index 3) - int32_t count = 0; - Formattable* parseResult = fmt->parse(result, count, ec); - if (count != 1) { - errln((UnicodeString)"parse returned " + count + " args"); - } else if (parseResult[0] != args[0]) { - errln((UnicodeString)"parsed argument " + toString(parseResult[0]) + " != " + toString(args[0])); - } - delete []parseResult; + int32_t count = 0; + Formattable* parseResult = fmt->parse(result, count, ec); + if (count != 1) { + errln((UnicodeString)"parse returned " + count + " args"); + } else if (parseResult[0] != args[0]) { + errln((UnicodeString)"parsed argument " + toString(parseResult[0]) + " != " + toString(args[0])); } + delete []parseResult; } } delete fmt; @@ -1643,7 +1647,7 @@ void TestMessageFormat::TestCompatibleApostrophe() { } Formattable zero0[] = { (int32_t)0 }; - FieldPosition fieldpos(0); + FieldPosition fieldpos(FieldPosition::DONT_CARE); UnicodeString buffer1, buffer2; assertEquals("incompatible ICU MessageFormat compatibility-apostrophe behavior", "ab12'3'4''.yz", @@ -1702,7 +1706,7 @@ void TestMessageFormat::testAutoQuoteApostrophe(void) { "'} '{'}'", "'} '{'}''", "'} {{{''", "'} {{{'''", }; - int32_t pattern_count = sizeof(patterns)/sizeof(patterns[0]); + int32_t pattern_count = UPRV_LENGTHOF(patterns); for (int i = 0; i < pattern_count; i += 2) { UErrorCode status = U_ZERO_ERROR; @@ -1797,11 +1801,11 @@ void TestMessageFormat::testCoverage(void) { void TestMessageFormat::testGetFormatNames() { IcuTestErrorCode errorCode(*this, "testGetFormatNames"); MessageFormat msgfmt("Hello, {alice,number} {oops,date,full} {zip,spellout} World.", Locale::getRoot(), errorCode); - if(errorCode.logDataIfFailureAndReset("MessageFormat() failed")) { + if(errorCode.errDataIfFailureAndReset("MessageFormat() failed")) { return; } LocalPointer names(msgfmt.getFormatNames(errorCode)); - if(errorCode.logIfFailureAndReset("msgfmt.getFormatNames() failed")) { + if(errorCode.errIfFailureAndReset("msgfmt.getFormatNames() failed")) { return; } const UnicodeString *name; @@ -1843,11 +1847,11 @@ void TestMessageFormat::TestTrimArgumentName() { // ICU 4.8 allows and ignores white space around argument names and numbers. IcuTestErrorCode errorCode(*this, "TestTrimArgumentName"); MessageFormat m("a { 0 , number , '#,#'#.0 } z", Locale::getEnglish(), errorCode); - if (errorCode.logDataIfFailureAndReset("Unable to instantiate MessageFormat")) { + if (errorCode.errDataIfFailureAndReset("Unable to instantiate MessageFormat")) { return; } Formattable args[1] = { (int32_t)2 }; - FieldPosition ignore(0); + FieldPosition ignore(FieldPosition::DONT_CARE); UnicodeString result; assertEquals("trim-numbered-arg format() failed", "a #,#2.0 z", m.format(args, 1, result, ignore, errorCode)); @@ -1868,11 +1872,11 @@ void TestMessageFormat::TestSelectOrdinal() { "{0,plural,one{1 file}other{# files}}, " "{0,selectordinal,one{#st file}two{#nd file}few{#rd file}other{#th file}}", Locale::getEnglish(), errorCode); - if (errorCode.logDataIfFailureAndReset("Unable to instantiate MessageFormat")) { + if (errorCode.errDataIfFailureAndReset("Unable to instantiate MessageFormat")) { return; } Formattable args[1] = { (int32_t)21 }; - FieldPosition ignore(0); + FieldPosition ignore(FieldPosition::DONT_CARE); UnicodeString result; assertEquals("plural-and-ordinal format(21) failed", "21 files, 21st file", m.format(args, 1, result, ignore, errorCode), TRUE); @@ -1889,7 +1893,7 @@ void TestMessageFormat::TestSelectOrdinal() { assertEquals("plural-and-ordinal format(3) failed", "3 files, 3rd file", m.format(args, 1, result.remove(), ignore, errorCode), TRUE); - errorCode.logDataIfFailureAndReset(""); + errorCode.errDataIfFailureAndReset(""); } void TestMessageFormat::TestDecimals() { @@ -1963,4 +1967,65 @@ void TestMessageFormat::TestDecimals() { errorCode.reset(); } +void TestMessageFormat::TestArgIsPrefixOfAnother() { + IcuTestErrorCode errorCode(*this, "TestArgIsPrefixOfAnother"); + // Ticket #11952 + MessageFormat mf1("{0,select,a{A}ab{AB}abc{ABC}other{?}}", Locale::getEnglish(), errorCode); + Formattable args[3]; + FieldPosition ignore; + UnicodeString result; + args[0].setString("a"); + assertEquals("a", "A", mf1.format(args, 1, result, ignore, errorCode)); + args[0].setString("ab"); + assertEquals("ab", "AB", mf1.format(args, 1, result.remove(), ignore, errorCode)); + args[0].setString("abc"); + assertEquals("abc", "ABC", mf1.format(args, 1, result.remove(), ignore, errorCode)); + + // Ticket #12172 + MessageFormat mf2("{a} {aa} {aaa}", Locale::getEnglish(), errorCode); + UnicodeString argNames[3] = { "a", "aa", "aaa" }; + args[0].setString("A"); + args[1].setString("AB"); + args[2].setString("ABC"); + assertEquals("a aa aaa", "A AB ABC", mf2.format(argNames, args, 3, result.remove(), errorCode)); + + // Ticket #12172 + MessageFormat mf3("{aa} {aaa}", Locale::getEnglish(), errorCode); + assertEquals("aa aaa", "AB ABC", mf3.format(argNames + 1, args + 1, 2, result.remove(), errorCode)); +} + +void TestMessageFormat::TestMessageFormatNumberSkeleton() { + IcuTestErrorCode status(*this, "TestMessageFormatNumberSkeleton"); + + static const struct TestCase { + const char16_t* messagePattern; + const char* localeName; + double arg; + const char16_t* expected; + } cases[] = { + { u"{0,number,::percent}", "en", 50, u"50%" }, + { u"{0,number,::percent scale/100}", "en", 0.5, u"50%" }, + { u"{0,number, :: percent scale/100 }", "en", 0.5, u"50%" }, + { u"{0,number,::currency/USD}", "en", 23, u"$23.00" }, + { u"{0,number,::precision-integer}", "en", 514.23, u"514" }, + { u"{0,number,::.000}", "en", 514.23, u"514.230" }, + { u"{0,number,::.}", "en", 514.23, u"514" }, + { u"{0,number,::}", "fr", 514.23, u"514,23" }, + { u"Cost: {0,number,::currency/EUR}.", "en", 4.3, u"Cost: €4.30." }, + { u"{0,number,'::'0.00}", "en", 50, u"::50.00" }, // pattern literal + }; + + for (auto& cas : cases) { + status.setScope(cas.messagePattern); + MessageFormat msgf(cas.messagePattern, cas.localeName, status); + UnicodeString sb; + FieldPosition fpos(0); + Formattable argsArray[] = {{cas.arg}}; + Formattable args(argsArray, 1); + msgf.format(args, sb, status); + + assertEquals(cas.messagePattern, cas.expected, sb); + } +} + #endif /* #if !UCONFIG_NO_FORMATTING */