]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/intltest/tmsgfmt.cpp
ICU-400.39.tar.gz
[apple/icu.git] / icuSources / test / intltest / tmsgfmt.cpp
1 /********************************************************************
2 * Copyright (c) 1997-2008, International Business Machines
3 * Corporation and others. All Rights Reserved.
4 ********************************************************************
5 * File TMSGFMT.CPP
6 *
7 * Modification History:
8 *
9 * Date Name Description
10 * 03/24/97 helena Converted from Java.
11 * 07/11/97 helena Updated to work on AIX.
12 * 08/04/97 jfitz Updated to intltest
13 *******************************************************************/
14
15 #include "unicode/utypes.h"
16
17 #if !UCONFIG_NO_FORMATTING
18
19 #include "tmsgfmt.h"
20
21 #include "unicode/format.h"
22 #include "unicode/decimfmt.h"
23 #include "unicode/locid.h"
24 #include "unicode/msgfmt.h"
25 #include "unicode/numfmt.h"
26 #include "unicode/choicfmt.h"
27 #include "unicode/gregocal.h"
28 #include <stdio.h>
29
30 void
31 TestMessageFormat::runIndexedTest(int32_t index, UBool exec,
32 const char* &name, char* /*par*/) {
33 switch (index) {
34 TESTCASE(0,testBug1);
35 TESTCASE(1,testBug2);
36 TESTCASE(2,sample);
37 TESTCASE(3,PatternTest);
38 TESTCASE(4,testStaticFormat);
39 TESTCASE(5,testSimpleFormat);
40 TESTCASE(6,testMsgFormatChoice);
41 TESTCASE(7,testCopyConstructor);
42 TESTCASE(8,testAssignment);
43 TESTCASE(9,testClone);
44 TESTCASE(10,testEquals);
45 TESTCASE(11,testNotEquals);
46 TESTCASE(12,testSetLocale);
47 TESTCASE(13,testFormat);
48 TESTCASE(14,testParse);
49 TESTCASE(15,testAdopt);
50 TESTCASE(16,testCopyConstructor2);
51 TESTCASE(17,TestUnlimitedArgsAndSubformats);
52 TESTCASE(18,TestRBNF);
53 TESTCASE(19,TestTurkishCasing);
54 TESTCASE(20,testAutoQuoteApostrophe);
55 TESTCASE(21,testMsgFormatPlural);
56 default: name = ""; break;
57 }
58 }
59
60 void TestMessageFormat::testBug3()
61 {
62 double myNumber = -123456;
63 DecimalFormat *form = 0;
64 Locale locale[] = {
65 Locale("ar", "", ""),
66 Locale("be", "", ""),
67 Locale("bg", "", ""),
68 Locale("ca", "", ""),
69 Locale("cs", "", ""),
70 Locale("da", "", ""),
71 Locale("de", "", ""),
72 Locale("de", "AT", ""),
73 Locale("de", "CH", ""),
74 Locale("el", "", ""), // 10
75 Locale("en", "CA", ""),
76 Locale("en", "GB", ""),
77 Locale("en", "IE", ""),
78 Locale("en", "US", ""),
79 Locale("es", "", ""),
80 Locale("et", "", ""),
81 Locale("fi", "", ""),
82 Locale("fr", "", ""),
83 Locale("fr", "BE", ""),
84 Locale("fr", "CA", ""), // 20
85 Locale("fr", "CH", ""),
86 Locale("he", "", ""),
87 Locale("hr", "", ""),
88 Locale("hu", "", ""),
89 Locale("is", "", ""),
90 Locale("it", "", ""),
91 Locale("it", "CH", ""),
92 Locale("ja", "", ""),
93 Locale("ko", "", ""),
94 Locale("lt", "", ""), // 30
95 Locale("lv", "", ""),
96 Locale("mk", "", ""),
97 Locale("nl", "", ""),
98 Locale("nl", "BE", ""),
99 Locale("no", "", ""),
100 Locale("pl", "", ""),
101 Locale("pt", "", ""),
102 Locale("ro", "", ""),
103 Locale("ru", "", ""),
104 Locale("sh", "", ""), // 40
105 Locale("sk", "", ""),
106 Locale("sl", "", ""),
107 Locale("sq", "", ""),
108 Locale("sr", "", ""),
109 Locale("sv", "", ""),
110 Locale("tr", "", ""),
111 Locale("uk", "", ""),
112 Locale("zh", "", ""),
113 Locale("zh", "TW", "") // 49
114 };
115 int32_t i;
116 for (i= 0; i < 49; i++) {
117 UnicodeString buffer;
118 logln(locale[i].getDisplayName(buffer));
119 UErrorCode success = U_ZERO_ERROR;
120 // form = (DecimalFormat*)NumberFormat::createCurrencyInstance(locale[i], success);
121 form = (DecimalFormat*)NumberFormat::createInstance(locale[i], success);
122 if (U_FAILURE(success)) {
123 errln("Err: Number Format ");
124 logln("Number format creation failed.");
125 continue;
126 }
127 Formattable result;
128 FieldPosition pos(0);
129 buffer.remove();
130 form->format(myNumber, buffer, pos);
131 success = U_ZERO_ERROR;
132 ParsePosition parsePos;
133 form->parse(buffer, result, parsePos);
134 logln(UnicodeString(" -> ") /* + << dec*/ + toString(result) + UnicodeString("[supposed output for result]"));
135 if (U_FAILURE(success)) {
136 errln("Err: Number Format parse");
137 logln("Number format parse failed.");
138 }
139 delete form;
140 }
141 }
142
143 void TestMessageFormat::testBug1()
144 {
145 const double limit[] = {0.0, 1.0, 2.0};
146 const UnicodeString formats[] = {"0.0<=Arg<1.0",
147 "1.0<=Arg<2.0",
148 "2.0<-Arg"};
149 ChoiceFormat *cf = new ChoiceFormat(limit, formats, 3);
150 FieldPosition status(0);
151 UnicodeString toAppendTo;
152 cf->format((int32_t)1, toAppendTo, status);
153 if (toAppendTo != "1.0<=Arg<2.0") {
154 errln("ChoiceFormat cmp in testBug1");
155 }
156 logln(toAppendTo);
157 delete cf;
158 }
159
160 void TestMessageFormat::testBug2()
161 {
162 UErrorCode status = U_ZERO_ERROR;
163 UnicodeString result;
164 // {sfb} use double format in pattern, so result will match (not strictly necessary)
165 const UnicodeString pattern = "There {0,choice,0#are no files|1#is one file|1<are {0, number} files} on disk {1}. ";
166 logln("The input pattern : " + pattern);
167 MessageFormat *fmt = new MessageFormat(pattern, status);
168 if (U_FAILURE(status)) {
169 errln("MessageFormat pattern creation failed.");
170 return;
171 }
172 logln("The output pattern is : " + fmt->toPattern(result));
173 if (pattern != result) {
174 errln("MessageFormat::toPattern() failed.");
175 }
176 delete fmt;
177 }
178
179 #if 0
180 #if defined(_DEBUG) && U_IOSTREAM_SOURCE!=0
181 //----------------------------------------------------
182 // console I/O
183 //----------------------------------------------------
184
185 #if U_IOSTREAM_SOURCE >= 199711
186 # include <iostream>
187 std::ostream& operator<<(std::ostream& stream, const Formattable& obj);
188 #elif U_IOSTREAM_SOURCE >= 198506
189 # include <iostream.h>
190 ostream& operator<<(ostream& stream, const Formattable& obj);
191 #endif
192
193 #include "unicode/datefmt.h"
194 #include <stdlib.h>
195 #include <string.h>
196
197 IntlTest&
198 operator<<( IntlTest& stream,
199 const Formattable& obj)
200 {
201 static DateFormat *defDateFormat = 0;
202
203 UnicodeString buffer;
204 switch(obj.getType()) {
205 case Formattable::kDate :
206 if (defDateFormat == 0) {
207 defDateFormat = DateFormat::createInstance();
208 }
209 defDateFormat->format(obj.getDate(), buffer);
210 stream << buffer;
211 break;
212 case Formattable::kDouble :
213 char convert[20];
214 sprintf( convert, "%lf", obj.getDouble() );
215 stream << convert << "D";
216 break;
217 case Formattable::kLong :
218 stream << obj.getLong() << "L";
219 break;
220 case Formattable::kString:
221 stream << "\"" << obj.getString(buffer) << "\"";
222 break;
223 case Formattable::kArray:
224 int32_t i, count;
225 const Formattable* array;
226 array = obj.getArray(count);
227 stream << "[";
228 for (i=0; i<count; ++i) stream << array[i] << ( (i==(count-1)) ? "" : ", " );
229 stream << "]";
230 break;
231 default:
232 stream << "INVALID_Formattable";
233 }
234 return stream;
235 }
236 #endif /* defined(_DEBUG) && U_IOSTREAM_SOURCE!=0 */
237 #endif
238
239 void TestMessageFormat::PatternTest()
240 {
241 Formattable testArgs[] = {
242 Formattable(double(1)), Formattable(double(3456)),
243 Formattable("Disk"), Formattable(UDate((int32_t)1000000000L), Formattable::kIsDate)
244 };
245 UnicodeString testCases[] = {
246 "Quotes '', '{', 'a' {0} '{0}'",
247 "Quotes '', '{', 'a' {0,number} '{0}'",
248 "'{'1,number,'#',##} {1,number,'#',##}",
249 "There are {1} files on {2} at {3}.",
250 "On {2}, there are {1} files, with {0,number,currency}.",
251 "'{1,number,percent}', {1,number,percent},",
252 "'{1,date,full}', {1,date,full},",
253 "'{3,date,full}', {3,date,full},",
254 "'{1,number,#,##}' {1,number,#,##}",
255 };
256
257 UnicodeString testResultPatterns[] = {
258 "Quotes '', '{', a {0} '{'0}",
259 "Quotes '', '{', a {0,number} '{'0}",
260 "'{'1,number,#,##} {1,number,'#'#,##}",
261 "There are {1} files on {2} at {3}.",
262 "On {2}, there are {1} files, with {0,number,currency}.",
263 "'{'1,number,percent}, {1,number,percent},",
264 "'{'1,date,full}, {1,date,full},",
265 "'{'3,date,full}, {3,date,full},",
266 "'{'1,number,#,##} {1,number,#,##}"
267 };
268
269 UnicodeString testResultStrings[] = {
270 "Quotes ', {, a 1 {0}",
271 "Quotes ', {, a 1 {0}",
272 "{1,number,#,##} #34,56",
273 "There are 3,456 files on Disk at 1/12/70 5:46 AM.",
274 "On Disk, there are 3,456 files, with $1.00.",
275 "{1,number,percent}, 345,600%,",
276 "{1,date,full}, Wednesday, December 31, 1969,",
277 "{3,date,full}, Monday, January 12, 1970,",
278 "{1,number,#,##} 34,56"
279 };
280
281
282 for (int32_t i = 0; i < 9; ++i) {
283 //it_out << "\nPat in: " << testCases[i]);
284
285 MessageFormat *form = 0;
286 UErrorCode success = U_ZERO_ERROR;
287 UnicodeString buffer;
288 form = new MessageFormat(testCases[i], Locale::getUS(), success);
289 if (U_FAILURE(success)) {
290 errln("MessageFormat creation failed.#1");
291 logln(((UnicodeString)"MessageFormat for ") + testCases[i] + " creation failed.\n");
292 continue;
293 }
294 if (form->toPattern(buffer) != testResultPatterns[i]) {
295 errln(UnicodeString("TestMessageFormat::PatternTest failed test #2, i = ") + i);
296 //form->toPattern(buffer);
297 errln(((UnicodeString)" Orig: ") + testCases[i]);
298 errln(((UnicodeString)" Exp: ") + testResultPatterns[i]);
299 errln(((UnicodeString)" Got: ") + buffer);
300 }
301
302 //it_out << "Pat out: " << form->toPattern(buffer));
303 UnicodeString result;
304 int32_t count = 4;
305 FieldPosition fieldpos(0);
306 form->format(testArgs, count, result, fieldpos, success);
307 if (U_FAILURE(success)) {
308 errln("MessageFormat failed test #3");
309 logln("TestMessageFormat::PatternTest failed test #3");
310 continue;
311 }
312 if (result != testResultStrings[i]) {
313 errln("TestMessageFormat::PatternTest failed test #4");
314 logln("TestMessageFormat::PatternTest failed #4.");
315 logln(UnicodeString(" Result: ") + result );
316 logln(UnicodeString(" Expected: ") + testResultStrings[i] );
317 }
318
319
320 //it_out << "Result: " << result);
321 #if 0
322 /* TODO: Look at this test and see if this is still a valid test */
323 logln("---------------- test parse ----------------");
324
325 form->toPattern(buffer);
326 logln("MSG pattern for parse: " + buffer);
327
328 int32_t parseCount = 0;
329 Formattable* values = form->parse(result, parseCount, success);
330 if (U_FAILURE(success)) {
331 errln("MessageFormat failed test #5");
332 logln(UnicodeString("MessageFormat failed test #5 with error code ")+(int32_t)success);
333 } else if (parseCount != count) {
334 errln("MSG count not %d as expected. Got %d", count, parseCount);
335 }
336 UBool failed = FALSE;
337 for (int32_t j = 0; j < parseCount; ++j) {
338 if (values == 0 || testArgs[j] != values[j]) {
339 errln(((UnicodeString)"MSG testargs[") + j + "]: " + toString(testArgs[j]));
340 errln(((UnicodeString)"MSG values[") + j + "] : " + toString(values[j]));
341 failed = TRUE;
342 }
343 }
344 if (failed)
345 errln("MessageFormat failed test #6");
346 #endif
347 delete form;
348 }
349 }
350
351 void TestMessageFormat::sample()
352 {
353 MessageFormat *form = 0;
354 UnicodeString buffer1, buffer2;
355 UErrorCode success = U_ZERO_ERROR;
356 form = new MessageFormat("There are {0} files on {1}", success);
357 if (U_FAILURE(success)) {
358 errln("Err: Message format creation failed");
359 logln("Sample message format creation failed.");
360 return;
361 }
362 UnicodeString abc("abc");
363 UnicodeString def("def");
364 Formattable testArgs1[] = { abc, def };
365 FieldPosition fieldpos(0);
366 assertEquals("format",
367 "There are abc files on def",
368 form->format(testArgs1, 2, buffer2, fieldpos, success));
369 assertSuccess("format", success);
370 delete form;
371 }
372
373 void TestMessageFormat::testStaticFormat()
374 {
375 UErrorCode err = U_ZERO_ERROR;
376 Formattable arguments[] = {
377 (int32_t)7,
378 Formattable(UDate(8.71068e+011), Formattable::kIsDate),
379 "a disturbance in the Force"
380 };
381
382 UnicodeString result;
383 result = MessageFormat::format(
384 "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
385 arguments,
386 3,
387 result,
388 err);
389
390 if (U_FAILURE(err)) {
391 errln("TestMessageFormat::testStaticFormat #1");
392 logln(UnicodeString("TestMessageFormat::testStaticFormat failed test #1 with error code ")+(int32_t)err);
393 return;
394 }
395
396 const UnicodeString expected(
397 "At 12:20:00 PM on Aug 8, 1997, there was a disturbance in the Force on planet 7.", "");
398 if (result != expected) {
399 errln("TestMessageFormat::testStaticFormat failed on test");
400 logln( UnicodeString(" Result: ") + result );
401 logln( UnicodeString(" Expected: ") + expected );
402 }
403 }
404
405 /* When the default locale is tr, make sure that the pattern can still be parsed. */
406 void TestMessageFormat::TestTurkishCasing()
407 {
408 UErrorCode err = U_ZERO_ERROR;
409 Locale saveDefaultLocale;
410 Locale::setDefault( Locale("tr"), err );
411
412 Formattable arguments[] = {
413 (int32_t)7,
414 Formattable(UDate(8.71068e+011), Formattable::kIsDate),
415 "a disturbance in the Force"
416 };
417
418 UnicodeString result;
419 result = MessageFormat::format(
420 "At {1,TIME} on {1,DATE,SHORT}, there was {2} on planet {0,NUMBER,INTEGER}.",
421 arguments,
422 3,
423 result,
424 err);
425
426 if (U_FAILURE(err)) {
427 errln("TestTurkishCasing #1 with error code %s", u_errorName(err));
428 return;
429 }
430
431 const UnicodeString expected(
432 "At 12:20:00 on 08.08.1997, there was a disturbance in the Force on planet 7.", "");
433 if (result != expected) {
434 errln("TestTurkishCasing failed on test");
435 errln( UnicodeString(" Result: ") + result );
436 errln( UnicodeString(" Expected: ") + expected );
437 }
438 Locale::setDefault( saveDefaultLocale, err );
439 }
440
441 void TestMessageFormat::testSimpleFormat(/* char* par */)
442 {
443 logln("running TestMessageFormat::testSimpleFormat");
444
445 UErrorCode err = U_ZERO_ERROR;
446
447 Formattable testArgs1[] = {(int32_t)0, "MyDisk"};
448 Formattable testArgs2[] = {(int32_t)1, "MyDisk"};
449 Formattable testArgs3[] = {(int32_t)12, "MyDisk"};
450
451 MessageFormat* form = new MessageFormat(
452 "The disk \"{1}\" contains {0} file(s).", err);
453
454 UnicodeString string;
455 FieldPosition ignore(FieldPosition::DONT_CARE);
456 form->format(testArgs1, 2, string, ignore, err);
457 if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 0 file(s).") {
458 errln(UnicodeString("TestMessageFormat::testSimpleFormat failed on test #1"));
459 }
460
461 ignore.setField(FieldPosition::DONT_CARE);
462 string.remove();
463 form->format(testArgs2, 2, string, ignore, err);
464 if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 1 file(s).") {
465 logln(string);
466 errln(UnicodeString("TestMessageFormat::testSimpleFormat failed on test #2")+string);
467 }
468
469 ignore.setField(FieldPosition::DONT_CARE);
470 string.remove();
471 form->format(testArgs3, 2, string, ignore, err);
472 if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 12 file(s).") {
473 errln(UnicodeString("TestMessageFormat::testSimpleFormat failed on test #3")+string);
474 }
475
476 delete form;
477 }
478
479 void TestMessageFormat::testMsgFormatChoice(/* char* par */)
480 {
481 logln("running TestMessageFormat::testMsgFormatChoice");
482
483 UErrorCode err = U_ZERO_ERROR;
484
485 MessageFormat* form = new MessageFormat("The disk \"{1}\" contains {0}.", err);
486 double filelimits[] = {0,1,2};
487 UnicodeString filepart[] = {"no files","one file","{0,number} files"};
488 ChoiceFormat* fileform = new ChoiceFormat(filelimits, filepart, 3);
489 form->setFormat(1,*fileform); // NOT zero, see below
490 //is the format adopted?
491
492 FieldPosition ignore(FieldPosition::DONT_CARE);
493 UnicodeString string;
494 Formattable testArgs1[] = {(int32_t)0, "MyDisk"};
495 form->format(testArgs1, 2, string, ignore, err);
496 if (string != "The disk \"MyDisk\" contains no files.") {
497 errln("TestMessageFormat::testMsgFormatChoice failed on test #1");
498 }
499
500 ignore.setField(FieldPosition::DONT_CARE);
501 string.remove();
502 Formattable testArgs2[] = {(int32_t)1, "MyDisk"};
503 form->format(testArgs2, 2, string, ignore, err);
504 if (string != "The disk \"MyDisk\" contains one file.") {
505 errln("TestMessageFormat::testMsgFormatChoice failed on test #2");
506 }
507
508 ignore.setField(FieldPosition::DONT_CARE);
509 string.remove();
510 Formattable testArgs3[] = {(int32_t)1273, "MyDisk"};
511 form->format(testArgs3, 2, string, ignore, err);
512 if (string != "The disk \"MyDisk\" contains 1,273 files.") {
513 errln("TestMessageFormat::testMsgFormatChoice failed on test #3");
514 }
515
516 delete form;
517 delete fileform;
518 }
519
520
521 void TestMessageFormat::testMsgFormatPlural(/* char* par */)
522 {
523 logln("running TestMessageFormat::testMsgFormatPlural");
524
525 UErrorCode err = U_ZERO_ERROR;
526 UnicodeString t1("{0, plural, one{C''est # fichier} other{Ce sont # fichiers}} dans la liste.");
527 UnicodeString t2("{argument, plural, one{C''est # fichier} other {Ce sont # fichiers}} dans la liste.");
528 UnicodeString t3("There {0, plural, one{is # zavod}few{are {0, number,###.0} zavoda} other{are # zavodov}} in the directory.");
529 UnicodeString t4("There {argument, plural, one{is # zavod}few{are {argument, number,###.0} zavoda} other{are #zavodov}} in the directory.");
530 UnicodeString t5("{0, plural, one {{0, number,C''''est #,##0.0# fichier}} other {Ce sont # fichiers}} dans la liste.");
531 MessageFormat* mfNum = new MessageFormat(t1, Locale("fr"), err);
532 if (U_FAILURE(err)) {
533 errln("TestMessageFormat::testMsgFormatPlural #1 - argumentIndex");
534 logln(UnicodeString("TestMessageFormat::testMsgFormatPlural #1 with error code ")+(int32_t)err);
535 return;
536 }
537 Formattable testArgs1((int32_t)0);
538 FieldPosition ignore(FieldPosition::DONT_CARE);
539 UnicodeString numResult1;
540 mfNum->format(&testArgs1, 1, numResult1, ignore, err);
541
542 MessageFormat* mfAlpha = new MessageFormat(t2, Locale("fr"), err);
543 UnicodeString argName[] = {UnicodeString("argument")};
544 UnicodeString argNameResult;
545 mfAlpha->format(argName, &testArgs1, 1, argNameResult, err);
546 if (U_FAILURE(err)) {
547 errln("TestMessageFormat::testMsgFormatPlural #1 - argumentName");
548 logln(UnicodeString("TestMessageFormat::testMsgFormatPlural #1 with error code ")+(int32_t)err);
549 delete mfNum;
550 return;
551 }
552 if ( numResult1 != argNameResult){
553 errln("TestMessageFormat::testMsgFormatPlural #1");
554 logln(UnicodeString("The results of argumentName and argumentIndex are not the same."));
555 }
556 if ( numResult1 != UnicodeString("C\'est 0 fichier dans la liste.")) {
557 errln("TestMessageFormat::testMsgFormatPlural #1");
558 logln(UnicodeString("The results of argumentName and argumentIndex are not the same."));
559 }
560 err = U_ZERO_ERROR;
561
562 delete mfNum;
563 delete mfAlpha;
564
565 MessageFormat* mfNum2 = new MessageFormat(t3, Locale("ru"), err);
566 numResult1.remove();
567 Formattable testArgs2((int32_t)4);
568 mfNum2->format(&testArgs2, 1, numResult1, ignore, err);
569 MessageFormat* mfAlpha2 = new MessageFormat(t4, Locale("ru"), err);
570 argNameResult.remove();
571 mfAlpha2->format(argName, &testArgs2, 1, argNameResult, err);
572
573 if (U_FAILURE(err)) {
574 errln("TestMessageFormat::testMsgFormatPlural #2 - argumentName");
575 logln(UnicodeString("TestMessageFormat::testMsgFormatPlural #2 with error code ")+(int32_t)err);
576 delete mfNum2;
577 return;
578 }
579 if ( numResult1 != argNameResult){
580 errln("TestMessageFormat::testMsgFormatPlural #2");
581 logln(UnicodeString("The results of argumentName and argumentIndex are not the same."));
582 }
583 if ( numResult1 != UnicodeString("There are 4,0 zavoda in the directory.")) {
584 errln("TestMessageFormat::testMsgFormatPlural #2");
585 logln(UnicodeString("The results of argumentName and argumentIndex are not the same."));
586 }
587
588 delete mfNum2;
589 delete mfAlpha2;
590
591 // nested formats
592 err = U_ZERO_ERROR;
593 MessageFormat* msgFmt = new MessageFormat(t5, Locale("fr"), err);
594 if (U_FAILURE(err)) {
595 errln("TestMessageFormat::test nested PluralFormat with argumentName");
596 logln(UnicodeString("TestMessageFormat::test nested PluralFormat with error code ")+(int32_t)err);
597 delete msgFmt;
598 return;
599 }
600 Formattable testArgs3((int32_t)0);
601 argNameResult.remove();
602 msgFmt->format(&testArgs3, 1, argNameResult, ignore, err);
603 if (U_FAILURE(err)) {
604 errln("TestMessageFormat::test nested PluralFormat with argumentName");
605 }
606 if ( argNameResult!= UnicodeString("C'est 0,0 fichier dans la liste.")) {
607 errln(UnicodeString("TestMessageFormat::test nested named PluralFormat."));
608 logln(UnicodeString("The unexpected nested named PluralFormat."));
609 }
610 delete msgFmt;
611 }
612
613
614 //---------------------------------
615 // API Tests
616 //---------------------------------
617
618 void TestMessageFormat::testCopyConstructor()
619 {
620 UErrorCode success = U_ZERO_ERROR;
621 MessageFormat *x = new MessageFormat("There are {0} files on {1}", success);
622 MessageFormat *z = new MessageFormat("There are {0} files on {1} created", success);
623 MessageFormat *y = 0;
624 y = new MessageFormat(*x);
625 if ( (*x == *y) &&
626 (*x != *z) &&
627 (*y != *z) )
628 logln("First test (operator ==): Passed!");
629 else {
630 errln("TestMessageFormat::testCopyConstructor failed #1");
631 logln("First test (operator ==): Failed!");
632 }
633 if ( ((*x == *y) && (*y == *x)) &&
634 ((*x != *z) && (*z != *x)) &&
635 ((*y != *z) && (*z != *y)) )
636 logln("Second test (equals): Passed!");
637 else {
638 errln("TestMessageFormat::testCopyConstructor failed #2");
639 logln("Second test (equals): Failed!");
640 }
641
642 delete x;
643 delete y;
644 delete z;
645 }
646
647
648 void TestMessageFormat::testAssignment()
649 {
650 UErrorCode success = U_ZERO_ERROR;
651 MessageFormat *x = new MessageFormat("There are {0} files on {1}", success);
652 MessageFormat *z = new MessageFormat("There are {0} files on {1} created", success);
653 MessageFormat *y = new MessageFormat("There are {0} files on {1} created", success);
654 *y = *x;
655 if ( (*x == *y) &&
656 (*x != *z) &&
657 (*y != *z) )
658 logln("First test (operator ==): Passed!");
659 else {
660 errln( "TestMessageFormat::testAssignment failed #1");
661 logln("First test (operator ==): Failed!");
662 }
663 if ( ((*x == *y) && (*y == *x)) &&
664 ((*x != *z) && (*z != *x)) &&
665 ((*y != *z) && (*z != *y)) )
666 logln("Second test (equals): Passed!");
667 else {
668 errln("TestMessageFormat::testAssignment failed #2");
669 logln("Second test (equals): Failed!");
670 }
671
672 delete x;
673 delete y;
674 delete z;
675 }
676
677 void TestMessageFormat::testClone()
678 {
679 UErrorCode success = U_ZERO_ERROR;
680 MessageFormat *x = new MessageFormat("There are {0} files on {1}", success);
681 MessageFormat *z = new MessageFormat("There are {0} files on {1} created", success);
682 MessageFormat *y = 0;
683 y = (MessageFormat*)x->clone();
684 if ( (*x == *y) &&
685 (*x != *z) &&
686 (*y != *z) )
687 logln("First test (operator ==): Passed!");
688 else {
689 errln("TestMessageFormat::testClone failed #1");
690 logln("First test (operator ==): Failed!");
691 }
692 if ( ((*x == *y) && (*y == *x)) &&
693 ((*x != *z) && (*z != *x)) &&
694 ((*y != *z) && (*z != *y)) )
695 logln("Second test (equals): Passed!");
696 else {
697 errln("TestMessageFormat::testClone failed #2");
698 logln("Second test (equals): Failed!");
699 }
700
701 delete x;
702 delete y;
703 delete z;
704 }
705
706 void TestMessageFormat::testEquals()
707 {
708 UErrorCode success = U_ZERO_ERROR;
709 MessageFormat x("There are {0} files on {1}", success);
710 MessageFormat y("There are {0} files on {1}", success);
711 if (!(x == y)) {
712 errln( "TestMessageFormat::testEquals failed #1");
713 logln("First test (operator ==): Failed!");
714 }
715
716 }
717
718 void TestMessageFormat::testNotEquals()
719 {
720 UErrorCode success = U_ZERO_ERROR;
721 MessageFormat x("There are {0} files on {1}", success);
722 MessageFormat y(x);
723 y.setLocale(Locale("fr"));
724 if (!(x != y)) {
725 errln( "TestMessageFormat::testEquals failed #1");
726 logln("First test (operator !=): Failed!");
727 }
728 y = x;
729 y.applyPattern("There are {0} files on {1} the disk", success);
730 if (!(x != y)) {
731 errln( "TestMessageFormat::testEquals failed #1");
732 logln("Second test (operator !=): Failed!");
733 }
734 }
735
736
737 void TestMessageFormat::testSetLocale()
738 {
739 UErrorCode err = U_ZERO_ERROR;
740 GregorianCalendar cal(err);
741 Formattable arguments[] = {
742 456.83,
743 Formattable(UDate(8.71068e+011), Formattable::kIsDate),
744 "deposit"
745 };
746
747 UnicodeString result;
748
749 //UnicodeString formatStr = "At {1,time} on {1,date}, you made a {2} of {0,number,currency}.";
750 UnicodeString formatStr = "At <time> on {1,date}, you made a {2} of {0,number,currency}.";
751 // {sfb} to get $, would need Locale::US, not Locale::ENGLISH
752 // Just use unlocalized currency symbol.
753 //UnicodeString compareStrEng = "At <time> on Aug 8, 1997, you made a deposit of $456.83.";
754 UnicodeString compareStrEng = "At <time> on Aug 8, 1997, you made a deposit of ";
755 compareStrEng += (UChar) 0x00a4;
756 compareStrEng += "456.83.";
757 // {sfb} to get DM, would need Locale::GERMANY, not Locale::GERMAN
758 // Just use unlocalized currency symbol.
759 //UnicodeString compareStrGer = "At <time> on 08.08.1997, you made a deposit of 456,83 DM.";
760 UnicodeString compareStrGer = "At <time> on 08.08.1997, you made a deposit of ";
761 compareStrGer += "456,83";
762 compareStrGer += (UChar) 0x00a0;
763 compareStrGer += (UChar) 0x00a4;
764 compareStrGer += ".";
765
766 MessageFormat msg( formatStr, err);
767 result = "";
768 FieldPosition pos(0);
769 result = msg.format(
770 arguments,
771 3,
772 result,
773 pos,
774 err);
775
776 logln(result);
777 if (result != compareStrEng) {
778 errln("*** MSG format err.");
779 }
780
781 msg.setLocale(Locale::getEnglish());
782 UBool getLocale_ok = TRUE;
783 if (msg.getLocale() != Locale::getEnglish()) {
784 errln("*** MSG getLocal err.");
785 getLocale_ok = FALSE;
786 }
787
788 msg.setLocale(Locale::getGerman());
789
790 if (msg.getLocale() != Locale::getGerman()) {
791 errln("*** MSG getLocal err.");
792 getLocale_ok = FALSE;
793 }
794
795 msg.applyPattern( formatStr, err);
796
797 pos.setField(0);
798 result = "";
799 result = msg.format(
800 arguments,
801 3,
802 result,
803 pos,
804 err);
805
806 logln(result);
807 if (result == compareStrGer) {
808 logln("MSG setLocale tested.");
809 }else{
810 errln( "*** MSG setLocale err.");
811 }
812
813 if (getLocale_ok) {
814 logln("MSG getLocale tested.");
815 }
816 }
817
818 void TestMessageFormat::testFormat()
819 {
820 UErrorCode err = U_ZERO_ERROR;
821 GregorianCalendar cal(err);
822
823 const Formattable ftarray[] =
824 {
825 Formattable( UDate(8.71068e+011), Formattable::kIsDate )
826 };
827 const int32_t ft_cnt = sizeof(ftarray) / sizeof(Formattable);
828 Formattable ft_arr( ftarray, ft_cnt );
829
830 Formattable* fmt = new Formattable(UDate(8.71068e+011), Formattable::kIsDate);
831
832 UnicodeString result;
833
834 //UnicodeString formatStr = "At {1,time} on {1,date}, you made a {2} of {0,number,currency}.";
835 UnicodeString formatStr = "On {0,date}, it began.";
836 UnicodeString compareStr = "On Aug 8, 1997, it began.";
837
838 err = U_ZERO_ERROR;
839 MessageFormat msg( formatStr, err);
840 FieldPosition fp(0);
841
842 result = "";
843 fp = 0;
844 result = msg.format(
845 *fmt,
846 result,
847 //FieldPosition(0),
848 fp,
849 err);
850
851 if (err != U_ILLEGAL_ARGUMENT_ERROR) {
852 errln("*** MSG format without expected error code.");
853 }
854 err = U_ZERO_ERROR;
855
856 result = "";
857 fp = 0;
858 result = msg.format(
859 ft_arr,
860 result,
861 //FieldPosition(0),
862 fp,
863 err);
864
865 logln("MSG format( Formattable&, ... ) expected:" + compareStr);
866 logln("MSG format( Formattable&, ... ) result:" + result);
867 if (result != compareStr) {
868 errln("*** MSG format( Formattable&, .... ) err.");
869 }else{
870 logln("MSG format( Formattable&, ... ) tested.");
871 }
872
873 delete fmt;
874
875 }
876
877 void TestMessageFormat::testParse()
878 {
879 UErrorCode err = U_ZERO_ERROR;
880 int32_t count;
881 UnicodeString msgFormatString = "{0} =sep= {1}";
882 MessageFormat msg( msgFormatString, err);
883 UnicodeString source = "abc =sep= def";
884 UnicodeString tmp1, tmp2;
885
886 Formattable* fmt_arr = msg.parse( source, count, err );
887 if (U_FAILURE(err) || (!fmt_arr)) {
888 errln("*** MSG parse (ustring, count, err) error.");
889 }else{
890 logln("MSG parse -- count: %d", count);
891 if (count != 2) {
892 errln("*** MSG parse (ustring, count, err) count err.");
893 }else{
894 if ((fmt_arr[0].getType() == Formattable::kString)
895 && (fmt_arr[1].getType() == Formattable::kString)
896 && (fmt_arr[0].getString(tmp1) == "abc")
897 && (fmt_arr[1].getString(tmp2) == "def")) {
898 logln("MSG parse (ustring, count, err) tested.");
899 }else{
900 errln("*** MSG parse (ustring, count, err) result err.");
901 }
902 }
903 }
904 delete[] fmt_arr;
905
906 ParsePosition pp(0);
907
908 fmt_arr = msg.parse( source, pp, count );
909 if ((pp == 0) || (!fmt_arr)) {
910 errln("*** MSG parse (ustring, parsepos., count) error.");
911 }else{
912 logln("MSG parse -- count: %d", count);
913 if (count != 2) {
914 errln("*** MSG parse (ustring, parsepos., count) count err.");
915 }else{
916 if ((fmt_arr[0].getType() == Formattable::kString)
917 && (fmt_arr[1].getType() == Formattable::kString)
918 && (fmt_arr[0].getString(tmp1) == "abc")
919 && (fmt_arr[1].getString(tmp2) == "def")) {
920 logln("MSG parse (ustring, parsepos., count) tested.");
921 }else{
922 errln("*** MSG parse (ustring, parsepos., count) result err.");
923 }
924 }
925 }
926 delete[] fmt_arr;
927
928 pp = 0;
929 Formattable fmta;
930
931 msg.parseObject( source, fmta, pp );
932 if (pp == 0) {
933 errln("*** MSG parse (ustring, Formattable, parsepos ) error.");
934 }else{
935 logln("MSG parse -- count: %d", count);
936 fmta.getArray(count);
937 if (count != 2) {
938 errln("*** MSG parse (ustring, Formattable, parsepos ) count err.");
939 }else{
940 if ((fmta[0].getType() == Formattable::kString)
941 && (fmta[1].getType() == Formattable::kString)
942 && (fmta[0].getString(tmp1) == "abc")
943 && (fmta[1].getString(tmp2) == "def")) {
944 logln("MSG parse (ustring, Formattable, parsepos ) tested.");
945 }else{
946 errln("*** MSG parse (ustring, Formattable, parsepos ) result err.");
947 }
948 }
949 }
950 }
951
952
953 void TestMessageFormat::testAdopt()
954 {
955 UErrorCode err = U_ZERO_ERROR;
956
957 UnicodeString formatStr("{0,date},{1},{2,number}", "");
958 UnicodeString formatStrChange("{0,number},{1,number},{2,date}", "");
959 err = U_ZERO_ERROR;
960 MessageFormat msg( formatStr, err);
961 MessageFormat msgCmp( formatStr, err);
962 int32_t count, countCmp;
963 const Format** formats = msg.getFormats(count);
964 const Format** formatsCmp = msgCmp.getFormats(countCmp);
965 const Format** formatsChg = 0;
966 const Format** formatsAct = 0;
967 int32_t countAct;
968 const Format* a;
969 const Format* b;
970 UnicodeString patCmp;
971 UnicodeString patAct;
972 Format** formatsToAdopt;
973
974 if (!formats || !formatsCmp || (count <= 0) || (count != countCmp)) {
975 errln("Error getting Formats");
976 return;
977 }
978
979 int32_t i;
980
981 for (i = 0; i < count; i++) {
982 a = formats[i];
983 b = formatsCmp[i];
984 if ((a != NULL) && (b != NULL)) {
985 if (*a != *b) {
986 errln("a != b");
987 return;
988 }
989 }else if ((a != NULL) || (b != NULL)) {
990 errln("(a != NULL) || (b != NULL)");
991 return;
992 }
993 }
994
995 msg.applyPattern( formatStrChange, err ); //set msg formats to something different
996 int32_t countChg;
997 formatsChg = msg.getFormats(countChg); // tested function
998 if (!formatsChg || (countChg != count)) {
999 errln("Error getting Formats");
1000 return;
1001 }
1002
1003 UBool diff;
1004 diff = TRUE;
1005 for (i = 0; i < count; i++) {
1006 a = formatsChg[i];
1007 b = formatsCmp[i];
1008 if ((a != NULL) && (b != NULL)) {
1009 if (*a == *b) {
1010 logln("formatsChg == formatsCmp at index %d", i);
1011 diff = FALSE;
1012 }
1013 }
1014 }
1015 if (!diff) {
1016 errln("*** MSG getFormats diff err.");
1017 return;
1018 }
1019
1020 logln("MSG getFormats tested.");
1021
1022 msg.setFormats( formatsCmp, countCmp ); //tested function
1023
1024 formatsAct = msg.getFormats(countAct);
1025 if (!formatsAct || (countAct <=0) || (countAct != countCmp)) {
1026 errln("Error getting Formats");
1027 return;
1028 }
1029
1030 assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove()));
1031 assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove()));
1032
1033 for (i = 0; i < countAct; i++) {
1034 a = formatsAct[i];
1035 b = formatsCmp[i];
1036 if ((a != NULL) && (b != NULL)) {
1037 if (*a != *b) {
1038 logln("formatsAct != formatsCmp at index %d", i);
1039 errln("a != b");
1040 return;
1041 }
1042 }else if ((a != NULL) || (b != NULL)) {
1043 errln("(a != NULL) || (b != NULL)");
1044 return;
1045 }
1046 }
1047 logln("MSG setFormats tested.");
1048
1049 //----
1050
1051 msg.applyPattern( formatStrChange, err ); //set msg formats to something different
1052
1053 formatsToAdopt = new Format* [countCmp];
1054 if (!formatsToAdopt) {
1055 errln("memory allocation error");
1056 return;
1057 }
1058
1059 for (i = 0; i < countCmp; i++) {
1060 if (formatsCmp[i] == NULL) {
1061 formatsToAdopt[i] = NULL;
1062 }else{
1063 formatsToAdopt[i] = formatsCmp[i]->clone();
1064 if (!formatsToAdopt[i]) {
1065 errln("Can't clone format at index %d", i);
1066 return;
1067 }
1068 }
1069 }
1070 msg.adoptFormats( formatsToAdopt, countCmp ); // function to test
1071 delete[] formatsToAdopt;
1072
1073 assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove()));
1074 assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove()));
1075
1076 formatsAct = msg.getFormats(countAct);
1077 if (!formatsAct || (countAct <=0) || (countAct != countCmp)) {
1078 errln("Error getting Formats");
1079 return;
1080 }
1081
1082 for (i = 0; i < countAct; i++) {
1083 a = formatsAct[i];
1084 b = formatsCmp[i];
1085 if ((a != NULL) && (b != NULL)) {
1086 if (*a != *b) {
1087 errln("a != b");
1088 return;
1089 }
1090 }else if ((a != NULL) || (b != NULL)) {
1091 errln("(a != NULL) || (b != NULL)");
1092 return;
1093 }
1094 }
1095 logln("MSG adoptFormats tested.");
1096
1097 //---- adoptFormat
1098
1099 msg.applyPattern( formatStrChange, err ); //set msg formats to something different
1100
1101 formatsToAdopt = new Format* [countCmp];
1102 if (!formatsToAdopt) {
1103 errln("memory allocation error");
1104 return;
1105 }
1106
1107 for (i = 0; i < countCmp; i++) {
1108 if (formatsCmp[i] == NULL) {
1109 formatsToAdopt[i] = NULL;
1110 }else{
1111 formatsToAdopt[i] = formatsCmp[i]->clone();
1112 if (!formatsToAdopt[i]) {
1113 errln("Can't clone format at index %d", i);
1114 return;
1115 }
1116 }
1117 }
1118
1119 for ( i = 0; i < countCmp; i++ ) {
1120 msg.adoptFormat( i, formatsToAdopt[i] ); // function to test
1121 }
1122 delete[] formatsToAdopt; // array itself not needed in this case;
1123
1124 assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove()));
1125 assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove()));
1126
1127 formatsAct = msg.getFormats(countAct);
1128 if (!formatsAct || (countAct <=0) || (countAct != countCmp)) {
1129 errln("Error getting Formats");
1130 return;
1131 }
1132
1133 for (i = 0; i < countAct; i++) {
1134 a = formatsAct[i];
1135 b = formatsCmp[i];
1136 if ((a != NULL) && (b != NULL)) {
1137 if (*a != *b) {
1138 errln("a != b");
1139 return;
1140 }
1141 }else if ((a != NULL) || (b != NULL)) {
1142 errln("(a != NULL) || (b != NULL)");
1143 return;
1144 }
1145 }
1146 logln("MSG adoptFormat tested.");
1147 }
1148
1149 // This test is a regression test for a fixed bug in the copy constructor.
1150 // It is kept as a global function rather than as a method since the test depends on memory values.
1151 // (At least before the bug was fixed, whether it showed up or not depended on memory contents,
1152 // which is probably why it didn't show up in the regular test for the copy constructor.)
1153 // For this reason, the test isn't changed even though it contains function calls whose results are
1154 // not tested and had no problems. Actually, the test failed by *crashing*.
1155 static void _testCopyConstructor2()
1156 {
1157 UErrorCode status = U_ZERO_ERROR;
1158 UnicodeString formatStr("Hello World on {0,date,full}", "");
1159 UnicodeString resultStr(" ", "");
1160 UnicodeString result;
1161 FieldPosition fp(0);
1162 UDate d = Calendar::getNow();
1163 const Formattable fargs( d, Formattable::kIsDate );
1164
1165 MessageFormat* fmt1 = new MessageFormat( formatStr, status );
1166 MessageFormat* fmt2 = new MessageFormat( *fmt1 );
1167 MessageFormat* fmt3;
1168 MessageFormat* fmt4;
1169
1170 if (fmt1 == NULL) it_err("testCopyConstructor2: (fmt1 != NULL)");
1171
1172 result = fmt1->format( &fargs, 1, resultStr, fp, status );
1173
1174 if (fmt2 == NULL) it_err("testCopyConstructor2: (fmt2 != NULL)");
1175
1176 fmt3 = (MessageFormat*) fmt1->clone();
1177 fmt4 = (MessageFormat*) fmt2->clone();
1178
1179 if (fmt3 == NULL) it_err("testCopyConstructor2: (fmt3 != NULL)");
1180 if (fmt4 == NULL) it_err("testCopyConstructor2: (fmt4 != NULL)");
1181
1182 result = fmt1->format( &fargs, 1, resultStr, fp, status );
1183 result = fmt2->format( &fargs, 1, resultStr, fp, status );
1184 result = fmt3->format( &fargs, 1, resultStr, fp, status );
1185 result = fmt4->format( &fargs, 1, resultStr, fp, status );
1186 delete fmt1;
1187 delete fmt2;
1188 delete fmt3;
1189 delete fmt4;
1190 }
1191
1192 void TestMessageFormat::testCopyConstructor2() {
1193 _testCopyConstructor2();
1194 }
1195
1196 /**
1197 * Verify that MessageFormat accomodates more than 10 arguments and
1198 * more than 10 subformats.
1199 */
1200 void TestMessageFormat::TestUnlimitedArgsAndSubformats() {
1201 UErrorCode ec = U_ZERO_ERROR;
1202 const UnicodeString pattern =
1203 "On {0,date} (aka {0,date,short}, aka {0,date,long}) "
1204 "at {0,time} (aka {0,time,short}, aka {0,time,long}) "
1205 "there were {1,number} werjes "
1206 "(a {3,number,percent} increase over {2,number}) "
1207 "despite the {4}''s efforts "
1208 "and to delight of {5}, {6}, {7}, {8}, {9}, and {10} {11}.";
1209 MessageFormat msg(pattern, ec);
1210 if (U_FAILURE(ec)) {
1211 errln("FAIL: constructor failed");
1212 return;
1213 }
1214
1215 const Formattable ARGS[] = {
1216 Formattable(UDate(1e13), Formattable::kIsDate),
1217 Formattable((int32_t)1303),
1218 Formattable((int32_t)1202),
1219 Formattable(1303.0/1202 - 1),
1220 Formattable("Glimmung"),
1221 Formattable("the printers"),
1222 Formattable("Nick"),
1223 Formattable("his father"),
1224 Formattable("his mother"),
1225 Formattable("the spiddles"),
1226 Formattable("of course"),
1227 Formattable("Horace"),
1228 };
1229 const int32_t ARGS_LENGTH = sizeof(ARGS) / sizeof(ARGS[0]);
1230 Formattable ARGS_OBJ(ARGS, ARGS_LENGTH);
1231
1232 UnicodeString expected =
1233 "On Nov 20, 2286 (aka 11/20/86, aka November 20, 2286) "
1234 "at 9:46:40 AM (aka 9:46 AM, aka 9:46:40 AM PST) "
1235 "there were 1,303 werjes "
1236 "(a 8% increase over 1,202) "
1237 "despite the Glimmung's efforts "
1238 "and to delight of the printers, Nick, his father, "
1239 "his mother, the spiddles, and of course Horace.";
1240 UnicodeString result;
1241 msg.format(ARGS_OBJ, result, ec);
1242 if (result == expected) {
1243 logln(result);
1244 } else {
1245 errln((UnicodeString)"FAIL: Got " + result +
1246 ", expected " + expected);
1247 }
1248 }
1249
1250 // test RBNF extensions to message format
1251 void TestMessageFormat::TestRBNF(void) {
1252 // WARNING: this depends on the RBNF formats for en_US
1253 Locale locale("en", "US", "");
1254
1255 UErrorCode ec = U_ZERO_ERROR;
1256
1257 UnicodeString values[] = {
1258 // decimal values do not format completely for ordinal or duration, and
1259 // do not always parse, so do not include them
1260 "0", "1", "12", "100", "123", "1001", "123,456", "-17",
1261 };
1262 int32_t values_count = sizeof(values)/sizeof(values[0]);
1263
1264 UnicodeString formats[] = {
1265 "There are {0,spellout} files to search.",
1266 "There are {0,spellout,%simplified} files to search.",
1267 "The bogus spellout {0,spellout,%BOGUS} files behaves like the default.",
1268 "This is the {0,ordinal} file to search.", // TODO fix bug, ordinal does not parse
1269 "Searching this file will take {0,duration} to complete.",
1270 "Searching this file will take {0,duration,%with-words} to complete.",
1271 };
1272 int32_t formats_count = sizeof(formats)/sizeof(formats[0]);
1273
1274 Formattable args[1];
1275
1276 NumberFormat* numFmt = NumberFormat::createInstance(locale, ec);
1277 if (U_FAILURE(ec)) {
1278 dataerrln("Error calling NumberFormat::createInstance()");
1279 return;
1280 }
1281
1282 for (int i = 0; i < formats_count; ++i) {
1283 MessageFormat* fmt = new MessageFormat(formats[i], locale, ec);
1284 logln((UnicodeString)"Testing format pattern: '" + formats[i] + "'");
1285
1286 for (int j = 0; j < values_count; ++j) {
1287 ec = U_ZERO_ERROR;
1288 numFmt->parse(values[j], args[0], ec);
1289 if (U_FAILURE(ec)) {
1290 errln((UnicodeString)"Failed to parse test argument " + values[j]);
1291 } else {
1292 FieldPosition fp(0);
1293 UnicodeString result;
1294 fmt->format(args, 1, result, fp, ec);
1295 logln((UnicodeString)"value: " + toString(args[0]) + " --> " + result + UnicodeString(" ec: ") + u_errorName(ec));
1296
1297 if (i != 3) { // TODO: fix this, for now skip ordinal parsing (format string at index 3)
1298 int32_t count = 0;
1299 Formattable* parseResult = fmt->parse(result, count, ec);
1300 if (count != 1) {
1301 errln((UnicodeString)"parse returned " + count + " args");
1302 } else if (parseResult[0] != args[0]) {
1303 errln((UnicodeString)"parsed argument " + toString(parseResult[0]) + " != " + toString(args[0]));
1304 }
1305 delete []parseResult;
1306 }
1307 }
1308 }
1309 delete fmt;
1310 }
1311 delete numFmt;
1312 }
1313
1314 void TestMessageFormat::testAutoQuoteApostrophe(void) {
1315 const char* patterns[] = { // pattern, expected pattern
1316 "'", "''",
1317 "''", "''",
1318 "'{", "'{'",
1319 "' {", "'' {",
1320 "'a", "''a",
1321 "'{'a", "'{'a",
1322 "'{a'", "'{a'",
1323 "'{}", "'{}'",
1324 "{'", "{'",
1325 "{'a", "{'a",
1326 "{'a{}'a}'a", "{'a{}'a}''a",
1327 "'}'", "'}'",
1328 "'} '{'}'", "'} '{'}''",
1329 "'} {{{''", "'} {{{'''",
1330 };
1331 int32_t pattern_count = sizeof(patterns)/sizeof(patterns[0]);
1332
1333 for (int i = 0; i < pattern_count; i += 2) {
1334 UErrorCode status = U_ZERO_ERROR;
1335 UnicodeString result = MessageFormat::autoQuoteApostrophe(patterns[i], status);
1336 UnicodeString target(patterns[i+1]);
1337 if (target != result) {
1338 const int BUF2_LEN = 64;
1339 char buf[256];
1340 char buf2[BUF2_LEN];
1341 int32_t len = result.extract(0, result.length(), buf2, BUF2_LEN);
1342 if (len >= BUF2_LEN) {
1343 buf2[BUF2_LEN-1] = 0;
1344 }
1345 sprintf(buf, "[%2d] test \"%s\": target (\"%s\") != result (\"%s\")\n", i/2, patterns[i], patterns[i+1], buf2);
1346 errln(buf);
1347 }
1348 }
1349 }
1350
1351 #endif /* #if !UCONFIG_NO_FORMATTING */