]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/dev/test/format/TestMessageFormat.java
go
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / dev / test / format / TestMessageFormat.java
1 //##header J2SE15
2 /*
3 **********************************************************************
4 * Copyright (c) 2004-2009, International Business Machines
5 * Corporation and others.  All Rights Reserved.
6 **********************************************************************
7 * Author: Alan Liu
8 * Created: April 6, 2004
9 * Since: ICU 3.0
10 **********************************************************************
11 */
12 package com.ibm.icu.dev.test.format;
13
14 import java.text.AttributedCharacterIterator;
15 import java.text.AttributedString;
16 import java.text.ChoiceFormat;
17 import java.text.FieldPosition;
18 import java.text.Format;
19 import java.text.ParseException;
20 import java.text.ParsePosition;
21 import java.util.Date;
22 import java.util.Iterator;
23 import java.util.Locale;
24 import java.util.HashMap;
25 import java.util.Map;
26 import java.util.Set;
27
28 import com.ibm.icu.text.DateFormat;
29 import com.ibm.icu.text.DecimalFormat;
30 import com.ibm.icu.text.DecimalFormatSymbols;
31 import com.ibm.icu.text.MessageFormat;
32 import com.ibm.icu.text.NumberFormat;
33 import com.ibm.icu.text.SimpleDateFormat;
34 import com.ibm.icu.text.UFormat;
35 import com.ibm.icu.util.TimeZone;
36 import com.ibm.icu.util.ULocale;
37
38 public class TestMessageFormat extends com.ibm.icu.dev.test.TestFmwk {
39
40     public static void main(String[] args) throws Exception {
41         new TestMessageFormat().run(args);
42     }
43
44     public void TestBug3()
45     {
46         double myNumber = -123456;
47         DecimalFormat form = null;
48         Locale locale[] = {
49             new Locale("ar", "", ""),
50             new Locale("be", "", ""),
51             new Locale("bg", "", ""),
52             new Locale("ca", "", ""),
53             new Locale("cs", "", ""),
54             new Locale("da", "", ""),
55             new Locale("de", "", ""),
56             new Locale("de", "AT", ""),
57             new Locale("de", "CH", ""),
58             new Locale("el", "", ""),       // 10
59             new Locale("en", "CA", ""),
60             new Locale("en", "GB", ""),
61             new Locale("en", "IE", ""),
62             new Locale("en", "US", ""),
63             new Locale("es", "", ""),
64             new Locale("et", "", ""),
65             new Locale("fi", "", ""),
66             new Locale("fr", "", ""),
67             new Locale("fr", "BE", ""),
68             new Locale("fr", "CA", ""),     // 20
69             new Locale("fr", "CH", ""),
70             new Locale("he", "", ""),
71             new Locale("hr", "", ""),
72             new Locale("hu", "", ""),
73             new Locale("is", "", ""),
74             new Locale("it", "", ""),
75             new Locale("it", "CH", ""),
76             new Locale("ja", "", ""),
77             new Locale("ko", "", ""),
78             new Locale("lt", "", ""),       // 30
79             new Locale("lv", "", ""),
80             new Locale("mk", "", ""),
81             new Locale("nl", "", ""),
82             new Locale("nl", "BE", ""),
83             new Locale("no", "", ""),
84             new Locale("pl", "", ""),
85             new Locale("pt", "", ""),
86             new Locale("ro", "", ""),
87             new Locale("ru", "", ""),
88             new Locale("sh", "", ""),       // 40
89             new Locale("sk", "", ""),
90             new Locale("sl", "", ""),
91             new Locale("sq", "", ""),
92             new Locale("sr", "", ""),
93             new Locale("sv", "", ""),
94             new Locale("tr", "", ""),
95             new Locale("uk", "", ""),
96             new Locale("zh", "", ""),
97             new Locale("zh", "TW", "")      // 49
98         };
99         StringBuffer buffer = new StringBuffer();
100         ParsePosition parsePos = new ParsePosition(0);
101         int i;
102         for (i= 0; i < 49; i++) {
103     //        form = (DecimalFormat)NumberFormat.getCurrencyInstance(locale[i]);
104             form = (DecimalFormat)NumberFormat.getInstance(locale[i]);
105             if (form == null) {
106                 errln("Number format creation failed for " + locale[i].getDisplayName());
107                 continue;
108             }
109             FieldPosition pos = new FieldPosition(0);
110             buffer.setLength(0);
111             form.format(myNumber, buffer, pos);
112             parsePos.setIndex(0);
113             Object result = form.parse(buffer.toString(), parsePos);
114             logln(locale[i].getDisplayName() + " -> " + result);
115             if (parsePos.getIndex() != buffer.length()) {
116                 errln("Number format parse failed.");
117             }
118         }
119     }
120
121     public void TestBug1()
122     {
123         final double limit[] = {0.0, 1.0, 2.0};
124         final String formats[] = {"0.0<=Arg<1.0",
125                                   "1.0<=Arg<2.0",
126                                   "2.0<-Arg"};
127         ChoiceFormat cf = new ChoiceFormat(limit, formats);
128         assertEquals("ChoiceFormat.format", formats[1], cf.format(1));
129     }
130
131     public void TestBug2()
132     {
133         // {sfb} use double format in pattern, so result will match (not strictly necessary)
134         final String pattern = "There {0,choice,0.0#are no files|1.0#is one file|1.0<are {0, number} files} on disk {1}. ";
135         logln("The input pattern : " + pattern);
136         try {
137             MessageFormat fmt = new MessageFormat(pattern);
138             assertEquals("toPattern", pattern, fmt.toPattern());
139         } catch (IllegalArgumentException e) {
140             errln("MessageFormat pattern creation failed.");
141         }
142     }
143
144     public void TestPattern() // aka PatternTest()
145     {
146         Object testArgs[] = {
147             new Double(1), new Double(3456),
148             "Disk", new Date(1000000000L)
149         };
150         String testCases[] = {
151            "Quotes '', '{', 'a' {0} '{0}'",
152            "Quotes '', '{', 'a' {0,number} '{0}'",
153            "'{'1,number,'#',##} {1,number,'#',##}",
154            "There are {1} files on {2} at {3}.",
155            "On {2}, there are {1} files, with {0,number,currency}.",
156            "'{1,number,percent}', {1,number,percent},",
157            "'{1,date,full}', {1,date,full},",
158            "'{3,date,full}', {3,date,full},",
159            "'{1,number,#,##}' {1,number,#,##}",
160         };
161
162         String testResultPatterns[] = {
163             "Quotes '', '{', a {0} '{'0}",
164             "Quotes '', '{', a {0,number} '{'0}",
165             "'{'1,number,#,##} {1,number,'#'#,##}",
166             "There are {1} files on {2} at {3}.",
167             "On {2}, there are {1} files, with {0,number,currency}.",
168             "'{'1,number,percent}, {1,number,percent},",
169             "'{'1,date,full}, {1,date,full},",
170             "'{'3,date,full}, {3,date,full},",
171             "'{'1,number,#,##} {1,number,#,##}"
172         };
173
174         String testResultStrings[] = {
175             "Quotes ', {, a 1 {0}",
176             "Quotes ', {, a 1 {0}",
177             "{1,number,#,##} #34,56",
178             "There are 3,456 files on Disk at 1/12/70 5:46 AM.",
179             "On Disk, there are 3,456 files, with $1.00.",
180             "{1,number,percent}, 345,600%,",
181             "{1,date,full}, Wednesday, December 31, 1969,",
182             "{3,date,full}, Monday, January 12, 1970,",
183             "{1,number,#,##} 34,56"
184         };
185
186         for (int i = 0; i < 9; ++i) {
187             //it_out << "\nPat in:  " << testCases[i]);
188
189             //String buffer;
190             MessageFormat form = null;
191             try {
192                 form = new MessageFormat(testCases[i], Locale.US);
193             } catch (IllegalArgumentException e1) {
194                 errln("MessageFormat for " + testCases[i] + " creation failed.");
195                 continue;
196             }
197             assertEquals("\"" + testCases[i] + "\".toPattern()", testResultPatterns[i], form.toPattern());
198
199             //it_out << "Pat out: " << form.toPattern(buffer));
200             StringBuffer result = new StringBuffer();
201             FieldPosition fieldpos = new FieldPosition(0);
202             form.format(testArgs, result, fieldpos);
203             assertEquals("format", testResultStrings[i], result.toString());
204
205             //it_out << "Result:  " << result);
206     //        /* TODO: Look at this test and see if this is still a valid test */
207     //        logln("---------------- test parse ----------------");
208     //
209     //        int count = 4;
210     //        form.toPattern(buffer);
211     //        logln("MSG pattern for parse: " + buffer);
212     //
213     //        int parseCount = 0;
214     //        Formattable* values = form.parse(result, parseCount, success);
215     //        if (U_FAILURE(success)) {
216     //            errln("MessageFormat failed test #5");
217     //            logln(String("MessageFormat failed test #5 with error code ")+(int)success);
218     //        } else if (parseCount != count) {
219     //            errln("MSG count not %d as expected. Got %d", count, parseCount);
220     //        }
221     //        UBool failed = FALSE;
222     //        for (int j = 0; j < parseCount; ++j) {
223     //             if (values == 0 || testArgs[j] != values[j]) {
224     //                errln(((String)"MSG testargs[") + j + "]: " + toString(testArgs[j]));
225     //                errln(((String)"MSG values[") + j + "]  : " + toString(values[j]));
226     //                failed = TRUE;
227     //             }
228     //        }
229     //        if (failed)
230     //            errln("MessageFormat failed test #6");
231         }
232     }
233
234     public void TestSample() // aka sample()
235     {
236         MessageFormat form = null;
237         StringBuffer buffer2 = new StringBuffer();
238         try {
239             form = new MessageFormat("There are {0} files on {1}");
240         } catch (IllegalArgumentException e1) {
241             errln("Sample message format creation failed.");
242             return;
243         }
244         Object testArgs1[] = { "abc", "def" };
245         FieldPosition fieldpos = new FieldPosition(0);
246         assertEquals("format",
247                      "There are abc files on def",
248                      form.format(testArgs1, buffer2, fieldpos).toString());
249     }
250
251     public void TestStaticFormat()
252     {
253         Object arguments[] = {
254             new Integer(7),
255             new Date(871068000000L),
256             "a disturbance in the Force"
257         };
258
259         assertEquals("format",
260             "At 12:20:00 PM on Aug 8, 1997, there was a disturbance in the Force on planet 7.",
261             MessageFormat.format("At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
262                                  arguments));
263     }
264
265     static final int FieldPosition_DONT_CARE = -1;
266
267     public void TestSimpleFormat()
268     {
269         Object testArgs1[] = {new Integer(0), "MyDisk"};
270         Object testArgs2[] = {new Integer(1), "MyDisk"};
271         Object testArgs3[] = {new Integer(12), "MyDisk"};
272
273         MessageFormat form = new MessageFormat(
274             "The disk \"{1}\" contains {0} file(s).");
275
276         StringBuffer string = new StringBuffer();
277         FieldPosition ignore = new FieldPosition(FieldPosition_DONT_CARE);
278         form.format(testArgs1, string, ignore);
279         assertEquals("format",
280                      "The disk \"MyDisk\" contains 0 file(s).",
281                      string.toString());
282
283         string.setLength(0);
284         form.format(testArgs2, string, ignore);
285         assertEquals("format",
286                      "The disk \"MyDisk\" contains 1 file(s).",
287                      string.toString());
288
289         string.setLength(0);
290         form.format(testArgs3, string, ignore);
291         assertEquals("format",
292                      "The disk \"MyDisk\" contains 12 file(s).",
293                      string.toString());
294     }
295
296     public void TestMsgFormatChoice()
297     {
298         MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0}.");
299         double filelimits[] = {0,1,2};
300         String filepart[] = {"no files","one file","{0,number} files"};
301         ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
302         form.setFormat(1, fileform); // NOT zero, see below
303
304         FieldPosition ignore = new FieldPosition(FieldPosition_DONT_CARE);
305         StringBuffer string = new StringBuffer();
306         Object testArgs1[] = {new Integer(0), "MyDisk"};
307         form.format(testArgs1, string, ignore);
308         assertEquals("format#1",
309                      "The disk \"MyDisk\" contains no files.",
310                      string.toString());
311
312         string.setLength(0);
313         Object testArgs2[] = {new Integer(1), "MyDisk"};
314         form.format(testArgs2, string, ignore);
315         assertEquals("format#2",
316                      "The disk \"MyDisk\" contains one file.",
317                      string.toString());
318
319         string.setLength(0);
320         Object testArgs3[] = {new Integer(1273), "MyDisk"};
321         form.format(testArgs3, string, ignore);
322         assertEquals("format#3",
323                      "The disk \"MyDisk\" contains 1,273 files.",
324                      string.toString());
325     }
326
327     //---------------------------------
328     //  API Tests
329     //---------------------------------
330
331     public void TestClone()
332     {
333         MessageFormat x = new MessageFormat("There are {0} files on {1}");
334         MessageFormat z = new MessageFormat("There are {0} files on {1} created");
335         MessageFormat y = null;
336         y = (MessageFormat)x.clone();
337         if (x.equals(y) &&
338             !x.equals(z) &&
339             !y.equals(z) )
340             logln("First test (operator ==): Passed!");
341         else {
342             errln("First test (operator ==): Failed!");
343         }
344         if ((x.equals(y) && y.equals(x)) &&
345             (!x.equals(z) && !z.equals(x)) &&
346             (!y.equals(z) && !z.equals(y)) )
347             logln("Second test (equals): Passed!");
348         else {
349             errln("Second test (equals): Failed!");
350         }
351
352     }
353
354     public void TestEquals()
355     {
356         MessageFormat x = new MessageFormat("There are {0} files on {1}");
357         MessageFormat y = new MessageFormat("There are {0} files on {1}");
358         if (!x.equals(y)) {
359             errln("First test (operator ==): Failed!");
360         }
361
362     }
363
364     public void TestNotEquals()
365     {
366         MessageFormat x = new MessageFormat("There are {0} files on {1}");
367         MessageFormat y = new MessageFormat("There are {0} files on {1}");
368         y.setLocale(Locale.FRENCH);
369         if (x.equals(y)) {
370             errln("First test (operator !=): Failed!");
371         }
372         y = new MessageFormat("There are {0} files on {1}");
373         y.applyPattern("There are {0} files on {1} the disk");
374         if (x.equals(y)) {
375             errln("Second test (operator !=): Failed!");
376         }
377     }
378
379     public void TestHashCode()
380     {
381         ULocale save = ULocale.getDefault();
382         ULocale.setDefault(ULocale.US);
383
384         MessageFormat x = new MessageFormat("There are {0} files on {1}");
385         MessageFormat z = new MessageFormat("There are {0} files on {1}");
386         MessageFormat y = null;
387         y = (MessageFormat)x.clone();
388         if (x.hashCode() != y.hashCode())
389             errln("FAIL: identical objects have different hashcodes");
390         if (x.hashCode() != z.hashCode())
391             errln("FAIL: identical objects have different hashcodes");
392
393     /* These are not errors
394         y.setLocale(ULocale.FRENCH);
395         if (x.hashCode() == y.hashCode())
396             errln("FAIL: different objects have same hashcodes. Locale ignored");
397
398         z.applyPattern("There are {0} files on {1} the disk");
399         if (x.hashCode() == z.hashCode())
400             errln("FAIL: different objects have same hashcodes. Pattern ignored");
401     */
402
403         ULocale.setDefault(save);
404     }
405
406     public void TestSetLocale()
407     {
408         Object arguments[] = {
409             new Double(456.83),
410             new Date(871068000000L),
411             "deposit"
412             };
413
414         StringBuffer result = new StringBuffer();
415
416         //String formatStr = "At {1,time} on {1,date}, you made a {2} of {0,number,currency}.";
417         String formatStr = "At <time> on {1,date}, you made a {2} of {0,number,currency}.";
418         // {sfb} to get $, would need Locale::US, not Locale::ENGLISH
419         // Just use unlocalized currency symbol.
420         //String compareStrEng = "At <time> on Aug 8, 1997, you made a deposit of $456.83.";
421         String compareStrEng = "At <time> on Aug 8, 1997, you made a deposit of ";
422         compareStrEng += '\u00a4';
423         compareStrEng += "456.83.";
424         // {sfb} to get DM, would need Locale::GERMANY, not Locale::GERMAN
425         // Just use unlocalized currency symbol.
426         //String compareStrGer = "At <time> on 08.08.1997, you made a deposit of 456,83 DM.";
427         String compareStrGer = "At <time> on 08.08.1997, you made a deposit of ";
428         compareStrGer += "456,83\u00a0";
429         compareStrGer += '\u00a4';
430         compareStrGer += ".";
431
432         MessageFormat msg = new MessageFormat(formatStr, Locale.ENGLISH);
433         result.setLength(0);
434         FieldPosition pos = new FieldPosition(0);
435         result = msg.format(
436             arguments,
437             result,
438             pos);
439         assertEquals("format", compareStrEng, result.toString());
440
441         msg.setLocale(Locale.ENGLISH);
442         assertEquals("getLocale", Locale.ENGLISH, msg.getLocale());
443
444         msg.setLocale(Locale.GERMAN);
445         assertEquals("getLocale", Locale.GERMAN, msg.getLocale());
446
447         msg.applyPattern(formatStr);
448         result.setLength(0);
449         result = msg.format(
450             arguments,
451             result,
452             pos);
453         assertEquals("format", compareStrGer, result.toString());
454
455         //Cover getULocale()
456         logln("Testing set/get ULocale ...");
457         msg.setLocale(ULocale.ENGLISH);
458         assertEquals("getULocale", ULocale.ENGLISH, msg.getULocale());
459
460         msg.setLocale(ULocale.GERMAN);
461         assertEquals("getULocale", ULocale.GERMAN, msg.getULocale());
462
463         msg.applyPattern(formatStr);
464         result.setLength(0);
465         result = msg.format(
466             arguments,
467             result,
468             pos);
469         assertEquals("format", compareStrGer, result.toString());
470     }
471
472     public void TestFormat()
473     {
474         final Object ft_arr[] =
475         {
476             new Date(871068000000L)
477         };
478
479         StringBuffer result = new StringBuffer();
480
481         //String formatStr = "At {1,time} on {1,date}, you made a {2} of {0,number,currency}.";
482         String formatStr = "On {0,date}, it began.";
483         String compareStr = "On Aug 8, 1997, it began.";
484
485         MessageFormat msg = new MessageFormat(formatStr);
486         FieldPosition fp = new FieldPosition(0);
487
488         try {
489             msg.format(new Date(871068000000L),
490                        result,
491                        fp);
492             errln("*** MSG format without expected error code.");
493         } catch (Exception e1) {
494         }
495
496         result.setLength(0);
497         result = msg.format(
498             ft_arr,
499             result,
500             fp);
501         assertEquals("format", compareStr, result.toString());
502     }
503
504     public void TestParse()
505     {
506         String msgFormatString = "{0} =sep= {1}";
507         MessageFormat msg = new MessageFormat(msgFormatString);
508         String source = "abc =sep= def";
509
510         try {
511             Object[] fmt_arr = msg.parse(source);
512             if (fmt_arr.length != 2) {
513                 errln("*** MSG parse (ustring, count, err) count err.");
514             } else {
515                 // TODO: This if statement seems to be redundant. [tschumann]
516                 if (fmt_arr.length != 2) {
517                     errln("*** MSG parse (ustring, parsepos., count) count err.");
518                 } else {
519                     assertEquals("parse()[0]", "abc", fmt_arr[0]);
520                     assertEquals("parse()[1]", "def", fmt_arr[1]);
521                 }
522             }
523         } catch (ParseException e1) {
524             errln("*** MSG parse (ustring, count, err) error.");
525         }
526
527         ParsePosition pp = new ParsePosition(0);
528
529         Object[] fmt_arr = msg.parse(source, pp);
530         if (pp.getIndex()==0 || fmt_arr==null) {
531             errln("*** MSG parse (ustring, parsepos., count) error.");
532         } else {
533             if (fmt_arr.length != 2) {
534                 errln("*** MSG parse (ustring, parsepos., count) count err.");
535             } else {
536                 assertEquals("parse()[0]", "abc", fmt_arr[0]);
537                 assertEquals("parse()[1]", "def", fmt_arr[1]);
538             }
539         }
540
541         pp.setIndex(0);
542         Object[] fmta;
543
544         fmta = (Object[]) msg.parseObject( source, pp );
545         if (pp.getIndex() == 0) {
546             errln("*** MSG parse (ustring, Object, parsepos ) error.");
547         } else {
548             if (fmta.length != 2) {
549                 errln("*** MSG parse (ustring, count, err) count err.");
550             } else {
551                 // TODO: Don't we want to check fmta?
552                 //       In this case this if statement would be redundant, too.
553                 //       [tschumann]
554                 if (fmt_arr.length != 2) {
555                     errln("*** MSG parse (ustring, parsepos., count) count err.");
556                 } else {
557                     // TODO: Don't we want to check fmta? [tschumann]
558                     assertEquals("parse()[0]", "abc", fmt_arr[0]);
559                     assertEquals("parse()[1]", "def", fmt_arr[1]);
560                 }
561             }
562         }
563     }
564
565     /**
566      * Of course, in Java there is no adopt, but we retain the same
567      * method name. [alan]
568      */
569     public void TestAdopt()
570     {
571         String formatStr = "{0,date},{1},{2,number}";
572         String formatStrChange = "{0,number},{1,number},{2,date}";
573         MessageFormat msg = new MessageFormat(formatStr);
574         MessageFormat msgCmp = new MessageFormat(formatStr);
575         Format[] formats = msg.getFormats();
576         Format[] formatsCmp = msgCmp.getFormats();
577         Format[] formatsChg = null;
578         Format[] formatsAct = null;
579         Format a = null;
580         Format b = null;
581         Format[] formatsToAdopt = null;
582
583         if (formats==null || formatsCmp==null || (formats.length <= 0) || (formats.length != formatsCmp.length)) {
584             errln("Error getting Formats");
585             return;
586         }
587
588         int i;
589
590         for (i = 0; i < formats.length; i++) {
591             a = formats[i];
592             b = formatsCmp[i];
593             if ((a != null) && (b != null)) {
594                 if (!a.equals(b)) {
595                     errln("a != b");
596                     return;
597                 }
598             } else if ((a != null) || (b != null)) {
599                 errln("(a != null) || (b != null)");
600                 return;
601             }
602         }
603
604         msg.applyPattern( formatStrChange ); //set msg formats to something different
605         formatsChg = msg.getFormats(); // tested function
606         if (formatsChg==null || (formatsChg.length != formats.length)) {
607             errln("Error getting Formats");
608             return;
609         }
610
611         boolean diff;
612         diff = true;
613         for (i = 0; i < formats.length; i++) {
614             a = formatsChg[i];
615             b = formatsCmp[i];
616             if ((a != null) && (b != null)) {
617                 if (a.equals(b)) {
618                     logln("formatsChg == formatsCmp at index " + i);
619                     diff = false;
620                 }
621             }
622         }
623         if (!diff) {
624             errln("*** MSG getFormats diff err.");
625             return;
626         }
627
628         logln("MSG getFormats tested.");
629
630         msg.setFormats( formatsCmp ); //tested function
631
632         formatsAct = msg.getFormats();
633         if (formatsAct==null || (formatsAct.length <=0) || (formatsAct.length != formatsCmp.length)) {
634             errln("Error getting Formats");
635             return;
636         }
637
638         assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern());
639         assertEquals("msg.toPattern()", formatStr, msg.toPattern());
640
641         for (i = 0; i < formatsAct.length; i++) {
642             a = formatsAct[i];
643             b = formatsCmp[i];
644             if ((a != null) && (b != null)) {
645                 if (!a.equals(b)) {
646                     errln("formatsAct != formatsCmp at index " + i);
647                     return;
648                 }
649             } else if ((a != null) || (b != null)) {
650                 errln("(a != null) || (b != null)");
651                 return;
652             }
653         }
654         logln("MSG setFormats tested.");
655
656         //----
657
658         msg.applyPattern( formatStrChange ); //set msg formats to something different
659
660         formatsToAdopt = new Format[formatsCmp.length];
661         if (formatsToAdopt==null) {
662             errln("memory allocation error");
663             return;
664         }
665
666         for (i = 0; i < formatsCmp.length; i++) {
667             if (formatsCmp[i] == null) {
668                 formatsToAdopt[i] = null;
669             } else {
670                 formatsToAdopt[i] = (Format) formatsCmp[i].clone();
671                 if (formatsToAdopt[i]==null) {
672                     errln("Can't clone format at index " + i);
673                     return;
674                 }
675             }
676         }
677         msg.setFormats( formatsToAdopt ); // function to test
678
679         assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern());
680         assertEquals("msg.toPattern()", formatStr, msg.toPattern());
681
682         formatsAct = msg.getFormats();
683         if (formatsAct==null || (formatsAct.length <=0) || (formatsAct.length != formatsCmp.length)) {
684             errln("Error getting Formats");
685             return;
686         }
687
688         for (i = 0; i < formatsAct.length; i++) {
689             a = formatsAct[i];
690             b = formatsCmp[i];
691             if ((a != null) && (b != null)) {
692                 if (!a.equals(b)) {
693                     errln("a != b");
694                     return;
695                 }
696             } else if ((a != null) || (b != null)) {
697                 errln("(a != null) || (b != null)");
698                 return;
699             }
700         }
701         logln("MSG adoptFormats tested.");
702
703         //---- adoptFormat
704
705         msg.applyPattern( formatStrChange ); //set msg formats to something different
706
707         formatsToAdopt = new Format[formatsCmp.length];
708         if (formatsToAdopt==null) {
709             errln("memory allocation error");
710             return;
711         }
712
713         for (i = 0; i < formatsCmp.length; i++) {
714             if (formatsCmp[i] == null) {
715                 formatsToAdopt[i] = null;
716             } else {
717                 formatsToAdopt[i] = (Format) formatsCmp[i].clone();
718                 if (formatsToAdopt[i]==null) {
719                     errln("Can't clone format at index " + i);
720                     return;
721                 }
722             }
723         }
724
725         for ( i = 0; i < formatsCmp.length; i++ ) {
726             msg.setFormat( i, formatsToAdopt[i] ); // function to test
727         }
728
729         assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern());
730         assertEquals("msg.toPattern()", formatStr, msg.toPattern());
731
732         formatsAct = msg.getFormats();
733         if (formatsAct==null || (formatsAct.length <=0) || (formatsAct.length != formatsCmp.length)) {
734             errln("Error getting Formats");
735             return;
736         }
737
738         for (i = 0; i < formatsAct.length; i++) {
739             a = formatsAct[i];
740             b = formatsCmp[i];
741             if ((a != null) && (b != null)) {
742                 if (!a.equals(b)) {
743                     errln("a != b");
744                     return;
745                 }
746             } else if ((a != null) || (b != null)) {
747                 errln("(a != null) || (b != null)");
748                 return;
749             }
750         }
751         logln("MSG adoptFormat tested.");
752     }
753
754     /**
755      * Verify that MessageFormat accomodates more than 10 arguments and
756      * more than 10 subformats.
757      */
758     public void TestUnlimitedArgsAndSubformats() {
759         final String pattern =
760             "On {0,date} (aka {0,date,short}, aka {0,date,long}) "+
761             "at {0,time} (aka {0,time,short}, aka {0,time,long}) "+
762             "there were {1,number} werjes "+
763             "(a {3,number,percent} increase over {2,number}) "+
764             "despite the {4}''s efforts "+
765             "and to delight of {5}, {6}, {7}, {8}, {9}, and {10} {11}.";
766         try {
767             MessageFormat msg = new MessageFormat(pattern);
768
769             final Object ARGS[] = {
770                 new Date(10000000000000L),
771                 new Integer(1303),
772                 new Integer(1202),
773                 new Double(1303.0/1202 - 1),
774                 "Glimmung",
775                 "the printers",
776                 "Nick",
777                 "his father",
778                 "his mother",
779                 "the spiddles",
780                 "of course",
781                 "Horace"
782             };
783
784             String expected =
785                 "On Nov 20, 2286 (aka 11/20/86, aka November 20, 2286) "+
786                 "at 9:46:40 AM (aka 9:46 AM, aka 9:46:40 AM PST) "+
787                 "there were 1,303 werjes "+
788                 "(a 8% increase over 1,202) "+
789                 "despite the Glimmung's efforts "+
790                 "and to delight of the printers, Nick, his father, "+
791                 "his mother, the spiddles, and of course Horace.";
792             assertEquals("format", expected, msg.format(ARGS));
793         } catch (IllegalArgumentException e1) {
794             errln("FAIL: constructor failed");
795         }
796     }
797
798     // test RBNF extensions to message format
799     public void TestRBNF() {
800         // WARNING: this depends on the RBNF formats for en_US
801         Locale locale = Locale.US;
802         String[] values = {
803             // decimal values do not format completely for ordinal or duration, and
804             // do not always parse, so do not include them
805             "0", "1", "12", "100", "123", "1001", "123,456", "-17",
806         };
807         String[] formats = {
808             "There are {0,spellout} files to search.",
809             "There are {0,spellout,%simplified} files to search.",
810             "The bogus spellout {0,spellout,%BOGUS} files behaves like the default.",
811             "This is the {0,ordinal} file to search.", // TODO fix bug, ordinal does not parse
812             "Searching this file will take {0,duration} to complete.",
813             "Searching this file will take {0,duration,%with-words} to complete.",
814         };
815         final NumberFormat numFmt = NumberFormat.getInstance(locale);
816         Object[] args = new Object[1];
817         Number num = null;
818         for (int i = 0; i < formats.length; ++i) {
819             MessageFormat fmt = new MessageFormat(formats[i], locale);
820             logln("Testing format pattern: '" + formats[i] + "'");
821             for (int j = 0; j < values.length; ++j) {
822                 try {
823                     num = numFmt.parse(values[j]);
824                 }
825                 catch (Exception e) {
826                     throw new IllegalStateException("failed to parse test argument");
827                 }
828                 args[0] = num;
829                 String result = fmt.format(args);
830                 logln("value: " + num + " --> " + result);
831
832                 if (i != 3) { // TODO: fix this, for now skip ordinal parsing (format string at index 3)
833                     try {
834                         Object[] parsedArgs = fmt.parse(result);
835                         if (parsedArgs.length != 1) {
836                             errln("parse returned " + parsedArgs.length + " args");
837                         } else if (!parsedArgs[0].equals(num)) {
838                             errln("parsed argument " + parsedArgs[0] + " != " + num);
839                         }
840                     }
841                     catch (Exception e) {
842                         errln("parse of '" + result + " returned exception: " + e.getMessage());
843                     }
844                 }
845             }
846         }
847     }
848
849     public void TestSetGetFormats()
850     {
851         Object arguments[] = {
852             new Double(456.83),
853             new Date(871068000000L),
854             "deposit"
855             };
856
857         StringBuffer result = new StringBuffer();
858
859         String formatStr = "At <time> on {1,date}, you made a {2} of {0,number,currency}.";
860         // original expected format result
861         String compareStr = "At <time> on Aug 8, 1997, you made a deposit of $456.83.";
862         // the date being German-style, but the currency being English-style
863         String compareStr2 = "At <time> on 08.08.1997, you made a deposit of ";
864         compareStr2 += '\u00a4';
865         compareStr2 += "456.83.";
866         // both date and currency formats are German-style
867         String compareStr3 = "At <time> on 08.08.1997, you made a deposit of ";
868         compareStr3 += "456,83\u00a0";
869         compareStr3 += '\u00a4';
870         compareStr3 += ".";
871
872         MessageFormat msg = new MessageFormat(formatStr, ULocale.US);
873         result.setLength(0);
874         FieldPosition pos = new FieldPosition(0);
875         result = msg.format(
876             arguments,
877             result,
878             pos);
879         assertEquals("format", compareStr, result.toString());
880
881         // constructs a Format array with a English-style Currency formatter
882         //                            and a German-style Date formatter
883         //      might not meaningful, just for testing setFormatsByArgIndex
884         Format[] fmts = new Format[] {
885             NumberFormat.getCurrencyInstance(ULocale.ENGLISH),
886             DateFormat.getDateInstance(DateFormat.DEFAULT, ULocale.GERMAN)
887             };
888
889         msg.setFormatsByArgumentIndex(fmts);
890         result.setLength(0);
891         pos = new FieldPosition(0);
892         result = msg.format(
893             arguments,
894             result,
895             pos);
896         assertEquals("format", compareStr2, result.toString());
897
898         // Construct a German-style Currency formatter, replace the corresponding one
899         // Thus both formatters should format objects with German-style
900         Format newFmt = NumberFormat.getCurrencyInstance(ULocale.GERMAN);
901         msg.setFormatByArgumentIndex(0, newFmt);
902         result.setLength(0);
903         pos = new FieldPosition(0);
904         result = msg.format(
905             arguments,
906             result,
907             pos);
908         assertEquals("format", compareStr3, result.toString());
909
910         // verify getFormatsByArgumentIndex
911         //   you should got three formats by that
912         //          - DecimalFormat     locale: de
913         //          - SimpleDateFormat  locale: de
914         //          - null
915         Format[] fmts2 = msg.getFormatsByArgumentIndex();
916         assertEquals("1st subformmater: Format Class", "com.ibm.icu.text.DecimalFormat", fmts2[0].getClass().getName());
917         assertEquals("1st subformmater: its Locale", ULocale.GERMAN, ((UFormat)fmts2[0]).getLocale(ULocale.VALID_LOCALE));
918         assertEquals("2nd subformatter: Format Class", "com.ibm.icu.text.SimpleDateFormat", fmts2[1].getClass().getName());
919         assertEquals("2nd subformmater: its Locale", ULocale.GERMAN, ((UFormat)fmts2[1]).getLocale(ULocale.VALID_LOCALE));
920         assertTrue("The third subFormatter is null", null == fmts2[2]);
921     }
922
923     // Test the fix pattern api
924     public void TestAutoQuoteApostrophe() {
925         final String[] patterns = { // new pattern, expected pattern
926             "'", "''",
927             "''", "''",
928             "'{", "'{'",
929             "' {", "'' {",
930             "'a", "''a",
931             "'{'a", "'{'a",
932             "'{a'", "'{a'",
933             "'{}", "'{}'",
934             "{'", "{'",
935             "{'a", "{'a",
936             "{'a{}'a}'a", "{'a{}'a}''a",
937             "'}'", "'}'",
938             "'} '{'}'", "'} '{'}''",
939             "'} {{{''", "'} {{{'''",
940         };
941         for (int i = 0; i < patterns.length; i += 2) {
942             assertEquals("[" + (i/2) + "] \"" + patterns[i] + "\"", patterns[i+1], MessageFormat.autoQuoteApostrophe(patterns[i]));
943         }
944     }
945     
946     // This tests passing named arguments instead of numbers to format(). 
947     public void testFormatNamedArguments() {
948         Map arguments = new HashMap();
949         arguments.put("startDate", new Date(871068000000L));
950
951         StringBuffer result = new StringBuffer();
952         
953         String formatStr = "On {startDate,date}, it began.";
954         String compareStr = "On Aug 8, 1997, it began.";
955
956         MessageFormat msg = new MessageFormat(formatStr);
957         FieldPosition fp = new FieldPosition(0);
958
959         try {
960             msg.format(arguments.get("startDate"), result, fp);
961             errln("*** MSG format without expected error code.");
962         } catch (Exception e1) {
963         }
964
965         result.setLength(0);
966         result = msg.format(
967             arguments,
968             result,
969             fp);
970         assertEquals("format", compareStr, result.toString());
971     }
972     
973     // This tests parsing formatted messages with named arguments instead of
974     // numbers. 
975     public void testParseNamedArguments() {
976         String msgFormatString = "{foo} =sep= {bar}";
977         MessageFormat msg = new MessageFormat(msgFormatString);
978         String source = "abc =sep= def";
979
980         try {
981             Map fmt_map = msg.parseToMap(source);
982             if (fmt_map.keySet().size() != 2) {
983                 errln("*** MSG parse (ustring, count, err) count err.");
984             } else {
985                 assertEquals("parse()[0]", "abc", fmt_map.get("foo"));
986                 assertEquals("parse()[1]", "def", fmt_map.get("bar"));
987             }
988         } catch (ParseException e1) {
989             errln("*** MSG parse (ustring, count, err) error.");
990         }
991
992         ParsePosition pp = new ParsePosition(0);
993         Map fmt_map = msg.parseToMap(source, pp); 
994         if (pp.getIndex()==0 || fmt_map==null) {
995             errln("*** MSG parse (ustring, parsepos., count) error.");
996         } else {
997             if (fmt_map.keySet().size() != 2) {
998                 errln("*** MSG parse (ustring, parsepos., count) count err.");
999             } else {
1000                 assertEquals("parse()[0]", "abc", fmt_map.get("foo"));
1001                 assertEquals("parse()[1]", "def", fmt_map.get("bar"));
1002             }
1003         }
1004
1005         pp.setIndex(0);
1006        
1007         Map fmta = (Map) msg.parseObject( source, pp );
1008         if (pp.getIndex() == 0) {
1009             errln("*** MSG parse (ustring, Object, parsepos ) error.");
1010         } else {
1011             if (fmta.keySet().size() != 2) {
1012                 errln("*** MSG parse (ustring, count, err) count err.");
1013             } else {
1014                 assertEquals("parse()[0]", "abc", fmta.get("foo"));
1015                 assertEquals("parse()[1]", "def", fmta.get("bar"));
1016             }
1017         }
1018     }
1019     
1020     // Ensure that methods designed for numeric arguments only, will throw
1021     // an exception when called on MessageFormat objects created with
1022     // named arguments.
1023     public void testNumericOnlyMethods() {
1024         MessageFormat msg = new MessageFormat("Number of files: {numfiles}");
1025         boolean gotException = false;
1026         try {
1027             Format fmts[] = {new DecimalFormat()};
1028             msg.setFormatsByArgumentIndex(fmts);
1029         } catch (IllegalArgumentException e) {
1030             gotException = true;
1031         }
1032         if (!gotException) {
1033             errln("MessageFormat.setFormatsByArgumentIndex() should throw an " +
1034                   "IllegalArgumentException when called on formats with " + 
1035                   "named arguments but did not!");
1036         }
1037         
1038         gotException = false;
1039         try {
1040             msg.setFormatByArgumentIndex(0, new DecimalFormat());
1041         } catch (IllegalArgumentException e) {
1042             gotException = true;
1043         }
1044         if (!gotException) {
1045             errln("MessageFormat.setFormatByArgumentIndex() should throw an " +
1046                   "IllegalArgumentException when called on formats with " + 
1047                   "named arguments but did not!");
1048         }
1049         
1050         gotException = false;
1051         try {
1052             msg.getFormatsByArgumentIndex();
1053         } catch (IllegalArgumentException e) {
1054             gotException = true;
1055         }
1056         if (!gotException) {
1057             errln("MessageFormat.getFormatsByArgumentIndex() should throw an " +
1058                   "IllegalArgumentException when called on formats with " + 
1059                   "named arguments but did not!");
1060         }
1061         
1062         gotException = false;
1063         try {
1064             Object args[] = {new Long(42)};
1065             msg.format(args, new StringBuffer(), new FieldPosition(0));
1066         } catch (IllegalArgumentException e) {
1067             gotException = true;
1068         }
1069         if (!gotException) {
1070             errln("MessageFormat.format(Object[], StringBuffer, FieldPosition) " +
1071                   "should throw an IllegalArgumentException when called on " + 
1072                   "formats with named arguments but did not!");
1073         }
1074         
1075         gotException = false;
1076         try {
1077             Object args[] = {new Long(42)};
1078             msg.format((Object) args, new StringBuffer(), new FieldPosition(0));
1079         } catch (IllegalArgumentException e) {
1080             gotException = true;
1081         }
1082         if (!gotException) {
1083             errln("MessageFormat.format(Object, StringBuffer, FieldPosition) " +
1084                   "should throw an IllegalArgumentException when called with " +
1085                   "non-Map object as argument on formats with named " + 
1086                   "arguments but did not!");
1087         }
1088         
1089         gotException = false;
1090         try {
1091             msg.parse("Number of files: 5", new ParsePosition(0));
1092         } catch (IllegalArgumentException e) {
1093             gotException = true;
1094         }
1095         if (!gotException) {
1096             errln("MessageFormat.parse(String, ParsePosition) " +
1097                   "should throw an IllegalArgumentException when called with " +
1098                   "non-Map object as argument on formats with named " + 
1099                   "arguments but did not!");
1100         }
1101         
1102         gotException = false;
1103         try {
1104             msg.parse("Number of files: 5");
1105         } catch (IllegalArgumentException e) {
1106             gotException = true;
1107         } catch (ParseException e) {
1108             errln("Wrong exception thrown.");
1109         }
1110         if (!gotException) {
1111             errln("MessageFormat.parse(String) " +
1112                   "should throw an IllegalArgumentException when called with " +
1113                   "non-Map object as argument on formats with named " + 
1114                   "arguments but did not!");
1115         }
1116     }
1117     
1118     public void testNamedArguments() {
1119         // Ensure that mixed argument types are not allowed.
1120         // Either all arguments have to be numeric or valid identifiers.
1121         try {
1122             new MessageFormat("Number of files in folder {0}: {numfiles}");
1123             errln("Creating a MessageFormat with mixed argument types " + 
1124                     "(named and numeric) should throw an " + 
1125                     "IllegalArgumentException but did not!");
1126         } catch (IllegalArgumentException e) {}
1127         
1128         try {
1129             new MessageFormat("Number of files in folder {folder}: {1}");
1130             errln("Creating a MessageFormat with mixed argument types " + 
1131                     "(named and numeric) should throw an " + 
1132                     "IllegalArgumentException but did not!");
1133         } catch (IllegalArgumentException e) {}
1134         
1135         // Test named arguments.
1136         MessageFormat mf = new MessageFormat("Number of files in folder {folder}: {numfiles}");
1137         if (!mf.usesNamedArguments()) {
1138             errln("message format 1 should have used named arguments");
1139         }
1140         mf = new MessageFormat("Wavelength:  {\u028EValue\uFF14}");
1141         if (!mf.usesNamedArguments()) {
1142             errln("message format 2 should have used named arguments");
1143         }
1144         
1145         // Test argument names with invalid start characters.
1146         try {
1147             new MessageFormat("Wavelength:  {_\u028EValue\uFF14}");
1148             errln("Creating a MessageFormat with invalid argument names " + 
1149             "should throw an IllegalArgumentException but did not!");
1150         } catch (IllegalArgumentException e) {}
1151         
1152         try {
1153             new MessageFormat("Wavelength:  {\uFF14\u028EValue}");
1154             errln("Creating a MessageFormat with invalid argument names " + 
1155             "should throw an IllegalArgumentException but did not!");
1156         } catch (IllegalArgumentException e) {}
1157         
1158         // Test argument names with invalid continue characters.
1159         try {
1160             new MessageFormat("Wavelength:  {Value@\uFF14}");
1161             errln("Creating a MessageFormat with invalid argument names " + 
1162             "should throw an IllegalArgumentException but did not!");
1163         } catch (IllegalArgumentException e) {}
1164         
1165         try {
1166             new MessageFormat("Wavelength:  {Value(\uFF14)}");
1167             errln("Creating a MessageFormat with invalid argument names " + 
1168             "should throw an IllegalArgumentException but did not!");
1169         } catch (IllegalArgumentException e) {}        
1170     }
1171
1172     public void testNumericFormatWithMap() {
1173         MessageFormat mf = new MessageFormat("X:{2} Y:{1}");
1174         if (mf.usesNamedArguments()) {
1175             errln("should not use named arguments");
1176         }
1177
1178         Map map12 = new HashMap();
1179         map12.put("1", "one");
1180         map12.put("2", "two");
1181
1182         String target = "X:two Y:one";
1183         String result = mf.format(map12);
1184         if (!target.equals(result)) {
1185             errln("expected '" + target + "' but got '" + result + "'");
1186         }
1187
1188         try {
1189             Map mapResult = mf.parseToMap(target);
1190             if (!map12.equals(mapResult)) {
1191                 errln("expected " + map12 + " but got " + mapResult);
1192             }
1193         } catch (ParseException e) {
1194             errln("unexpected exception: " + e.getMessage());
1195         }
1196
1197         Map map10 = new HashMap();
1198         map10.put("1", "one");
1199         map10.put("0", "zero");
1200         target = "X:{2} Y:one";
1201         result = mf.format(map10);
1202         if (!target.equals(result)) {
1203             errln("expected '" + target + "' but got '" + result + "'");
1204         }
1205
1206         DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM);
1207         DateFormat timeFormat = DateFormat.getTimeInstance(DateFormat.MEDIUM);
1208         Map fmtMap = new HashMap();
1209         fmtMap.put("1", dateFormat);
1210         fmtMap.put("2", timeFormat);
1211         mf.setFormatsByArgumentName(fmtMap);
1212         Date date = new Date(661439820000L);
1213
1214         try {
1215             result = mf.format(map12); // should fail, wrong argument type
1216             fail("expected exception but got '" + result + "'");
1217         } catch (IllegalArgumentException e) {
1218             // expect this
1219         }
1220
1221         Map argMap = new HashMap();
1222         argMap.put("1", date);
1223         argMap.put("2", date);
1224         target = "X:5:17:00 AM Y:Dec 17, 1990";
1225         result = mf.format(argMap);
1226         if (!target.equals(result)) {
1227             errln("expected '" + target + "' but got '" + result + "'");
1228         }
1229     }
1230
1231     // This tests nested Formats inside PluralFormat.
1232     public void testNestedFormatsInPluralFormat() {
1233         try {
1234             MessageFormat msgFmt = new MessageFormat(
1235                     "{0, plural, one {{0, number,C''''est #,##0.0# fichier}} " +
1236                     "other {Ce sont # fichiers}} dans la liste.",
1237                     new ULocale("fr"));
1238             Object objArray[] = {new Long(0)};
1239             HashMap objMap = new HashMap();
1240             objMap.put("argument", objArray[0]);
1241             String result = msgFmt.format(objArray);
1242             if (!result.equals("C'est 0,0 fichier dans la liste.")) {
1243                 errln("PluralFormat produced wrong message string.");
1244             }
1245         } catch (Exception e) {
1246             e.printStackTrace();
1247             throw new RuntimeException(e.getMessage());
1248         }
1249     }
1250
1251     // This tests PluralFormats used inside MessageFormats.
1252     public void testPluralFormat() {
1253         {
1254             MessageFormat mfNum = new MessageFormat(
1255                     "{0, plural, one{C''est # fichier} other " + 
1256                       "{Ce sont # fichiers}} dans la liste.",
1257                     new ULocale("fr"));
1258             MessageFormat mfAlpha = new MessageFormat(
1259                     "{argument, plural, one{C''est # fichier} other {Ce " +
1260                       "sont # fichiers}} dans la liste.",
1261                     new ULocale("fr"));
1262             Object objArray[] = {new Long(0)};
1263             HashMap objMap = new HashMap();
1264             objMap.put("argument", objArray[0]);
1265             String result = mfNum.format(objArray);
1266             if (!result.equals(mfAlpha.format(objMap))) {
1267                 errln("PluralFormat's output differs when using named " + 
1268                         "arguments instead of numbers!");
1269             }
1270             if (!result.equals("C'est 0 fichier dans la liste.")) {
1271                 errln("PluralFormat produced wrong message string.");
1272             }
1273         }
1274         {
1275             MessageFormat mfNum = new MessageFormat (
1276                     "There {0, plural, one{is # zavod}few{are {0, " +
1277                       "number,###.0} zavoda} other{are # zavodov}} in the " +
1278                       "directory.",
1279                     new ULocale("ru"));
1280             MessageFormat mfAlpha = new MessageFormat (
1281                     "There {argument, plural, one{is # zavod}few{" +
1282                       "are {argument, number,###.0} zavoda} other{are # " + 
1283                       "zavodov}} in the directory.",
1284                     new ULocale("ru"));
1285             Object objArray[] = {new Long(4)};
1286             HashMap objMap = new HashMap();
1287             objMap.put("argument", objArray[0]);
1288             String result = mfNum.format(objArray);
1289             if (!result.equals(mfAlpha.format(objMap))) {
1290                 errln("PluralFormat's output differs when using named " + 
1291                         "arguments instead of numbers!");
1292             }
1293             if (!result.equals("There are 4,0 zavoda in the directory.")) {
1294                 errln("PluralFormat produced wrong message string.");
1295             }
1296         }
1297     }
1298
1299   // Test toPattern when there is a PluralFormat
1300   public void testPluralFormatToPattern() {
1301     String[] patterns = {
1302       "Beware of vicious {0, plural, one {hamster} other {hamsters}}.",
1303       "{0, plural, one {{0, number,C''''est #,##0.0# fichier}} other {Ce sont # fichiers}} dans la liste.",
1304       "{0, plural, one {C''est # fichier} other {Ce sont # fichiers}} dans la liste.",
1305     };
1306
1307     for (int i = 0; i < patterns.length; ++i) {
1308       String pattern = patterns[i];
1309       MessageFormat mf = new MessageFormat(pattern);
1310       MessageFormat mf2 = new MessageFormat(mf.toPattern());
1311       if (!mf.equals(mf2)) {
1312         errln("message formats not equal for pattern:\n*** '" + pattern + "'\n*** '" +
1313               mf.toPattern() + "'");
1314       }
1315     }
1316   }
1317
1318     // Test case for null arguments.
1319     // Ticket#6361
1320     public void TestNullArgs() {
1321         MessageFormat msgfmt = new MessageFormat("{0} - {1}");
1322         Object[][] TEST_CASES = {
1323             {null,                          "{0} - {1}"},
1324             {new Object[] {null},           "null - {1}"},
1325             {new Object[] {null, null},     "null - null"},
1326             {new Object[] {"one"},          "one - {1}"},
1327             {new Object[] {"one", null},    "one - null"},
1328             {new Object[] {null, "two"},    "null - two"},
1329         };
1330
1331         for (int i = 0; i < TEST_CASES.length; i++) {
1332             String text = msgfmt.format(TEST_CASES[i][0]);
1333             if (!text.equals(TEST_CASES[i][1])) {
1334                 errln("FAIL: Returned[" + text + "] Expected[" + TEST_CASES[i][1] + "]");
1335             }
1336         }
1337     }
1338     
1339     public void TestSetFormat() {
1340         MessageFormat ms = new MessageFormat("{number} {date}", ULocale.ENGLISH);
1341         final DecimalFormat decimalFormat = new DecimalFormat("000.000", DecimalFormatSymbols.getInstance(ULocale.ENGLISH));
1342         ms.setFormatByArgumentName("number", decimalFormat);
1343         final SimpleDateFormat dateFormat = new SimpleDateFormat("'year:'yy 'month:'MM 'day:'dd");
1344         dateFormat.setTimeZone(TimeZone.getTimeZone("Etc/GMT"));
1345         ms.setFormatByArgumentName("date", dateFormat);
1346         Map map = new HashMap();
1347         map.put("number", new Integer(1234));
1348         map.put("date", new Date(0,0,0));
1349         String result = ms.format(map);
1350         assertEquals("setFormatByArgumentName", "1234.000 year:99 month:12 day:31", result);
1351         Set formatNames = ms.getFormatArgumentNames();
1352         assertEquals("Format Names match", formatNames, map.keySet());
1353         assertEquals("Decimal", decimalFormat, ms.getFormatByArgumentName("number"));
1354         assertEquals("Date", dateFormat, ms.getFormatByArgumentName("date"));
1355     }
1356
1357 //#if defined(FOUNDATION10) || defined(J2SE13)
1358 //#else
1359     // Test case for formatToCharacterIterator
1360     public void TestFormatToCharacterIterator() {
1361         MessageFormat[] msgfmts = {
1362             new MessageFormat("The {3,ordinal} folder ''{0}'' contains {2,number} file(s), created at {1,time} on {1,date}."),
1363             new MessageFormat("The {arg3,ordinal} folder ''{arg0}'' contains {arg2,number} file(s), created at {arg1,time} on {arg1,date}."), // same as above, but named args
1364             new MessageFormat("The folder contains {0}.")
1365         };
1366
1367         double filelimits[] = {0,1,2};
1368         String filepart[] = {"no files","one file","{0,number} files"};
1369         ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
1370         msgfmts[2].setFormat(0, fileform);
1371
1372         
1373         Object[] args0 = new Object[] {"tmp", new Date(1184777888000L), new Integer(15), new Integer(2)};
1374
1375         HashMap args1 = new HashMap();
1376         args1.put("arg0", "tmp");
1377         args1.put("arg1", new Date(1184777888000L));
1378         args1.put("arg2", new Integer(15));
1379         args1.put("arg3", new Integer(2));
1380
1381         Object[] args2 = new Object[] {new Integer(34)};
1382
1383         Object[] args = {
1384             args0,
1385             args1,
1386             args2
1387         };
1388         
1389         String[] expectedStrings = {
1390             "The 2\u207f\u1d48 folder 'tmp' contains 15 file(s), created at 9:58:08 AM on Jul 18, 2007.",
1391             "The 2\u207f\u1d48 folder 'tmp' contains 15 file(s), created at 9:58:08 AM on Jul 18, 2007.",
1392             "The folder contains 34 files."
1393         };
1394
1395         AttributedString[] expectedAttributedStrings = {
1396             new AttributedString(expectedStrings[0]),
1397             new AttributedString(expectedStrings[1]),
1398             new AttributedString(expectedStrings[2])
1399         };
1400
1401         // Add expected attributes to the expectedAttributedStrings[0]
1402         expectedAttributedStrings[0].addAttribute(MessageFormat.Field.ARGUMENT, new Integer(3), 4, 7);
1403         expectedAttributedStrings[0].addAttribute(MessageFormat.Field.ARGUMENT, new Integer(0), 16, 19);
1404         expectedAttributedStrings[0].addAttribute(MessageFormat.Field.ARGUMENT, new Integer(2), 30, 32);
1405         expectedAttributedStrings[0].addAttribute(NumberFormat.Field.INTEGER, NumberFormat.Field.INTEGER, 30, 32);
1406         expectedAttributedStrings[0].addAttribute(MessageFormat.Field.ARGUMENT, new Integer(1), 53, 63);
1407         expectedAttributedStrings[0].addAttribute(DateFormat.Field.HOUR1, DateFormat.Field.HOUR1, 53, 54);
1408         expectedAttributedStrings[0].addAttribute(DateFormat.Field.MINUTE, DateFormat.Field.MINUTE, 55, 57);
1409         expectedAttributedStrings[0].addAttribute(DateFormat.Field.SECOND, DateFormat.Field.SECOND, 58, 60);
1410         expectedAttributedStrings[0].addAttribute(DateFormat.Field.AM_PM, DateFormat.Field.AM_PM, 61, 63);
1411         expectedAttributedStrings[0].addAttribute(MessageFormat.Field.ARGUMENT, new Integer(1), 67, 79);
1412         expectedAttributedStrings[0].addAttribute(DateFormat.Field.MONTH, DateFormat.Field.MONTH, 67, 70);
1413         expectedAttributedStrings[0].addAttribute(DateFormat.Field.DAY_OF_MONTH, DateFormat.Field.DAY_OF_MONTH, 71, 73);
1414         expectedAttributedStrings[0].addAttribute(DateFormat.Field.YEAR, DateFormat.Field.YEAR, 75, 79);
1415
1416         // Add expected attributes to the expectedAttributedStrings[1]
1417         expectedAttributedStrings[1].addAttribute(MessageFormat.Field.ARGUMENT, "arg3", 4, 7);
1418         expectedAttributedStrings[1].addAttribute(MessageFormat.Field.ARGUMENT, "arg0", 16, 19);
1419         expectedAttributedStrings[1].addAttribute(MessageFormat.Field.ARGUMENT, "arg2", 30, 32);
1420         expectedAttributedStrings[1].addAttribute(NumberFormat.Field.INTEGER, NumberFormat.Field.INTEGER, 30, 32);
1421         expectedAttributedStrings[1].addAttribute(MessageFormat.Field.ARGUMENT, "arg1", 53, 63);
1422         expectedAttributedStrings[1].addAttribute(DateFormat.Field.HOUR1, DateFormat.Field.HOUR1, 53, 54);
1423         expectedAttributedStrings[1].addAttribute(DateFormat.Field.MINUTE, DateFormat.Field.MINUTE, 55, 57);
1424         expectedAttributedStrings[1].addAttribute(DateFormat.Field.SECOND, DateFormat.Field.SECOND, 58, 60);
1425         expectedAttributedStrings[1].addAttribute(DateFormat.Field.AM_PM, DateFormat.Field.AM_PM, 61, 63);
1426         expectedAttributedStrings[1].addAttribute(MessageFormat.Field.ARGUMENT, "arg1", 67, 79);
1427         expectedAttributedStrings[1].addAttribute(DateFormat.Field.MONTH, DateFormat.Field.MONTH, 67, 70);
1428         expectedAttributedStrings[1].addAttribute(DateFormat.Field.DAY_OF_MONTH, DateFormat.Field.DAY_OF_MONTH, 71, 73);
1429         expectedAttributedStrings[1].addAttribute(DateFormat.Field.YEAR, DateFormat.Field.YEAR, 75, 79);
1430
1431         // Add expected attributes to the expectedAttributedStrings[2]
1432         expectedAttributedStrings[2].addAttribute(MessageFormat.Field.ARGUMENT, new Integer(0), 20, 28);
1433         expectedAttributedStrings[2].addAttribute(NumberFormat.Field.INTEGER, NumberFormat.Field.INTEGER, 20, 22);
1434
1435         for (int i = 0; i < msgfmts.length; i++) {
1436             AttributedCharacterIterator acit = msgfmts[i].formatToCharacterIterator(args[i]);
1437             AttributedCharacterIterator expectedAcit = expectedAttributedStrings[i].getIterator();
1438
1439             // Check available attributes
1440             Set attrSet = acit.getAllAttributeKeys();
1441             Set expectedAttrSet = expectedAcit.getAllAttributeKeys();
1442             if (attrSet.size() != expectedAttrSet.size()) {
1443                 errln("FAIL: Number of attribute keys is " + attrSet.size() + " expected: " + expectedAttrSet.size());
1444             }
1445             Iterator attrIterator = attrSet.iterator();
1446             while (attrIterator.hasNext()) {
1447                 AttributedCharacterIterator.Attribute attr = (AttributedCharacterIterator.Attribute)attrIterator.next();
1448                 if (!expectedAttrSet.contains(attr)) {
1449                     errln("FAIL: The attribute " + attr + " is not expected.");
1450                 }
1451             }
1452
1453             StringBuffer buf = new StringBuffer();
1454             int index = acit.getBeginIndex();
1455             int end = acit.getEndIndex();
1456             int indexExp = expectedAcit.getBeginIndex();
1457             int expectedLen = expectedAcit.getEndIndex() - indexExp;
1458             if (end - index != expectedLen) {
1459                 errln("FAIL: Length of the result attributed string is " + (end - index) + " expected: " + expectedLen);
1460             } else {
1461                 // Check attributes associated with each character
1462                 while (index < end) {
1463                     char c = acit.setIndex(index);
1464                     buf.append(c);
1465                     expectedAcit.setIndex(indexExp);
1466
1467                     Map attrs = acit.getAttributes();
1468                     Map attrsExp = expectedAcit.getAttributes();
1469                     if (attrs.size() != attrsExp.size()) {
1470                         errln("FAIL: Number of attributes associated with index " + index + " is " + attrs.size()
1471                                 + " expected: " + attrsExp.size());
1472                     } else {
1473                         // Check all attributes at the index
1474                         Iterator entryIterator = attrsExp.entrySet().iterator();
1475                         while (entryIterator.hasNext()) {
1476                             Map.Entry entry = (Map.Entry)entryIterator.next();
1477                             if (attrs.containsKey(entry.getKey())) {
1478                                 Object value = attrs.get(entry.getKey());
1479                                 assertEquals("Attribute value at index " + index, entry.getValue(), value);
1480                             } else {
1481                                 errln("FAIL: Attribute " + entry.getKey() + " is missing at index " + index);
1482                             }
1483                         }
1484                     }
1485                     index++;
1486                     indexExp++;
1487                 }
1488                 assertEquals("AttributedString contents", expectedStrings[i], buf.toString());
1489             }
1490         }
1491     }
1492 //#endif
1493 }