]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/intltest/tmsgfmt.cpp
ICU-6.2.22.tar.gz
[apple/icu.git] / icuSources / test / intltest / tmsgfmt.cpp
CommitLineData
b75a7d8f
A
1/********************************************************************
2 * COPYRIGHT:
374ca955 3 * Copyright (c) 1997-2004, International Business Machines Corporation and
b75a7d8f
A
4 * others. All Rights Reserved.
5 ********************************************************************/
6/*
7* File TMSGFMT.CPP
8*
9* Modification History:
10*
11* Date Name Description
12* 03/24/97 helena Converted from Java.
13* 07/11/97 helena Updated to work on AIX.
14* 08/04/97 jfitz Updated to intltest
15********************************************************************************
16*/
17
18#include "unicode/utypes.h"
19
20#if !UCONFIG_NO_FORMATTING
21
22#include "tmsgfmt.h"
23
24#include "unicode/format.h"
25#include "unicode/decimfmt.h"
26#include "unicode/locid.h"
27#include "unicode/msgfmt.h"
28#include "unicode/numfmt.h"
29#include "unicode/choicfmt.h"
30#include "unicode/gregocal.h"
31
32void
33TestMessageFormat::runIndexedTest(int32_t index, UBool exec,
34 const char* &name, char* /*par*/) {
35 switch (index) {
36 TESTCASE(0,testBug1);
37 TESTCASE(1,testBug2);
38 TESTCASE(2,sample);
39 TESTCASE(3,PatternTest);
40 TESTCASE(4,testStaticFormat);
41 TESTCASE(5,testSimpleFormat);
42 TESTCASE(6,testMsgFormatChoice);
43 TESTCASE(7,testCopyConstructor);
44 TESTCASE(8,testAssignment);
45 TESTCASE(9,testClone);
46 TESTCASE(10,testEquals);
47 TESTCASE(11,testNotEquals);
48 TESTCASE(12,testSetLocale);
49 TESTCASE(13,testFormat);
50 TESTCASE(14,testParse);
51 TESTCASE(15,testAdopt);
52 TESTCASE(16,testCopyConstructor2);
53 TESTCASE(17,TestUnlimitedArgsAndSubformats);
374ca955 54 TESTCASE(18,TestRBNF);
b75a7d8f
A
55 default: name = ""; break;
56 }
57}
58
59void TestMessageFormat::testBug3()
60{
61 double myNumber = -123456;
62 DecimalFormat *form = 0;
63 Locale locale[] = {
64 Locale("ar", "", ""),
65 Locale("be", "", ""),
66 Locale("bg", "", ""),
67 Locale("ca", "", ""),
68 Locale("cs", "", ""),
69 Locale("da", "", ""),
70 Locale("de", "", ""),
71 Locale("de", "AT", ""),
72 Locale("de", "CH", ""),
73 Locale("el", "", ""), // 10
74 Locale("en", "CA", ""),
75 Locale("en", "GB", ""),
76 Locale("en", "IE", ""),
77 Locale("en", "US", ""),
78 Locale("es", "", ""),
79 Locale("et", "", ""),
80 Locale("fi", "", ""),
81 Locale("fr", "", ""),
82 Locale("fr", "BE", ""),
83 Locale("fr", "CA", ""), // 20
84 Locale("fr", "CH", ""),
85 Locale("he", "", ""),
86 Locale("hr", "", ""),
87 Locale("hu", "", ""),
88 Locale("is", "", ""),
89 Locale("it", "", ""),
90 Locale("it", "CH", ""),
91 Locale("ja", "", ""),
92 Locale("ko", "", ""),
93 Locale("lt", "", ""), // 30
94 Locale("lv", "", ""),
95 Locale("mk", "", ""),
96 Locale("nl", "", ""),
97 Locale("nl", "BE", ""),
98 Locale("no", "", ""),
99 Locale("pl", "", ""),
100 Locale("pt", "", ""),
101 Locale("ro", "", ""),
102 Locale("ru", "", ""),
103 Locale("sh", "", ""), // 40
104 Locale("sk", "", ""),
105 Locale("sl", "", ""),
106 Locale("sq", "", ""),
107 Locale("sr", "", ""),
108 Locale("sv", "", ""),
109 Locale("tr", "", ""),
110 Locale("uk", "", ""),
111 Locale("zh", "", ""),
112 Locale("zh", "TW", "") // 49
113 };
114 int32_t i;
115 for (i= 0; i < 49; i++) {
116 UnicodeString buffer;
117 logln(locale[i].getDisplayName(buffer));
118 UErrorCode success = U_ZERO_ERROR;
119// form = (DecimalFormat*)NumberFormat::createCurrencyInstance(locale[i], success);
120 form = (DecimalFormat*)NumberFormat::createInstance(locale[i], success);
121 if (U_FAILURE(success)) {
122 errln("Err: Number Format ");
123 logln("Number format creation failed.");
124 continue;
125 }
126 Formattable result;
127 FieldPosition pos(0);
128 buffer.remove();
129 form->format(myNumber, buffer, pos);
130 success = U_ZERO_ERROR;
131 ParsePosition parsePos;
132 form->parse(buffer, result, parsePos);
374ca955 133 logln(UnicodeString(" -> ") /* + << dec*/ + toString(result) + UnicodeString("[supposed output for result]"));
b75a7d8f
A
134 if (U_FAILURE(success)) {
135 errln("Err: Number Format parse");
136 logln("Number format parse failed.");
137 }
138 delete form;
139 }
140}
141
142void TestMessageFormat::testBug1()
143{
144 const double limit[] = {0.0, 1.0, 2.0};
145 const UnicodeString formats[] = {"0.0<=Arg<1.0",
146 "1.0<=Arg<2.0",
147 "2.0<-Arg"};
148 ChoiceFormat *cf = new ChoiceFormat(limit, formats, 3);
149 FieldPosition status(0);
150 UnicodeString toAppendTo;
151 cf->format((int32_t)1, toAppendTo, status);
152 if (toAppendTo != "1.0<=Arg<2.0") {
153 errln("ChoiceFormat cmp in testBug1");
154 }
155 logln(toAppendTo);
156 delete cf;
157}
158
159void TestMessageFormat::testBug2()
160{
161 UErrorCode status = U_ZERO_ERROR;
162 UnicodeString result;
163 // {sfb} use double format in pattern, so result will match (not strictly necessary)
164 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}. ";
165 logln("The input pattern : " + pattern);
166 MessageFormat *fmt = new MessageFormat(pattern, status);
167 if (U_FAILURE(status)) {
168 errln("MessageFormat pattern creation failed.");
169 return;
170 }
171 logln("The output pattern is : " + fmt->toPattern(result));
172 if (pattern != result) {
173 errln("MessageFormat::toPattern() failed.");
174 }
175 delete fmt;
176}
177
178#if 0
179#if defined(_DEBUG) && U_IOSTREAM_SOURCE!=0
180//----------------------------------------------------
181// console I/O
182//----------------------------------------------------
183
184#if U_IOSTREAM_SOURCE >= 199711
185# include <iostream>
186 std::ostream& operator<<(std::ostream& stream, const Formattable& obj);
187#elif U_IOSTREAM_SOURCE >= 198506
188# include <iostream.h>
189 ostream& operator<<(ostream& stream, const Formattable& obj);
190#endif
191
192#include "unicode/datefmt.h"
193#include <stdlib.h>
194#include <stdio.h>
195#include <string.h>
196
197IntlTest&
198operator<<( 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
239void 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
351void 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);
374ca955
A
366 assertEquals("format",
367 "There are abc files on def",
368 form->format(testArgs1, 2, buffer2, fieldpos, success));
369 assertSuccess("format", success);
b75a7d8f
A
370 delete form;
371}
372
374ca955 373void TestMessageFormat::testStaticFormat()
b75a7d8f 374{
b75a7d8f 375 UErrorCode err = U_ZERO_ERROR;
b75a7d8f
A
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
406void TestMessageFormat::testSimpleFormat(/* char* par */)
407{
408 logln("running TestMessageFormat::testSimpleFormat");
409
410 UErrorCode err = U_ZERO_ERROR;
411
412 Formattable testArgs1[] = {(int32_t)0, "MyDisk"};
413 Formattable testArgs2[] = {(int32_t)1, "MyDisk"};
414 Formattable testArgs3[] = {(int32_t)12, "MyDisk"};
415
416 MessageFormat* form = new MessageFormat(
417 "The disk \"{1}\" contains {0} file(s).", err);
418
419 UnicodeString string;
420 FieldPosition ignore(FieldPosition::DONT_CARE);
421 form->format(testArgs1, 2, string, ignore, err);
422 if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 0 file(s).") {
423 errln(UnicodeString("TestMessageFormat::testSimpleFormat failed on test #1"));
424 }
425
426 ignore.setField(FieldPosition::DONT_CARE);
427 string.remove();
428 form->format(testArgs2, 2, string, ignore, err);
429 if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 1 file(s).") {
430 logln(string);
431 errln(UnicodeString("TestMessageFormat::testSimpleFormat failed on test #2")+string);
432 }
433
434 ignore.setField(FieldPosition::DONT_CARE);
435 string.remove();
436 form->format(testArgs3, 2, string, ignore, err);
437 if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 12 file(s).") {
438 errln(UnicodeString("TestMessageFormat::testSimpleFormat failed on test #3")+string);
439 }
440
441 delete form;
442 }
443
444void TestMessageFormat::testMsgFormatChoice(/* char* par */)
445{
446 logln("running TestMessageFormat::testMsgFormatChoice");
447
448 UErrorCode err = U_ZERO_ERROR;
449
450 MessageFormat* form = new MessageFormat("The disk \"{1}\" contains {0}.", err);
451 double filelimits[] = {0,1,2};
452 UnicodeString filepart[] = {"no files","one file","{0,number} files"};
453 ChoiceFormat* fileform = new ChoiceFormat(filelimits, filepart, 3);
454 form->setFormat(1,*fileform); // NOT zero, see below
455 //is the format adopted?
456
457 FieldPosition ignore(FieldPosition::DONT_CARE);
458 UnicodeString string;
459 Formattable testArgs1[] = {(int32_t)0, "MyDisk"};
460 form->format(testArgs1, 2, string, ignore, err);
461 if (string != "The disk \"MyDisk\" contains no files.") {
462 errln("TestMessageFormat::testMsgFormatChoice failed on test #1");
463 }
464
465 ignore.setField(FieldPosition::DONT_CARE);
466 string.remove();
467 Formattable testArgs2[] = {(int32_t)1, "MyDisk"};
468 form->format(testArgs2, 2, string, ignore, err);
469 if (string != "The disk \"MyDisk\" contains one file.") {
470 errln("TestMessageFormat::testMsgFormatChoice failed on test #2");
471 }
472
473 ignore.setField(FieldPosition::DONT_CARE);
474 string.remove();
475 Formattable testArgs3[] = {(int32_t)1273, "MyDisk"};
476 form->format(testArgs3, 2, string, ignore, err);
477 if (string != "The disk \"MyDisk\" contains 1,273 files.") {
478 errln("TestMessageFormat::testMsgFormatChoice failed on test #3");
479 }
480
481 delete form;
482 delete fileform;
483}
484
485
486//---------------------------------
487// API Tests
488//---------------------------------
489
490void TestMessageFormat::testCopyConstructor()
491{
b75a7d8f
A
492 UErrorCode success = U_ZERO_ERROR;
493 MessageFormat *x = new MessageFormat("There are {0} files on {1}", success);
494 MessageFormat *z = new MessageFormat("There are {0} files on {1} created", success);
495 MessageFormat *y = 0;
496 y = new MessageFormat(*x);
497 if ( (*x == *y) &&
498 (*x != *z) &&
499 (*y != *z) )
500 logln("First test (operator ==): Passed!");
501 else {
502 errln("TestMessageFormat::testCopyConstructor failed #1");
503 logln("First test (operator ==): Failed!");
504 }
505 if ( ((*x == *y) && (*y == *x)) &&
506 ((*x != *z) && (*z != *x)) &&
507 ((*y != *z) && (*z != *y)) )
508 logln("Second test (equals): Passed!");
509 else {
510 errln("TestMessageFormat::testCopyConstructor failed #2");
511 logln("Second test (equals): Failed!");
512 }
513
514 delete x;
515 delete y;
516 delete z;
517}
518
519
520void TestMessageFormat::testAssignment()
521{
b75a7d8f
A
522 UErrorCode success = U_ZERO_ERROR;
523 MessageFormat *x = new MessageFormat("There are {0} files on {1}", success);
524 MessageFormat *z = new MessageFormat("There are {0} files on {1} created", success);
525 MessageFormat *y = new MessageFormat("There are {0} files on {1} created", success);
526 *y = *x;
527 if ( (*x == *y) &&
528 (*x != *z) &&
529 (*y != *z) )
530 logln("First test (operator ==): Passed!");
531 else {
532 errln( "TestMessageFormat::testAssignment failed #1");
533 logln("First test (operator ==): Failed!");
534 }
535 if ( ((*x == *y) && (*y == *x)) &&
536 ((*x != *z) && (*z != *x)) &&
537 ((*y != *z) && (*z != *y)) )
538 logln("Second test (equals): Passed!");
539 else {
540 errln("TestMessageFormat::testAssignment failed #2");
541 logln("Second test (equals): Failed!");
542 }
543
544 delete x;
545 delete y;
546 delete z;
547}
548
549void TestMessageFormat::testClone()
550{
b75a7d8f
A
551 UErrorCode success = U_ZERO_ERROR;
552 MessageFormat *x = new MessageFormat("There are {0} files on {1}", success);
553 MessageFormat *z = new MessageFormat("There are {0} files on {1} created", success);
554 MessageFormat *y = 0;
555 y = (MessageFormat*)x->clone();
556 if ( (*x == *y) &&
557 (*x != *z) &&
558 (*y != *z) )
559 logln("First test (operator ==): Passed!");
560 else {
561 errln("TestMessageFormat::testClone failed #1");
562 logln("First test (operator ==): Failed!");
563 }
564 if ( ((*x == *y) && (*y == *x)) &&
565 ((*x != *z) && (*z != *x)) &&
566 ((*y != *z) && (*z != *y)) )
567 logln("Second test (equals): Passed!");
568 else {
569 errln("TestMessageFormat::testClone failed #2");
570 logln("Second test (equals): Failed!");
571 }
572
573 delete x;
574 delete y;
575 delete z;
576}
577
578void TestMessageFormat::testEquals()
579{
b75a7d8f
A
580 UErrorCode success = U_ZERO_ERROR;
581 MessageFormat x("There are {0} files on {1}", success);
582 MessageFormat y("There are {0} files on {1}", success);
583 if (!(x == y)) {
584 errln( "TestMessageFormat::testEquals failed #1");
585 logln("First test (operator ==): Failed!");
586 }
587
588}
589
590void TestMessageFormat::testNotEquals()
591{
592 UErrorCode success = U_ZERO_ERROR;
593 MessageFormat x("There are {0} files on {1}", success);
594 MessageFormat y(x);
595 y.setLocale(Locale("fr"));
596 if (!(x != y)) {
597 errln( "TestMessageFormat::testEquals failed #1");
598 logln("First test (operator !=): Failed!");
599 }
600 y = x;
601 y.applyPattern("There are {0} files on {1} the disk", success);
602 if (!(x != y)) {
603 errln( "TestMessageFormat::testEquals failed #1");
374ca955 604 logln("Second test (operator !=): Failed!");
b75a7d8f
A
605 }
606}
607
608
609void TestMessageFormat::testSetLocale()
610{
611 UErrorCode err = U_ZERO_ERROR;
612 GregorianCalendar cal(err);
613 Formattable arguments[] = {
614 456.83,
615 Formattable(UDate(8.71068e+011), Formattable::kIsDate),
616 "deposit"
617 };
618
619 UnicodeString result;
620
621 //UnicodeString formatStr = "At {1,time} on {1,date}, you made a {2} of {0,number,currency}.";
622 UnicodeString formatStr = "At <time> on {1,date}, you made a {2} of {0,number,currency}.";
623 // {sfb} to get $, would need Locale::US, not Locale::ENGLISH
624 // Just use unlocalized currency symbol.
625 //UnicodeString compareStrEng = "At <time> on Aug 8, 1997, you made a deposit of $456.83.";
626 UnicodeString compareStrEng = "At <time> on Aug 8, 1997, you made a deposit of ";
627 compareStrEng += (UChar) 0x00a4;
628 compareStrEng += "456.83.";
629 // {sfb} to get DM, would need Locale::GERMANY, not Locale::GERMAN
630 // Just use unlocalized currency symbol.
631 //UnicodeString compareStrGer = "At <time> on 08.08.1997, you made a deposit of 456,83 DM.";
632 UnicodeString compareStrGer = "At <time> on 08.08.1997, you made a deposit of ";
633 compareStrGer += (UChar) 0x00a4;
634 compareStrGer += " 456,83.";
635
636 MessageFormat msg( formatStr, err);
637 result = "";
638 FieldPosition pos(0);
639 result = msg.format(
640 arguments,
641 3,
642 result,
643 pos,
644 err);
645
646 logln(result);
647 if (result != compareStrEng) {
648 errln("*** MSG format err.");
649 }
650
651 msg.setLocale(Locale::getEnglish());
652 UBool getLocale_ok = TRUE;
653 if (msg.getLocale() != Locale::getEnglish()) {
654 errln("*** MSG getLocal err.");
655 getLocale_ok = FALSE;
656 }
657
658 msg.setLocale(Locale::getGerman());
659
660 if (msg.getLocale() != Locale::getGerman()) {
661 errln("*** MSG getLocal err.");
662 getLocale_ok = FALSE;
663 }
664
665 msg.applyPattern( formatStr, err);
666
667 pos.setField(0);
668 result = "";
669 result = msg.format(
670 arguments,
671 3,
672 result,
673 pos,
674 err);
675
676 logln(result);
677 if (result == compareStrGer) {
678 logln("MSG setLocale tested.");
679 }else{
680 errln( "*** MSG setLocale err.");
681 }
682
683 if (getLocale_ok) {
684 logln("MSG getLocale tested.");
685 }
686}
687
688void TestMessageFormat::testFormat()
689{
690 UErrorCode err = U_ZERO_ERROR;
691 GregorianCalendar cal(err);
692
693 const Formattable ftarray[] =
694 {
695 Formattable( UDate(8.71068e+011), Formattable::kIsDate )
696 };
697 const int32_t ft_cnt = sizeof(ftarray) / sizeof(Formattable);
698 Formattable ft_arr( ftarray, ft_cnt );
699
700 Formattable* fmt = new Formattable(UDate(8.71068e+011), Formattable::kIsDate);
701
702 UnicodeString result;
703
704 //UnicodeString formatStr = "At {1,time} on {1,date}, you made a {2} of {0,number,currency}.";
705 UnicodeString formatStr = "On {0,date}, it began.";
706 UnicodeString compareStr = "On Aug 8, 1997, it began.";
707
708 err = U_ZERO_ERROR;
709 MessageFormat msg( formatStr, err);
710 FieldPosition fp(0);
711
712 result = "";
713 fp = 0;
714 result = msg.format(
715 *fmt,
716 result,
717 //FieldPosition(0),
718 fp,
719 err);
720
721 if (err != U_ILLEGAL_ARGUMENT_ERROR) {
722 errln("*** MSG format without expected error code.");
723 }
724 err = U_ZERO_ERROR;
725
726 result = "";
727 fp = 0;
728 result = msg.format(
729 ft_arr,
730 result,
731 //FieldPosition(0),
732 fp,
733 err);
734
735 logln("MSG format( Formattable&, ... ) expected:" + compareStr);
736 logln("MSG format( Formattable&, ... ) result:" + result);
737 if (result != compareStr) {
738 errln("*** MSG format( Formattable&, .... ) err.");
739 }else{
740 logln("MSG format( Formattable&, ... ) tested.");
741 }
742
743 delete fmt;
744
745}
746
747void TestMessageFormat::testParse()
748{
749 UErrorCode err = U_ZERO_ERROR;
750 int32_t count;
751 UnicodeString msgFormatString = "{0} =sep= {1}";
752 MessageFormat msg( msgFormatString, err);
753 UnicodeString source = "abc =sep= def";
754 UnicodeString tmp1, tmp2;
755
756 Formattable* fmt_arr = msg.parse( source, count, err );
757 if (U_FAILURE(err) || (!fmt_arr)) {
758 errln("*** MSG parse (ustring, count, err) error.");
759 }else{
760 logln("MSG parse -- count: %d", count);
761 if (count != 2) {
762 errln("*** MSG parse (ustring, count, err) count err.");
763 }else{
764 if ((fmt_arr[0].getType() == Formattable::kString)
765 && (fmt_arr[1].getType() == Formattable::kString)
766 && (fmt_arr[0].getString(tmp1) == "abc")
767 && (fmt_arr[1].getString(tmp2) == "def")) {
768 logln("MSG parse (ustring, count, err) tested.");
769 }else{
770 errln("*** MSG parse (ustring, count, err) result err.");
771 }
772 }
773 }
774 delete[] fmt_arr;
775
776 ParsePosition pp(0);
777
778 fmt_arr = msg.parse( source, pp, count );
779 if ((pp == 0) || (!fmt_arr)) {
780 errln("*** MSG parse (ustring, parsepos., count) error.");
781 }else{
782 logln("MSG parse -- count: %d", count);
783 if (count != 2) {
784 errln("*** MSG parse (ustring, parsepos., count) count err.");
785 }else{
786 if ((fmt_arr[0].getType() == Formattable::kString)
787 && (fmt_arr[1].getType() == Formattable::kString)
788 && (fmt_arr[0].getString(tmp1) == "abc")
789 && (fmt_arr[1].getString(tmp2) == "def")) {
790 logln("MSG parse (ustring, parsepos., count) tested.");
791 }else{
792 errln("*** MSG parse (ustring, parsepos., count) result err.");
793 }
794 }
795 }
796 delete[] fmt_arr;
797
798 pp = 0;
799 Formattable fmta;
800
801 msg.parseObject( source, fmta, pp );
802 if (pp == 0) {
803 errln("*** MSG parse (ustring, Formattable, parsepos ) error.");
804 }else{
805 logln("MSG parse -- count: %d", count);
806 fmta.getArray(count);
807 if (count != 2) {
808 errln("*** MSG parse (ustring, Formattable, parsepos ) count err.");
809 }else{
810 if ((fmta[0].getType() == Formattable::kString)
811 && (fmta[1].getType() == Formattable::kString)
812 && (fmta[0].getString(tmp1) == "abc")
813 && (fmta[1].getString(tmp2) == "def")) {
814 logln("MSG parse (ustring, Formattable, parsepos ) tested.");
815 }else{
816 errln("*** MSG parse (ustring, Formattable, parsepos ) result err.");
817 }
818 }
819 }
820}
821
822
823void TestMessageFormat::testAdopt()
824{
825 UErrorCode err = U_ZERO_ERROR;
826
827 UnicodeString formatStr("{0,date},{1},{2,number}", "");
828 UnicodeString formatStrChange("{0,number},{1,number},{2,date}", "");
829 err = U_ZERO_ERROR;
830 MessageFormat msg( formatStr, err);
831 MessageFormat msgCmp( formatStr, err);
832 int32_t count, countCmp;
833 const Format** formats = msg.getFormats(count);
834 const Format** formatsCmp = msgCmp.getFormats(countCmp);
835 const Format** formatsChg = 0;
836 const Format** formatsAct = 0;
837 int32_t countAct;
838 const Format* a;
839 const Format* b;
840 UnicodeString patCmp;
841 UnicodeString patAct;
842 Format** formatsToAdopt;
843
844 if (!formats || !formatsCmp || (count <= 0) || (count != countCmp)) {
845 errln("Error getting Formats");
846 return;
847 }
848
849 int32_t i;
850
851 for (i = 0; i < count; i++) {
852 a = formats[i];
853 b = formatsCmp[i];
854 if ((a != NULL) && (b != NULL)) {
855 if (*a != *b) {
856 errln("a != b");
857 return;
858 }
859 }else if ((a != NULL) || (b != NULL)) {
860 errln("(a != NULL) || (b != NULL)");
861 return;
862 }
863 }
864
865 msg.applyPattern( formatStrChange, err ); //set msg formats to something different
866 int32_t countChg;
867 formatsChg = msg.getFormats(countChg); // tested function
868 if (!formatsChg || (countChg != count)) {
869 errln("Error getting Formats");
870 return;
871 }
872
873 UBool diff;
874 diff = TRUE;
875 for (i = 0; i < count; i++) {
876 a = formatsChg[i];
877 b = formatsCmp[i];
878 if ((a != NULL) && (b != NULL)) {
879 if (*a == *b) {
374ca955 880 logln("formatsChg == formatsCmp at index %d", i);
b75a7d8f
A
881 diff = FALSE;
882 }
883 }
884 }
885 if (!diff) {
886 errln("*** MSG getFormats diff err.");
887 return;
888 }
889
890 logln("MSG getFormats tested.");
891
892 msg.setFormats( formatsCmp, countCmp ); //tested function
893
894 formatsAct = msg.getFormats(countAct);
895 if (!formatsAct || (countAct <=0) || (countAct != countCmp)) {
896 errln("Error getting Formats");
897 return;
898 }
899
374ca955
A
900 assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove()));
901 assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove()));
b75a7d8f
A
902
903 for (i = 0; i < countAct; i++) {
904 a = formatsAct[i];
905 b = formatsCmp[i];
906 if ((a != NULL) && (b != NULL)) {
907 if (*a != *b) {
908 logln("formatsAct != formatsCmp at index %d", i);
909 errln("a != b");
910 return;
911 }
912 }else if ((a != NULL) || (b != NULL)) {
913 errln("(a != NULL) || (b != NULL)");
914 return;
915 }
916 }
917 logln("MSG setFormats tested.");
918
b75a7d8f
A
919 //----
920
921 msg.applyPattern( formatStrChange, err ); //set msg formats to something different
922
923 formatsToAdopt = new Format* [countCmp];
924 if (!formatsToAdopt) {
925 errln("memory allocation error");
926 return;
927 }
928
929 for (i = 0; i < countCmp; i++) {
930 if (formatsCmp[i] == NULL) {
931 formatsToAdopt[i] = NULL;
932 }else{
933 formatsToAdopt[i] = formatsCmp[i]->clone();
934 if (!formatsToAdopt[i]) {
935 errln("Can't clone format at index %d", i);
936 return;
937 }
938 }
939 }
940 msg.adoptFormats( formatsToAdopt, countCmp ); // function to test
941 delete[] formatsToAdopt;
942
374ca955
A
943 assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove()));
944 assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove()));
b75a7d8f
A
945
946 formatsAct = msg.getFormats(countAct);
947 if (!formatsAct || (countAct <=0) || (countAct != countCmp)) {
948 errln("Error getting Formats");
949 return;
950 }
951
952 for (i = 0; i < countAct; i++) {
953 a = formatsAct[i];
954 b = formatsCmp[i];
955 if ((a != NULL) && (b != NULL)) {
956 if (*a != *b) {
957 errln("a != b");
958 return;
959 }
960 }else if ((a != NULL) || (b != NULL)) {
961 errln("(a != NULL) || (b != NULL)");
962 return;
963 }
964 }
965 logln("MSG adoptFormats tested.");
966
967 //---- adoptFormat
968
969 msg.applyPattern( formatStrChange, err ); //set msg formats to something different
970
971 formatsToAdopt = new Format* [countCmp];
972 if (!formatsToAdopt) {
973 errln("memory allocation error");
974 return;
975 }
976
977 for (i = 0; i < countCmp; i++) {
978 if (formatsCmp[i] == NULL) {
979 formatsToAdopt[i] = NULL;
980 }else{
981 formatsToAdopt[i] = formatsCmp[i]->clone();
982 if (!formatsToAdopt[i]) {
983 errln("Can't clone format at index %d", i);
984 return;
985 }
986 }
987 }
988
989 for ( i = 0; i < countCmp; i++ ) {
990 msg.adoptFormat( i, formatsToAdopt[i] ); // function to test
991 }
992 delete[] formatsToAdopt; // array itself not needed in this case;
993
374ca955
A
994 assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove()));
995 assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove()));
b75a7d8f
A
996
997 formatsAct = msg.getFormats(countAct);
998 if (!formatsAct || (countAct <=0) || (countAct != countCmp)) {
999 errln("Error getting Formats");
1000 return;
1001 }
1002
1003 for (i = 0; i < countAct; i++) {
1004 a = formatsAct[i];
1005 b = formatsCmp[i];
1006 if ((a != NULL) && (b != NULL)) {
1007 if (*a != *b) {
1008 errln("a != b");
1009 return;
1010 }
1011 }else if ((a != NULL) || (b != NULL)) {
1012 errln("(a != NULL) || (b != NULL)");
1013 return;
1014 }
1015 }
1016 logln("MSG adoptFormat tested.");
1017}
1018
1019// This test is a regression test for a fixed bug in the copy constructor.
1020// It is kept as a global function rather than as a method since the test depends on memory values.
1021// (At least before the bug was fixed, whether it showed up or not depended on memory contents,
1022// which is probably why it didn't show up in the regular test for the copy constructor.)
1023// For this reason, the test isn't changed even though it contains function calls whose results are
1024// not tested and had no problems. Actually, the test failed by *crashing*.
1025static void _testCopyConstructor2()
1026{
1027 UErrorCode status = U_ZERO_ERROR;
1028 UnicodeString formatStr("Hello World on {0,date,full}", "");
1029 UnicodeString resultStr(" ", "");
1030 UnicodeString result;
1031 FieldPosition fp(0);
1032 UDate d = Calendar::getNow();
1033 const Formattable fargs( d, Formattable::kIsDate );
1034
1035 MessageFormat* fmt1 = new MessageFormat( formatStr, status );
1036 MessageFormat* fmt2 = new MessageFormat( *fmt1 );
1037 MessageFormat* fmt3;
1038 MessageFormat* fmt4;
1039
1040 if (fmt1 == NULL) it_err("testCopyConstructor2: (fmt1 != NULL)");
1041
1042 result = fmt1->format( &fargs, 1, resultStr, fp, status );
1043
1044 if (fmt2 == NULL) it_err("testCopyConstructor2: (fmt2 != NULL)");
1045
1046 fmt3 = (MessageFormat*) fmt1->clone();
1047 fmt4 = (MessageFormat*) fmt2->clone();
1048
1049 if (fmt3 == NULL) it_err("testCopyConstructor2: (fmt3 != NULL)");
1050 if (fmt4 == NULL) it_err("testCopyConstructor2: (fmt4 != NULL)");
1051
1052 result = fmt1->format( &fargs, 1, resultStr, fp, status );
1053 result = fmt2->format( &fargs, 1, resultStr, fp, status );
1054 result = fmt3->format( &fargs, 1, resultStr, fp, status );
1055 result = fmt4->format( &fargs, 1, resultStr, fp, status );
1056 delete fmt1;
1057 delete fmt2;
1058 delete fmt3;
1059 delete fmt4;
1060}
1061
1062void TestMessageFormat::testCopyConstructor2() {
1063 _testCopyConstructor2();
1064}
1065
1066/**
1067 * Verify that MessageFormat accomodates more than 10 arguments and
1068 * more than 10 subformats.
1069 */
1070void TestMessageFormat::TestUnlimitedArgsAndSubformats() {
1071 UErrorCode ec = U_ZERO_ERROR;
1072 const UnicodeString pattern =
1073 "On {0,date} (aka {0,date,short}, aka {0,date,long}) "
1074 "at {0,time} (aka {0,time,short}, aka {0,time,long}) "
1075 "there were {1,number} werjes "
1076 "(a {3,number,percent} increase over {2,number}) "
1077 "despite the {4}''s efforts "
1078 "and to delight of {5}, {6}, {7}, {8}, {9}, and {10} {11}.";
1079 MessageFormat msg(pattern, ec);
1080 if (U_FAILURE(ec)) {
1081 errln("FAIL: constructor failed");
1082 return;
1083 }
1084
1085 const Formattable ARGS[] = {
1086 Formattable(UDate(1e13), Formattable::kIsDate),
1087 Formattable((int32_t)1303),
1088 Formattable((int32_t)1202),
1089 Formattable(1303.0/1202 - 1),
1090 Formattable("Glimmung"),
1091 Formattable("the printers"),
1092 Formattable("Nick"),
1093 Formattable("his father"),
1094 Formattable("his mother"),
1095 Formattable("the spiddles"),
1096 Formattable("of course"),
1097 Formattable("Horace"),
1098 };
1099 const int32_t ARGS_LENGTH = sizeof(ARGS) / sizeof(ARGS[0]);
1100 Formattable ARGS_OBJ(ARGS, ARGS_LENGTH);
1101
1102 UnicodeString expected =
1103 "On Nov 20, 2286 (aka 11/20/86, aka November 20, 2286) "
1104 "at 9:46:40 AM (aka 9:46 AM, aka 9:46:40 AM PST) "
1105 "there were 1,303 werjes "
1106 "(a 8% increase over 1,202) "
1107 "despite the Glimmung's efforts "
1108 "and to delight of the printers, Nick, his father, "
1109 "his mother, the spiddles, and of course Horace.";
1110 UnicodeString result;
1111 msg.format(ARGS_OBJ, result, ec);
1112 if (result == expected) {
1113 logln(result);
1114 } else {
1115 errln((UnicodeString)"FAIL: Got " + result +
1116 ", expected " + expected);
1117 }
1118}
1119
374ca955
A
1120// test RBNF extensions to message format
1121void TestMessageFormat::TestRBNF(void) {
1122 // WARNING: this depends on the RBNF formats for en_US
1123 Locale locale("en", "US", "");
1124
1125 UErrorCode ec = U_ZERO_ERROR;
1126
1127 UnicodeString values[] = {
1128 // decimal values do not format completely for ordinal or duration, and
1129 // do not always parse, so do not include them
1130 "0", "1", "12", "100", "123", "1001", "123,456", "-17",
1131 };
1132 int32_t values_count = sizeof(values)/sizeof(values[0]);
1133
1134 UnicodeString formats[] = {
1135 "There are {0,spellout} files to search.",
1136 "There are {0,spellout,%simplified} files to search.",
1137 "The bogus spellout {0,spellout,%BOGUS} files behaves like the default.",
1138 "This is the {0,ordinal} file to search.", // TODO fix bug, ordinal does not parse
1139 "Searching this file will take {0,duration} to complete.",
1140 "Searching this file will take {0,duration,%with-words} to complete.",
1141 };
1142 int32_t formats_count = sizeof(formats)/sizeof(formats[0]);
1143
1144 Formattable args[1];
1145
1146 NumberFormat* numFmt = NumberFormat::createInstance(locale, ec);
1147 for (int i = 0; i < formats_count; ++i) {
1148 MessageFormat* fmt = new MessageFormat(formats[i], locale, ec);
1149 logln((UnicodeString)"Testing format pattern: '" + formats[i] + "'");
1150 for (int j = 0; j < values_count; ++j) {
1151 ec = U_ZERO_ERROR;
1152 numFmt->parse(values[j], args[0], ec);
1153 if (U_FAILURE(ec)) {
1154 errln((UnicodeString)"Failed to parse test argument " + values[j]);
1155 } else {
1156 FieldPosition fp(0);
1157 UnicodeString result;
1158 fmt->format(args, 1, result, fp, ec);
1159 logln((UnicodeString)"value: " + toString(args[0]) + " --> " + result + UnicodeString(" ec: ") + u_errorName(ec));
1160
1161 if (i != 3) { // TODO: fix this, for now skip ordinal parsing (format string at index 3)
1162 int32_t count = 0;
1163 Formattable* parseResult = fmt->parse(result, count, ec);
1164 if (count != 1) {
1165 errln((UnicodeString)"parse returned " + count + " args");
1166 } else if (parseResult[0] != args[0]) {
1167 errln((UnicodeString)"parsed argument " + toString(parseResult[0]) + " != " + toString(args[0]));
1168 }
1169 delete []parseResult;
1170 }
1171 }
1172 }
1173 delete fmt;
1174 }
1175 delete numFmt;
1176}
1177
b75a7d8f 1178#endif /* #if !UCONFIG_NO_FORMATTING */