summaryrefslogtreecommitdiff
path: root/Build/source/libs/icu/icu-xetex/test/intltest/tmsgfmt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/icu/icu-xetex/test/intltest/tmsgfmt.cpp')
-rw-r--r--Build/source/libs/icu/icu-xetex/test/intltest/tmsgfmt.cpp1256
1 files changed, 1256 insertions, 0 deletions
diff --git a/Build/source/libs/icu/icu-xetex/test/intltest/tmsgfmt.cpp b/Build/source/libs/icu/icu-xetex/test/intltest/tmsgfmt.cpp
new file mode 100644
index 00000000000..aef0179f167
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/test/intltest/tmsgfmt.cpp
@@ -0,0 +1,1256 @@
+/********************************************************************
+ * Copyright (c) 1997-2007, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ ********************************************************************
+ * File TMSGFMT.CPP
+ *
+ * Modification History:
+ *
+ * Date Name Description
+ * 03/24/97 helena Converted from Java.
+ * 07/11/97 helena Updated to work on AIX.
+ * 08/04/97 jfitz Updated to intltest
+ *******************************************************************/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "tmsgfmt.h"
+
+#include "unicode/format.h"
+#include "unicode/decimfmt.h"
+#include "unicode/locid.h"
+#include "unicode/msgfmt.h"
+#include "unicode/numfmt.h"
+#include "unicode/choicfmt.h"
+#include "unicode/gregocal.h"
+#include <stdio.h>
+
+void
+TestMessageFormat::runIndexedTest(int32_t index, UBool exec,
+ const char* &name, char* /*par*/) {
+ switch (index) {
+ TESTCASE(0,testBug1);
+ TESTCASE(1,testBug2);
+ TESTCASE(2,sample);
+ TESTCASE(3,PatternTest);
+ TESTCASE(4,testStaticFormat);
+ TESTCASE(5,testSimpleFormat);
+ TESTCASE(6,testMsgFormatChoice);
+ TESTCASE(7,testCopyConstructor);
+ TESTCASE(8,testAssignment);
+ TESTCASE(9,testClone);
+ TESTCASE(10,testEquals);
+ TESTCASE(11,testNotEquals);
+ TESTCASE(12,testSetLocale);
+ TESTCASE(13,testFormat);
+ TESTCASE(14,testParse);
+ TESTCASE(15,testAdopt);
+ TESTCASE(16,testCopyConstructor2);
+ TESTCASE(17,TestUnlimitedArgsAndSubformats);
+ TESTCASE(18,TestRBNF);
+ TESTCASE(19,TestTurkishCasing);
+ TESTCASE(20,testAutoQuoteApostrophe);
+ default: name = ""; break;
+ }
+}
+
+void TestMessageFormat::testBug3()
+{
+ double myNumber = -123456;
+ DecimalFormat *form = 0;
+ Locale locale[] = {
+ Locale("ar", "", ""),
+ Locale("be", "", ""),
+ Locale("bg", "", ""),
+ Locale("ca", "", ""),
+ Locale("cs", "", ""),
+ Locale("da", "", ""),
+ Locale("de", "", ""),
+ Locale("de", "AT", ""),
+ Locale("de", "CH", ""),
+ Locale("el", "", ""), // 10
+ Locale("en", "CA", ""),
+ Locale("en", "GB", ""),
+ Locale("en", "IE", ""),
+ Locale("en", "US", ""),
+ Locale("es", "", ""),
+ Locale("et", "", ""),
+ Locale("fi", "", ""),
+ Locale("fr", "", ""),
+ Locale("fr", "BE", ""),
+ Locale("fr", "CA", ""), // 20
+ Locale("fr", "CH", ""),
+ Locale("he", "", ""),
+ Locale("hr", "", ""),
+ Locale("hu", "", ""),
+ Locale("is", "", ""),
+ Locale("it", "", ""),
+ Locale("it", "CH", ""),
+ Locale("ja", "", ""),
+ Locale("ko", "", ""),
+ Locale("lt", "", ""), // 30
+ Locale("lv", "", ""),
+ Locale("mk", "", ""),
+ Locale("nl", "", ""),
+ Locale("nl", "BE", ""),
+ Locale("no", "", ""),
+ Locale("pl", "", ""),
+ Locale("pt", "", ""),
+ Locale("ro", "", ""),
+ Locale("ru", "", ""),
+ Locale("sh", "", ""), // 40
+ Locale("sk", "", ""),
+ Locale("sl", "", ""),
+ Locale("sq", "", ""),
+ Locale("sr", "", ""),
+ Locale("sv", "", ""),
+ Locale("tr", "", ""),
+ Locale("uk", "", ""),
+ Locale("zh", "", ""),
+ Locale("zh", "TW", "") // 49
+ };
+ int32_t i;
+ for (i= 0; i < 49; i++) {
+ UnicodeString buffer;
+ logln(locale[i].getDisplayName(buffer));
+ UErrorCode success = U_ZERO_ERROR;
+// form = (DecimalFormat*)NumberFormat::createCurrencyInstance(locale[i], success);
+ form = (DecimalFormat*)NumberFormat::createInstance(locale[i], success);
+ if (U_FAILURE(success)) {
+ errln("Err: Number Format ");
+ logln("Number format creation failed.");
+ continue;
+ }
+ Formattable result;
+ FieldPosition pos(0);
+ buffer.remove();
+ form->format(myNumber, buffer, pos);
+ success = U_ZERO_ERROR;
+ ParsePosition parsePos;
+ form->parse(buffer, result, parsePos);
+ logln(UnicodeString(" -> ") /* + << dec*/ + toString(result) + UnicodeString("[supposed output for result]"));
+ if (U_FAILURE(success)) {
+ errln("Err: Number Format parse");
+ logln("Number format parse failed.");
+ }
+ delete form;
+ }
+}
+
+void TestMessageFormat::testBug1()
+{
+ const double limit[] = {0.0, 1.0, 2.0};
+ const UnicodeString formats[] = {"0.0<=Arg<1.0",
+ "1.0<=Arg<2.0",
+ "2.0<-Arg"};
+ ChoiceFormat *cf = new ChoiceFormat(limit, formats, 3);
+ FieldPosition status(0);
+ UnicodeString toAppendTo;
+ cf->format((int32_t)1, toAppendTo, status);
+ if (toAppendTo != "1.0<=Arg<2.0") {
+ errln("ChoiceFormat cmp in testBug1");
+ }
+ logln(toAppendTo);
+ delete cf;
+}
+
+void TestMessageFormat::testBug2()
+{
+ UErrorCode status = U_ZERO_ERROR;
+ UnicodeString result;
+ // {sfb} use double format in pattern, so result will match (not strictly necessary)
+ const UnicodeString pattern = "There {0,choice,0.0#are no files|1.0#is one file|1.0<are {0, number} files} on disk {1}. ";
+ logln("The input pattern : " + pattern);
+ MessageFormat *fmt = new MessageFormat(pattern, status);
+ if (U_FAILURE(status)) {
+ errln("MessageFormat pattern creation failed.");
+ return;
+ }
+ logln("The output pattern is : " + fmt->toPattern(result));
+ if (pattern != result) {
+ errln("MessageFormat::toPattern() failed.");
+ }
+ delete fmt;
+}
+
+#if 0
+#if defined(_DEBUG) && U_IOSTREAM_SOURCE!=0
+//----------------------------------------------------
+// console I/O
+//----------------------------------------------------
+
+#if U_IOSTREAM_SOURCE >= 199711
+# include <iostream>
+ std::ostream& operator<<(std::ostream& stream, const Formattable& obj);
+#elif U_IOSTREAM_SOURCE >= 198506
+# include <iostream.h>
+ ostream& operator<<(ostream& stream, const Formattable& obj);
+#endif
+
+#include "unicode/datefmt.h"
+#include <stdlib.h>
+#include <string.h>
+
+IntlTest&
+operator<<( IntlTest& stream,
+ const Formattable& obj)
+{
+ static DateFormat *defDateFormat = 0;
+
+ UnicodeString buffer;
+ switch(obj.getType()) {
+ case Formattable::kDate :
+ if (defDateFormat == 0) {
+ defDateFormat = DateFormat::createInstance();
+ }
+ defDateFormat->format(obj.getDate(), buffer);
+ stream << buffer;
+ break;
+ case Formattable::kDouble :
+ char convert[20];
+ sprintf( convert, "%lf", obj.getDouble() );
+ stream << convert << "D";
+ break;
+ case Formattable::kLong :
+ stream << obj.getLong() << "L";
+ break;
+ case Formattable::kString:
+ stream << "\"" << obj.getString(buffer) << "\"";
+ break;
+ case Formattable::kArray:
+ int32_t i, count;
+ const Formattable* array;
+ array = obj.getArray(count);
+ stream << "[";
+ for (i=0; i<count; ++i) stream << array[i] << ( (i==(count-1)) ? "" : ", " );
+ stream << "]";
+ break;
+ default:
+ stream << "INVALID_Formattable";
+ }
+ return stream;
+}
+#endif /* defined(_DEBUG) && U_IOSTREAM_SOURCE!=0 */
+#endif
+
+void TestMessageFormat::PatternTest()
+{
+ Formattable testArgs[] = {
+ Formattable(double(1)), Formattable(double(3456)),
+ Formattable("Disk"), Formattable(UDate((int32_t)1000000000L), Formattable::kIsDate)
+ };
+ UnicodeString testCases[] = {
+ "Quotes '', '{', 'a' {0} '{0}'",
+ "Quotes '', '{', 'a' {0,number} '{0}'",
+ "'{'1,number,'#',##} {1,number,'#',##}",
+ "There are {1} files on {2} at {3}.",
+ "On {2}, there are {1} files, with {0,number,currency}.",
+ "'{1,number,percent}', {1,number,percent},",
+ "'{1,date,full}', {1,date,full},",
+ "'{3,date,full}', {3,date,full},",
+ "'{1,number,#,##}' {1,number,#,##}",
+ };
+
+ UnicodeString testResultPatterns[] = {
+ "Quotes '', '{', a {0} '{'0}",
+ "Quotes '', '{', a {0,number} '{'0}",
+ "'{'1,number,#,##} {1,number,'#'#,##}",
+ "There are {1} files on {2} at {3}.",
+ "On {2}, there are {1} files, with {0,number,currency}.",
+ "'{'1,number,percent}, {1,number,percent},",
+ "'{'1,date,full}, {1,date,full},",
+ "'{'3,date,full}, {3,date,full},",
+ "'{'1,number,#,##} {1,number,#,##}"
+ };
+
+ UnicodeString testResultStrings[] = {
+ "Quotes ', {, a 1 {0}",
+ "Quotes ', {, a 1 {0}",
+ "{1,number,#,##} #34,56",
+ "There are 3,456 files on Disk at 1/12/70 5:46 AM.",
+ "On Disk, there are 3,456 files, with $1.00.",
+ "{1,number,percent}, 345,600%,",
+ "{1,date,full}, Wednesday, December 31, 1969,",
+ "{3,date,full}, Monday, January 12, 1970,",
+ "{1,number,#,##} 34,56"
+ };
+
+
+ for (int32_t i = 0; i < 9; ++i) {
+ //it_out << "\nPat in: " << testCases[i]);
+
+ MessageFormat *form = 0;
+ UErrorCode success = U_ZERO_ERROR;
+ UnicodeString buffer;
+ form = new MessageFormat(testCases[i], Locale::getUS(), success);
+ if (U_FAILURE(success)) {
+ errln("MessageFormat creation failed.#1");
+ logln(((UnicodeString)"MessageFormat for ") + testCases[i] + " creation failed.\n");
+ continue;
+ }
+ if (form->toPattern(buffer) != testResultPatterns[i]) {
+ errln(UnicodeString("TestMessageFormat::PatternTest failed test #2, i = ") + i);
+ //form->toPattern(buffer);
+ errln(((UnicodeString)" Orig: ") + testCases[i]);
+ errln(((UnicodeString)" Exp: ") + testResultPatterns[i]);
+ errln(((UnicodeString)" Got: ") + buffer);
+ }
+
+ //it_out << "Pat out: " << form->toPattern(buffer));
+ UnicodeString result;
+ int32_t count = 4;
+ FieldPosition fieldpos(0);
+ form->format(testArgs, count, result, fieldpos, success);
+ if (U_FAILURE(success)) {
+ errln("MessageFormat failed test #3");
+ logln("TestMessageFormat::PatternTest failed test #3");
+ continue;
+ }
+ if (result != testResultStrings[i]) {
+ errln("TestMessageFormat::PatternTest failed test #4");
+ logln("TestMessageFormat::PatternTest failed #4.");
+ logln(UnicodeString(" Result: ") + result );
+ logln(UnicodeString(" Expected: ") + testResultStrings[i] );
+ }
+
+
+ //it_out << "Result: " << result);
+#if 0
+ /* TODO: Look at this test and see if this is still a valid test */
+ logln("---------------- test parse ----------------");
+
+ form->toPattern(buffer);
+ logln("MSG pattern for parse: " + buffer);
+
+ int32_t parseCount = 0;
+ Formattable* values = form->parse(result, parseCount, success);
+ if (U_FAILURE(success)) {
+ errln("MessageFormat failed test #5");
+ logln(UnicodeString("MessageFormat failed test #5 with error code ")+(int32_t)success);
+ } else if (parseCount != count) {
+ errln("MSG count not %d as expected. Got %d", count, parseCount);
+ }
+ UBool failed = FALSE;
+ for (int32_t j = 0; j < parseCount; ++j) {
+ if (values == 0 || testArgs[j] != values[j]) {
+ errln(((UnicodeString)"MSG testargs[") + j + "]: " + toString(testArgs[j]));
+ errln(((UnicodeString)"MSG values[") + j + "] : " + toString(values[j]));
+ failed = TRUE;
+ }
+ }
+ if (failed)
+ errln("MessageFormat failed test #6");
+#endif
+ delete form;
+ }
+}
+
+void TestMessageFormat::sample()
+{
+ MessageFormat *form = 0;
+ UnicodeString buffer1, buffer2;
+ UErrorCode success = U_ZERO_ERROR;
+ form = new MessageFormat("There are {0} files on {1}", success);
+ if (U_FAILURE(success)) {
+ errln("Err: Message format creation failed");
+ logln("Sample message format creation failed.");
+ return;
+ }
+ UnicodeString abc("abc");
+ UnicodeString def("def");
+ Formattable testArgs1[] = { abc, def };
+ FieldPosition fieldpos(0);
+ assertEquals("format",
+ "There are abc files on def",
+ form->format(testArgs1, 2, buffer2, fieldpos, success));
+ assertSuccess("format", success);
+ delete form;
+}
+
+void TestMessageFormat::testStaticFormat()
+{
+ UErrorCode err = U_ZERO_ERROR;
+ Formattable arguments[] = {
+ (int32_t)7,
+ Formattable(UDate(8.71068e+011), Formattable::kIsDate),
+ "a disturbance in the Force"
+ };
+
+ UnicodeString result;
+ result = MessageFormat::format(
+ "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
+ arguments,
+ 3,
+ result,
+ err);
+
+ if (U_FAILURE(err)) {
+ errln("TestMessageFormat::testStaticFormat #1");
+ logln(UnicodeString("TestMessageFormat::testStaticFormat failed test #1 with error code ")+(int32_t)err);
+ return;
+ }
+
+ const UnicodeString expected(
+ "At 12:20:00 PM on Aug 8, 1997, there was a disturbance in the Force on planet 7.", "");
+ if (result != expected) {
+ errln("TestMessageFormat::testStaticFormat failed on test");
+ logln( UnicodeString(" Result: ") + result );
+ logln( UnicodeString(" Expected: ") + expected );
+ }
+}
+
+/* When the default locale is tr, make sure that the pattern can still be parsed. */
+void TestMessageFormat::TestTurkishCasing()
+{
+ UErrorCode err = U_ZERO_ERROR;
+ Locale saveDefaultLocale;
+ Locale::setDefault( Locale("tr"), err );
+
+ Formattable arguments[] = {
+ (int32_t)7,
+ Formattable(UDate(8.71068e+011), Formattable::kIsDate),
+ "a disturbance in the Force"
+ };
+
+ UnicodeString result;
+ result = MessageFormat::format(
+ "At {1,TIME} on {1,DATE,SHORT}, there was {2} on planet {0,NUMBER,INTEGER}.",
+ arguments,
+ 3,
+ result,
+ err);
+
+ if (U_FAILURE(err)) {
+ errln("TestTurkishCasing #1 with error code %s", u_errorName(err));
+ return;
+ }
+
+ const UnicodeString expected(
+ "At 12:20:00 on 08.08.1997, there was a disturbance in the Force on planet 7.", "");
+ if (result != expected) {
+ errln("TestTurkishCasing failed on test");
+ errln( UnicodeString(" Result: ") + result );
+ errln( UnicodeString(" Expected: ") + expected );
+ }
+ Locale::setDefault( saveDefaultLocale, err );
+}
+
+void TestMessageFormat::testSimpleFormat(/* char* par */)
+{
+ logln("running TestMessageFormat::testSimpleFormat");
+
+ UErrorCode err = U_ZERO_ERROR;
+
+ Formattable testArgs1[] = {(int32_t)0, "MyDisk"};
+ Formattable testArgs2[] = {(int32_t)1, "MyDisk"};
+ Formattable testArgs3[] = {(int32_t)12, "MyDisk"};
+
+ MessageFormat* form = new MessageFormat(
+ "The disk \"{1}\" contains {0} file(s).", err);
+
+ UnicodeString string;
+ FieldPosition ignore(FieldPosition::DONT_CARE);
+ form->format(testArgs1, 2, string, ignore, err);
+ if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 0 file(s).") {
+ errln(UnicodeString("TestMessageFormat::testSimpleFormat failed on test #1"));
+ }
+
+ ignore.setField(FieldPosition::DONT_CARE);
+ string.remove();
+ form->format(testArgs2, 2, string, ignore, err);
+ if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 1 file(s).") {
+ logln(string);
+ errln(UnicodeString("TestMessageFormat::testSimpleFormat failed on test #2")+string);
+ }
+
+ ignore.setField(FieldPosition::DONT_CARE);
+ string.remove();
+ form->format(testArgs3, 2, string, ignore, err);
+ if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 12 file(s).") {
+ errln(UnicodeString("TestMessageFormat::testSimpleFormat failed on test #3")+string);
+ }
+
+ delete form;
+ }
+
+void TestMessageFormat::testMsgFormatChoice(/* char* par */)
+{
+ logln("running TestMessageFormat::testMsgFormatChoice");
+
+ UErrorCode err = U_ZERO_ERROR;
+
+ MessageFormat* form = new MessageFormat("The disk \"{1}\" contains {0}.", err);
+ double filelimits[] = {0,1,2};
+ UnicodeString filepart[] = {"no files","one file","{0,number} files"};
+ ChoiceFormat* fileform = new ChoiceFormat(filelimits, filepart, 3);
+ form->setFormat(1,*fileform); // NOT zero, see below
+ //is the format adopted?
+
+ FieldPosition ignore(FieldPosition::DONT_CARE);
+ UnicodeString string;
+ Formattable testArgs1[] = {(int32_t)0, "MyDisk"};
+ form->format(testArgs1, 2, string, ignore, err);
+ if (string != "The disk \"MyDisk\" contains no files.") {
+ errln("TestMessageFormat::testMsgFormatChoice failed on test #1");
+ }
+
+ ignore.setField(FieldPosition::DONT_CARE);
+ string.remove();
+ Formattable testArgs2[] = {(int32_t)1, "MyDisk"};
+ form->format(testArgs2, 2, string, ignore, err);
+ if (string != "The disk \"MyDisk\" contains one file.") {
+ errln("TestMessageFormat::testMsgFormatChoice failed on test #2");
+ }
+
+ ignore.setField(FieldPosition::DONT_CARE);
+ string.remove();
+ Formattable testArgs3[] = {(int32_t)1273, "MyDisk"};
+ form->format(testArgs3, 2, string, ignore, err);
+ if (string != "The disk \"MyDisk\" contains 1,273 files.") {
+ errln("TestMessageFormat::testMsgFormatChoice failed on test #3");
+ }
+
+ delete form;
+ delete fileform;
+}
+
+
+//---------------------------------
+// API Tests
+//---------------------------------
+
+void TestMessageFormat::testCopyConstructor()
+{
+ UErrorCode success = U_ZERO_ERROR;
+ MessageFormat *x = new MessageFormat("There are {0} files on {1}", success);
+ MessageFormat *z = new MessageFormat("There are {0} files on {1} created", success);
+ MessageFormat *y = 0;
+ y = new MessageFormat(*x);
+ if ( (*x == *y) &&
+ (*x != *z) &&
+ (*y != *z) )
+ logln("First test (operator ==): Passed!");
+ else {
+ errln("TestMessageFormat::testCopyConstructor failed #1");
+ logln("First test (operator ==): Failed!");
+ }
+ if ( ((*x == *y) && (*y == *x)) &&
+ ((*x != *z) && (*z != *x)) &&
+ ((*y != *z) && (*z != *y)) )
+ logln("Second test (equals): Passed!");
+ else {
+ errln("TestMessageFormat::testCopyConstructor failed #2");
+ logln("Second test (equals): Failed!");
+ }
+
+ delete x;
+ delete y;
+ delete z;
+}
+
+
+void TestMessageFormat::testAssignment()
+{
+ UErrorCode success = U_ZERO_ERROR;
+ MessageFormat *x = new MessageFormat("There are {0} files on {1}", success);
+ MessageFormat *z = new MessageFormat("There are {0} files on {1} created", success);
+ MessageFormat *y = new MessageFormat("There are {0} files on {1} created", success);
+ *y = *x;
+ if ( (*x == *y) &&
+ (*x != *z) &&
+ (*y != *z) )
+ logln("First test (operator ==): Passed!");
+ else {
+ errln( "TestMessageFormat::testAssignment failed #1");
+ logln("First test (operator ==): Failed!");
+ }
+ if ( ((*x == *y) && (*y == *x)) &&
+ ((*x != *z) && (*z != *x)) &&
+ ((*y != *z) && (*z != *y)) )
+ logln("Second test (equals): Passed!");
+ else {
+ errln("TestMessageFormat::testAssignment failed #2");
+ logln("Second test (equals): Failed!");
+ }
+
+ delete x;
+ delete y;
+ delete z;
+}
+
+void TestMessageFormat::testClone()
+{
+ UErrorCode success = U_ZERO_ERROR;
+ MessageFormat *x = new MessageFormat("There are {0} files on {1}", success);
+ MessageFormat *z = new MessageFormat("There are {0} files on {1} created", success);
+ MessageFormat *y = 0;
+ y = (MessageFormat*)x->clone();
+ if ( (*x == *y) &&
+ (*x != *z) &&
+ (*y != *z) )
+ logln("First test (operator ==): Passed!");
+ else {
+ errln("TestMessageFormat::testClone failed #1");
+ logln("First test (operator ==): Failed!");
+ }
+ if ( ((*x == *y) && (*y == *x)) &&
+ ((*x != *z) && (*z != *x)) &&
+ ((*y != *z) && (*z != *y)) )
+ logln("Second test (equals): Passed!");
+ else {
+ errln("TestMessageFormat::testClone failed #2");
+ logln("Second test (equals): Failed!");
+ }
+
+ delete x;
+ delete y;
+ delete z;
+}
+
+void TestMessageFormat::testEquals()
+{
+ UErrorCode success = U_ZERO_ERROR;
+ MessageFormat x("There are {0} files on {1}", success);
+ MessageFormat y("There are {0} files on {1}", success);
+ if (!(x == y)) {
+ errln( "TestMessageFormat::testEquals failed #1");
+ logln("First test (operator ==): Failed!");
+ }
+
+}
+
+void TestMessageFormat::testNotEquals()
+{
+ UErrorCode success = U_ZERO_ERROR;
+ MessageFormat x("There are {0} files on {1}", success);
+ MessageFormat y(x);
+ y.setLocale(Locale("fr"));
+ if (!(x != y)) {
+ errln( "TestMessageFormat::testEquals failed #1");
+ logln("First test (operator !=): Failed!");
+ }
+ y = x;
+ y.applyPattern("There are {0} files on {1} the disk", success);
+ if (!(x != y)) {
+ errln( "TestMessageFormat::testEquals failed #1");
+ logln("Second test (operator !=): Failed!");
+ }
+}
+
+
+void TestMessageFormat::testSetLocale()
+{
+ UErrorCode err = U_ZERO_ERROR;
+ GregorianCalendar cal(err);
+ Formattable arguments[] = {
+ 456.83,
+ Formattable(UDate(8.71068e+011), Formattable::kIsDate),
+ "deposit"
+ };
+
+ UnicodeString result;
+
+ //UnicodeString formatStr = "At {1,time} on {1,date}, you made a {2} of {0,number,currency}.";
+ UnicodeString formatStr = "At <time> on {1,date}, you made a {2} of {0,number,currency}.";
+ // {sfb} to get $, would need Locale::US, not Locale::ENGLISH
+ // Just use unlocalized currency symbol.
+ //UnicodeString compareStrEng = "At <time> on Aug 8, 1997, you made a deposit of $456.83.";
+ UnicodeString compareStrEng = "At <time> on Aug 8, 1997, you made a deposit of ";
+ compareStrEng += (UChar) 0x00a4;
+ compareStrEng += "456.83.";
+ // {sfb} to get DM, would need Locale::GERMANY, not Locale::GERMAN
+ // Just use unlocalized currency symbol.
+ //UnicodeString compareStrGer = "At <time> on 08.08.1997, you made a deposit of 456,83 DM.";
+ UnicodeString compareStrGer = "At <time> on 08.08.1997, you made a deposit of ";
+ compareStrGer += "456,83 ";
+ compareStrGer += (UChar) 0x00a4;
+ compareStrGer += ".";
+
+ MessageFormat msg( formatStr, err);
+ result = "";
+ FieldPosition pos(0);
+ result = msg.format(
+ arguments,
+ 3,
+ result,
+ pos,
+ err);
+
+ logln(result);
+ if (result != compareStrEng) {
+ errln("*** MSG format err.");
+ }
+
+ msg.setLocale(Locale::getEnglish());
+ UBool getLocale_ok = TRUE;
+ if (msg.getLocale() != Locale::getEnglish()) {
+ errln("*** MSG getLocal err.");
+ getLocale_ok = FALSE;
+ }
+
+ msg.setLocale(Locale::getGerman());
+
+ if (msg.getLocale() != Locale::getGerman()) {
+ errln("*** MSG getLocal err.");
+ getLocale_ok = FALSE;
+ }
+
+ msg.applyPattern( formatStr, err);
+
+ pos.setField(0);
+ result = "";
+ result = msg.format(
+ arguments,
+ 3,
+ result,
+ pos,
+ err);
+
+ logln(result);
+ if (result == compareStrGer) {
+ logln("MSG setLocale tested.");
+ }else{
+ errln( "*** MSG setLocale err.");
+ }
+
+ if (getLocale_ok) {
+ logln("MSG getLocale tested.");
+ }
+}
+
+void TestMessageFormat::testFormat()
+{
+ UErrorCode err = U_ZERO_ERROR;
+ GregorianCalendar cal(err);
+
+ const Formattable ftarray[] =
+ {
+ Formattable( UDate(8.71068e+011), Formattable::kIsDate )
+ };
+ const int32_t ft_cnt = sizeof(ftarray) / sizeof(Formattable);
+ Formattable ft_arr( ftarray, ft_cnt );
+
+ Formattable* fmt = new Formattable(UDate(8.71068e+011), Formattable::kIsDate);
+
+ UnicodeString result;
+
+ //UnicodeString formatStr = "At {1,time} on {1,date}, you made a {2} of {0,number,currency}.";
+ UnicodeString formatStr = "On {0,date}, it began.";
+ UnicodeString compareStr = "On Aug 8, 1997, it began.";
+
+ err = U_ZERO_ERROR;
+ MessageFormat msg( formatStr, err);
+ FieldPosition fp(0);
+
+ result = "";
+ fp = 0;
+ result = msg.format(
+ *fmt,
+ result,
+ //FieldPosition(0),
+ fp,
+ err);
+
+ if (err != U_ILLEGAL_ARGUMENT_ERROR) {
+ errln("*** MSG format without expected error code.");
+ }
+ err = U_ZERO_ERROR;
+
+ result = "";
+ fp = 0;
+ result = msg.format(
+ ft_arr,
+ result,
+ //FieldPosition(0),
+ fp,
+ err);
+
+ logln("MSG format( Formattable&, ... ) expected:" + compareStr);
+ logln("MSG format( Formattable&, ... ) result:" + result);
+ if (result != compareStr) {
+ errln("*** MSG format( Formattable&, .... ) err.");
+ }else{
+ logln("MSG format( Formattable&, ... ) tested.");
+ }
+
+ delete fmt;
+
+}
+
+void TestMessageFormat::testParse()
+{
+ UErrorCode err = U_ZERO_ERROR;
+ int32_t count;
+ UnicodeString msgFormatString = "{0} =sep= {1}";
+ MessageFormat msg( msgFormatString, err);
+ UnicodeString source = "abc =sep= def";
+ UnicodeString tmp1, tmp2;
+
+ Formattable* fmt_arr = msg.parse( source, count, err );
+ if (U_FAILURE(err) || (!fmt_arr)) {
+ errln("*** MSG parse (ustring, count, err) error.");
+ }else{
+ logln("MSG parse -- count: %d", count);
+ if (count != 2) {
+ errln("*** MSG parse (ustring, count, err) count err.");
+ }else{
+ if ((fmt_arr[0].getType() == Formattable::kString)
+ && (fmt_arr[1].getType() == Formattable::kString)
+ && (fmt_arr[0].getString(tmp1) == "abc")
+ && (fmt_arr[1].getString(tmp2) == "def")) {
+ logln("MSG parse (ustring, count, err) tested.");
+ }else{
+ errln("*** MSG parse (ustring, count, err) result err.");
+ }
+ }
+ }
+ delete[] fmt_arr;
+
+ ParsePosition pp(0);
+
+ fmt_arr = msg.parse( source, pp, count );
+ if ((pp == 0) || (!fmt_arr)) {
+ errln("*** MSG parse (ustring, parsepos., count) error.");
+ }else{
+ logln("MSG parse -- count: %d", count);
+ if (count != 2) {
+ errln("*** MSG parse (ustring, parsepos., count) count err.");
+ }else{
+ if ((fmt_arr[0].getType() == Formattable::kString)
+ && (fmt_arr[1].getType() == Formattable::kString)
+ && (fmt_arr[0].getString(tmp1) == "abc")
+ && (fmt_arr[1].getString(tmp2) == "def")) {
+ logln("MSG parse (ustring, parsepos., count) tested.");
+ }else{
+ errln("*** MSG parse (ustring, parsepos., count) result err.");
+ }
+ }
+ }
+ delete[] fmt_arr;
+
+ pp = 0;
+ Formattable fmta;
+
+ msg.parseObject( source, fmta, pp );
+ if (pp == 0) {
+ errln("*** MSG parse (ustring, Formattable, parsepos ) error.");
+ }else{
+ logln("MSG parse -- count: %d", count);
+ fmta.getArray(count);
+ if (count != 2) {
+ errln("*** MSG parse (ustring, Formattable, parsepos ) count err.");
+ }else{
+ if ((fmta[0].getType() == Formattable::kString)
+ && (fmta[1].getType() == Formattable::kString)
+ && (fmta[0].getString(tmp1) == "abc")
+ && (fmta[1].getString(tmp2) == "def")) {
+ logln("MSG parse (ustring, Formattable, parsepos ) tested.");
+ }else{
+ errln("*** MSG parse (ustring, Formattable, parsepos ) result err.");
+ }
+ }
+ }
+}
+
+
+void TestMessageFormat::testAdopt()
+{
+ UErrorCode err = U_ZERO_ERROR;
+
+ UnicodeString formatStr("{0,date},{1},{2,number}", "");
+ UnicodeString formatStrChange("{0,number},{1,number},{2,date}", "");
+ err = U_ZERO_ERROR;
+ MessageFormat msg( formatStr, err);
+ MessageFormat msgCmp( formatStr, err);
+ int32_t count, countCmp;
+ const Format** formats = msg.getFormats(count);
+ const Format** formatsCmp = msgCmp.getFormats(countCmp);
+ const Format** formatsChg = 0;
+ const Format** formatsAct = 0;
+ int32_t countAct;
+ const Format* a;
+ const Format* b;
+ UnicodeString patCmp;
+ UnicodeString patAct;
+ Format** formatsToAdopt;
+
+ if (!formats || !formatsCmp || (count <= 0) || (count != countCmp)) {
+ errln("Error getting Formats");
+ return;
+ }
+
+ int32_t i;
+
+ for (i = 0; i < count; i++) {
+ a = formats[i];
+ b = formatsCmp[i];
+ if ((a != NULL) && (b != NULL)) {
+ if (*a != *b) {
+ errln("a != b");
+ return;
+ }
+ }else if ((a != NULL) || (b != NULL)) {
+ errln("(a != NULL) || (b != NULL)");
+ return;
+ }
+ }
+
+ msg.applyPattern( formatStrChange, err ); //set msg formats to something different
+ int32_t countChg;
+ formatsChg = msg.getFormats(countChg); // tested function
+ if (!formatsChg || (countChg != count)) {
+ errln("Error getting Formats");
+ return;
+ }
+
+ UBool diff;
+ diff = TRUE;
+ for (i = 0; i < count; i++) {
+ a = formatsChg[i];
+ b = formatsCmp[i];
+ if ((a != NULL) && (b != NULL)) {
+ if (*a == *b) {
+ logln("formatsChg == formatsCmp at index %d", i);
+ diff = FALSE;
+ }
+ }
+ }
+ if (!diff) {
+ errln("*** MSG getFormats diff err.");
+ return;
+ }
+
+ logln("MSG getFormats tested.");
+
+ msg.setFormats( formatsCmp, countCmp ); //tested function
+
+ formatsAct = msg.getFormats(countAct);
+ if (!formatsAct || (countAct <=0) || (countAct != countCmp)) {
+ errln("Error getting Formats");
+ return;
+ }
+
+ assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove()));
+ assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove()));
+
+ for (i = 0; i < countAct; i++) {
+ a = formatsAct[i];
+ b = formatsCmp[i];
+ if ((a != NULL) && (b != NULL)) {
+ if (*a != *b) {
+ logln("formatsAct != formatsCmp at index %d", i);
+ errln("a != b");
+ return;
+ }
+ }else if ((a != NULL) || (b != NULL)) {
+ errln("(a != NULL) || (b != NULL)");
+ return;
+ }
+ }
+ logln("MSG setFormats tested.");
+
+ //----
+
+ msg.applyPattern( formatStrChange, err ); //set msg formats to something different
+
+ formatsToAdopt = new Format* [countCmp];
+ if (!formatsToAdopt) {
+ errln("memory allocation error");
+ return;
+ }
+
+ for (i = 0; i < countCmp; i++) {
+ if (formatsCmp[i] == NULL) {
+ formatsToAdopt[i] = NULL;
+ }else{
+ formatsToAdopt[i] = formatsCmp[i]->clone();
+ if (!formatsToAdopt[i]) {
+ errln("Can't clone format at index %d", i);
+ return;
+ }
+ }
+ }
+ msg.adoptFormats( formatsToAdopt, countCmp ); // function to test
+ delete[] formatsToAdopt;
+
+ assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove()));
+ assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove()));
+
+ formatsAct = msg.getFormats(countAct);
+ if (!formatsAct || (countAct <=0) || (countAct != countCmp)) {
+ errln("Error getting Formats");
+ return;
+ }
+
+ for (i = 0; i < countAct; i++) {
+ a = formatsAct[i];
+ b = formatsCmp[i];
+ if ((a != NULL) && (b != NULL)) {
+ if (*a != *b) {
+ errln("a != b");
+ return;
+ }
+ }else if ((a != NULL) || (b != NULL)) {
+ errln("(a != NULL) || (b != NULL)");
+ return;
+ }
+ }
+ logln("MSG adoptFormats tested.");
+
+ //---- adoptFormat
+
+ msg.applyPattern( formatStrChange, err ); //set msg formats to something different
+
+ formatsToAdopt = new Format* [countCmp];
+ if (!formatsToAdopt) {
+ errln("memory allocation error");
+ return;
+ }
+
+ for (i = 0; i < countCmp; i++) {
+ if (formatsCmp[i] == NULL) {
+ formatsToAdopt[i] = NULL;
+ }else{
+ formatsToAdopt[i] = formatsCmp[i]->clone();
+ if (!formatsToAdopt[i]) {
+ errln("Can't clone format at index %d", i);
+ return;
+ }
+ }
+ }
+
+ for ( i = 0; i < countCmp; i++ ) {
+ msg.adoptFormat( i, formatsToAdopt[i] ); // function to test
+ }
+ delete[] formatsToAdopt; // array itself not needed in this case;
+
+ assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove()));
+ assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove()));
+
+ formatsAct = msg.getFormats(countAct);
+ if (!formatsAct || (countAct <=0) || (countAct != countCmp)) {
+ errln("Error getting Formats");
+ return;
+ }
+
+ for (i = 0; i < countAct; i++) {
+ a = formatsAct[i];
+ b = formatsCmp[i];
+ if ((a != NULL) && (b != NULL)) {
+ if (*a != *b) {
+ errln("a != b");
+ return;
+ }
+ }else if ((a != NULL) || (b != NULL)) {
+ errln("(a != NULL) || (b != NULL)");
+ return;
+ }
+ }
+ logln("MSG adoptFormat tested.");
+}
+
+// This test is a regression test for a fixed bug in the copy constructor.
+// It is kept as a global function rather than as a method since the test depends on memory values.
+// (At least before the bug was fixed, whether it showed up or not depended on memory contents,
+// which is probably why it didn't show up in the regular test for the copy constructor.)
+// For this reason, the test isn't changed even though it contains function calls whose results are
+// not tested and had no problems. Actually, the test failed by *crashing*.
+static void _testCopyConstructor2()
+{
+ UErrorCode status = U_ZERO_ERROR;
+ UnicodeString formatStr("Hello World on {0,date,full}", "");
+ UnicodeString resultStr(" ", "");
+ UnicodeString result;
+ FieldPosition fp(0);
+ UDate d = Calendar::getNow();
+ const Formattable fargs( d, Formattable::kIsDate );
+
+ MessageFormat* fmt1 = new MessageFormat( formatStr, status );
+ MessageFormat* fmt2 = new MessageFormat( *fmt1 );
+ MessageFormat* fmt3;
+ MessageFormat* fmt4;
+
+ if (fmt1 == NULL) it_err("testCopyConstructor2: (fmt1 != NULL)");
+
+ result = fmt1->format( &fargs, 1, resultStr, fp, status );
+
+ if (fmt2 == NULL) it_err("testCopyConstructor2: (fmt2 != NULL)");
+
+ fmt3 = (MessageFormat*) fmt1->clone();
+ fmt4 = (MessageFormat*) fmt2->clone();
+
+ if (fmt3 == NULL) it_err("testCopyConstructor2: (fmt3 != NULL)");
+ if (fmt4 == NULL) it_err("testCopyConstructor2: (fmt4 != NULL)");
+
+ result = fmt1->format( &fargs, 1, resultStr, fp, status );
+ result = fmt2->format( &fargs, 1, resultStr, fp, status );
+ result = fmt3->format( &fargs, 1, resultStr, fp, status );
+ result = fmt4->format( &fargs, 1, resultStr, fp, status );
+ delete fmt1;
+ delete fmt2;
+ delete fmt3;
+ delete fmt4;
+}
+
+void TestMessageFormat::testCopyConstructor2() {
+ _testCopyConstructor2();
+}
+
+/**
+ * Verify that MessageFormat accomodates more than 10 arguments and
+ * more than 10 subformats.
+ */
+void TestMessageFormat::TestUnlimitedArgsAndSubformats() {
+ UErrorCode ec = U_ZERO_ERROR;
+ const UnicodeString pattern =
+ "On {0,date} (aka {0,date,short}, aka {0,date,long}) "
+ "at {0,time} (aka {0,time,short}, aka {0,time,long}) "
+ "there were {1,number} werjes "
+ "(a {3,number,percent} increase over {2,number}) "
+ "despite the {4}''s efforts "
+ "and to delight of {5}, {6}, {7}, {8}, {9}, and {10} {11}.";
+ MessageFormat msg(pattern, ec);
+ if (U_FAILURE(ec)) {
+ errln("FAIL: constructor failed");
+ return;
+ }
+
+ const Formattable ARGS[] = {
+ Formattable(UDate(1e13), Formattable::kIsDate),
+ Formattable((int32_t)1303),
+ Formattable((int32_t)1202),
+ Formattable(1303.0/1202 - 1),
+ Formattable("Glimmung"),
+ Formattable("the printers"),
+ Formattable("Nick"),
+ Formattable("his father"),
+ Formattable("his mother"),
+ Formattable("the spiddles"),
+ Formattable("of course"),
+ Formattable("Horace"),
+ };
+ const int32_t ARGS_LENGTH = sizeof(ARGS) / sizeof(ARGS[0]);
+ Formattable ARGS_OBJ(ARGS, ARGS_LENGTH);
+
+ UnicodeString expected =
+ "On Nov 20, 2286 (aka 11/20/86, aka November 20, 2286) "
+ "at 9:46:40 AM (aka 9:46 AM, aka 9:46:40 AM PST) "
+ "there were 1,303 werjes "
+ "(a 8% increase over 1,202) "
+ "despite the Glimmung's efforts "
+ "and to delight of the printers, Nick, his father, "
+ "his mother, the spiddles, and of course Horace.";
+ UnicodeString result;
+ msg.format(ARGS_OBJ, result, ec);
+ if (result == expected) {
+ logln(result);
+ } else {
+ errln((UnicodeString)"FAIL: Got " + result +
+ ", expected " + expected);
+ }
+}
+
+// test RBNF extensions to message format
+void TestMessageFormat::TestRBNF(void) {
+ // WARNING: this depends on the RBNF formats for en_US
+ Locale locale("en", "US", "");
+
+ UErrorCode ec = U_ZERO_ERROR;
+
+ UnicodeString values[] = {
+ // decimal values do not format completely for ordinal or duration, and
+ // 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]);
+
+ 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
+ "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]);
+
+ Formattable args[1];
+
+ NumberFormat* numFmt = NumberFormat::createInstance(locale, ec);
+ if (U_FAILURE(ec)) {
+ dataerrln("Error calling NumberFormat::createInstance()");
+ return;
+ }
+
+ for (int i = 0; i < formats_count; ++i) {
+ MessageFormat* fmt = new MessageFormat(formats[i], locale, ec);
+ logln((UnicodeString)"Testing format pattern: '" + formats[i] + "'");
+
+ for (int j = 0; j < values_count; ++j) {
+ ec = U_ZERO_ERROR;
+ numFmt->parse(values[j], args[0], ec);
+ if (U_FAILURE(ec)) {
+ errln((UnicodeString)"Failed to parse test argument " + values[j]);
+ } else {
+ FieldPosition fp(0);
+ 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;
+ }
+ }
+ }
+ delete fmt;
+ }
+ delete numFmt;
+}
+
+void TestMessageFormat::testAutoQuoteApostrophe(void) {
+ const char* patterns[] = { // pattern, expected pattern
+ "'", "''",
+ "''", "''",
+ "'{", "'{'",
+ "' {", "'' {",
+ "'a", "''a",
+ "'{'a", "'{'a",
+ "'{a'", "'{a'",
+ "'{}", "'{}'",
+ "{'", "{'",
+ "{'a", "{'a",
+ "{'a{}'a}'a", "{'a{}'a}''a",
+ "'}'", "'}'",
+ "'} '{'}'", "'} '{'}''",
+ "'} {{{''", "'} {{{'''",
+ };
+ int32_t pattern_count = sizeof(patterns)/sizeof(patterns[0]);
+
+ for (int i = 0; i < pattern_count; i += 2) {
+ UErrorCode status = U_ZERO_ERROR;
+ UnicodeString result = MessageFormat::autoQuoteApostrophe(patterns[i], status);
+ UnicodeString target(patterns[i+1]);
+ if (target != result) {
+ const int BUF2_LEN = 64;
+ char buf[256];
+ char buf2[BUF2_LEN];
+ int32_t len = result.extract(0, result.length(), buf2, BUF2_LEN);
+ if (len >= BUF2_LEN) {
+ buf2[BUF2_LEN-1] = 0;
+ }
+ sprintf(buf, "[%2d] test \"%s\": target (\"%s\") != result (\"%s\")\n", i/2, patterns[i], patterns[i+1], buf2);
+ errln(buf);
+ }
+ }
+}
+
+#endif /* #if !UCONFIG_NO_FORMATTING */