]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-52_1/main/tests/core/src/com/ibm/icu/dev/test/format/MessageRegression.java
Clean up imports.
[Dictionary.git] / jars / icu4j-52_1 / main / tests / core / src / com / ibm / icu / dev / test / format / MessageRegression.java
1 /*
2 **********************************************************************
3 * Copyright (c) 2005-2011, International Business Machines
4 * Corporation and others.  All Rights Reserved.
5 **********************************************************************
6 * Author: Alan Liu
7 * Created: April 12, 2004
8 * Since: ICU 3.0
9 **********************************************************************
10 */
11 /**
12  * MessageRegression.java
13  *
14  * @test 1.29 01/03/12
15  * @bug 4031438 4058973 4074764 4094906 4104976 4105380 4106659 4106660 4106661
16  * 4111739 4112104 4113018 4114739 4114743 4116444 4118592 4118594 4120552
17  * 4142938 4169959 4232154 4293229
18  * @summary Regression tests for MessageFormat and associated classes
19  */
20 /*
21 (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
22 (C) Copyright IBM Corp. 1996 - All Rights Reserved
23
24   The original version of this source code and documentation is copyrighted and
25 owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are
26 provided under terms of a License Agreement between Taligent and Sun. This
27 technology is protected by multiple US and International patents. This notice and
28 attribution to Taligent may not be removed.
29   Taligent is a registered trademark of Taligent, Inc.
30 */
31 package com.ibm.icu.dev.test.format;
32
33 import java.io.ByteArrayInputStream;
34 import java.io.ByteArrayOutputStream;
35 import java.io.IOException;
36 import java.io.ObjectInputStream;
37 import java.io.ObjectOutputStream;
38 import java.text.ChoiceFormat;
39 import java.text.ParsePosition;
40 import java.util.Date;
41 import java.util.HashMap;
42 import java.util.Iterator;
43 import java.util.Locale;
44 import java.util.Map;
45
46 import com.ibm.icu.text.MessageFormat;
47 import com.ibm.icu.text.NumberFormat;
48 import com.ibm.icu.util.ULocale;
49
50 public class MessageRegression extends com.ibm.icu.dev.test.TestFmwk {
51
52     public static void main(String[] args) throws Exception {
53         new MessageRegression().run(args);
54     }
55
56     /* @bug 4074764
57      * Null exception when formatting pattern with MessageFormat
58      * with no parameters.
59      */
60     public void Test4074764() {
61         String[] pattern = {"Message without param",
62         "Message with param:{0}",
63         "Longer Message with param {0}"};
64         //difference between the two param strings are that
65         //in the first one, the param position is within the
66         //length of the string without param while it is not so
67         //in the other case.
68
69         MessageFormat messageFormatter = new MessageFormat("");
70
71         try {
72             //Apply pattern with param and print the result
73             messageFormatter.applyPattern(pattern[1]);
74             Object[] paramArray = {new String("BUG"), new Date()};
75             String tempBuffer = messageFormatter.format(paramArray);
76             if (!tempBuffer.equals("Message with param:BUG"))
77                 errln("MessageFormat with one param test failed.");
78             logln("Formatted with one extra param : " + tempBuffer);
79
80             //Apply pattern without param and print the result
81             messageFormatter.applyPattern(pattern[0]);
82             tempBuffer = messageFormatter.format(null);
83             if (!tempBuffer.equals("Message without param"))
84                 errln("MessageFormat with no param test failed.");
85             logln("Formatted with no params : " + tempBuffer);
86
87              tempBuffer = messageFormatter.format(paramArray);
88              if (!tempBuffer.equals("Message without param"))
89                 errln("Formatted with arguments > subsitution failed. result = " + tempBuffer.toString());
90              logln("Formatted with extra params : " + tempBuffer);
91             //This statement gives an exception while formatting...
92             //If we use pattern[1] for the message with param,
93             //we get an NullPointerException in MessageFormat.java(617)
94             //If we use pattern[2] for the message with param,
95             //we get an StringArrayIndexOutOfBoundsException in MessageFormat.java(614)
96             //Both are due to maxOffset not being reset to -1
97             //in applyPattern() when the pattern does not
98             //contain any param.
99         } catch (Exception foo) {
100             errln("Exception when formatting with no params.");
101         }
102     }
103
104     /* @bug 4058973
105      * MessageFormat.toPattern has weird rounding behavior.
106      *
107      * ICU 4.8: This test is commented out because toPattern() has been changed to return
108      * the original pattern string, rather than reconstituting a new (equivalent) one.
109      * This trivially eliminates issues with rounding or any other pattern string differences.
110      */
111     /*public void Test4058973() {
112
113         MessageFormat fmt = new MessageFormat("{0,choice,0#no files|1#one file|1< {0,number,integer} files}");
114         String pat = fmt.toPattern();
115         if (!pat.equals("{0,choice,0.0#no files|1.0#one file|1.0< {0,number,integer} files}")) {
116             errln("MessageFormat.toPattern failed");
117         }
118     }*/
119     /* @bug 4031438
120      * More robust message formats.
121      */
122     public void Test4031438() {
123         String pattern1 = "Impossible {1} has occurred -- status code is {0} and message is {2}.";
124         String pattern2 = "Double '' Quotes {0} test and quoted '{1}' test plus 'other {2} stuff'.";
125
126         MessageFormat messageFormatter = new MessageFormat("");
127
128         try {
129             logln("Apply with pattern : " + pattern1);
130             messageFormatter.applyPattern(pattern1);
131             Object[] paramArray = {new Integer(7)};
132             String tempBuffer = messageFormatter.format(paramArray);
133             if (!tempBuffer.equals("Impossible {1} has occurred -- status code is 7 and message is {2}."))
134                 errln("Tests arguments < substitution failed");
135             logln("Formatted with 7 : " + tempBuffer);
136             ParsePosition status = new ParsePosition(0);
137             Object[] objs = messageFormatter.parse(tempBuffer, status);
138             if (objs[paramArray.length] != null)
139                 errln("Parse failed with more than expected arguments");
140             for (int i = 0; i < objs.length; i++) {
141                 if (objs[i] != null && !objs[i].toString().equals(paramArray[i].toString())) {
142                     errln("Parse failed on object " + objs[i] + " at index : " + i);
143                 }
144             }
145             tempBuffer = messageFormatter.format(null);
146             if (!tempBuffer.equals("Impossible {1} has occurred -- status code is {0} and message is {2}."))
147                 errln("Tests with no arguments failed");
148             logln("Formatted with null : " + tempBuffer);
149             logln("Apply with pattern : " + pattern2);
150             messageFormatter.applyPattern(pattern2);
151             tempBuffer = messageFormatter.format(paramArray);
152             if (!tempBuffer.equals("Double ' Quotes 7 test and quoted {1} test plus 'other {2} stuff'."))
153                 errln("quote format test (w/ params) failed.");
154             logln("Formatted with params : " + tempBuffer);
155             tempBuffer = messageFormatter.format(null);
156             if (!tempBuffer.equals("Double ' Quotes {0} test and quoted {1} test plus 'other {2} stuff'."))
157                 errln("quote format test (w/ null) failed.");
158             logln("Formatted with null : " + tempBuffer);
159             logln("toPattern : " + messageFormatter.toPattern());
160         } catch (Exception foo) {
161             warnln("Exception when formatting in bug 4031438. "+foo.getMessage());
162         }
163     }
164     public void Test4052223()
165     {
166         ParsePosition pos = new ParsePosition(0);
167         if (pos.getErrorIndex() != -1) {
168             errln("ParsePosition.getErrorIndex initialization failed.");
169         }
170         MessageFormat fmt = new MessageFormat("There are {0} apples growing on the {1} tree.");
171         String str = new String("There is one apple growing on the peach tree.");
172         Object[] objs = fmt.parse(str, pos);
173         logln("unparsable string , should fail at " + pos.getErrorIndex());
174         if (pos.getErrorIndex() == -1)
175             errln("Bug 4052223 failed : parsing string " + str);
176         pos.setErrorIndex(4);
177         if (pos.getErrorIndex() != 4)
178             errln("setErrorIndex failed, got " + pos.getErrorIndex() + " instead of 4");
179         
180         if (objs != null) {
181             errln("objs should be null");
182         }
183         ChoiceFormat f = new ChoiceFormat(
184             "-1#are negative|0#are no or fraction|1#is one|1.0<is 1+|2#are two|2<are more than 2.");
185         pos.setIndex(0); pos.setErrorIndex(-1);
186         Number obj = f.parse("are negative", pos);
187         if (pos.getErrorIndex() != -1 && obj.doubleValue() == -1.0)
188             errln("Parse with \"are negative\" failed, at " + pos.getErrorIndex());
189         pos.setIndex(0); pos.setErrorIndex(-1);
190         obj = f.parse("are no or fraction ", pos);
191         if (pos.getErrorIndex() != -1 && obj.doubleValue() == 0.0)
192             errln("Parse with \"are no or fraction\" failed, at " + pos.getErrorIndex());
193         pos.setIndex(0); pos.setErrorIndex(-1);
194         obj = f.parse("go postal", pos);
195         if (pos.getErrorIndex() == -1 && !Double.isNaN(obj.doubleValue()))
196             errln("Parse with \"go postal\" failed, at " + pos.getErrorIndex());
197     }
198     /* @bug 4104976
199      * ChoiceFormat.equals(null) throws NullPointerException
200      */
201     public void Test4104976()
202     {
203         double[] limits = {1, 20};
204         String[] formats = {"xyz", "abc"};
205         ChoiceFormat cf = new ChoiceFormat(limits, formats);
206         try {
207             log("Compares to null is always false, returned : ");
208             logln(cf.equals(null) ? "TRUE" : "FALSE");
209         } catch (Exception foo) {
210             errln("ChoiceFormat.equals(null) throws exception.");
211         }
212     }
213     /* @bug 4106659
214      * ChoiceFormat.ctor(double[], String[]) doesn't check
215      * whether lengths of input arrays are equal.
216      */
217     public void Test4106659()
218     {
219         double[] limits = {1, 2, 3};
220         String[] formats = {"one", "two"};
221         ChoiceFormat cf = null;
222         try {
223             cf = new ChoiceFormat(limits, formats);
224         } catch (Exception foo) {
225             logln("ChoiceFormat constructor should check for the array lengths");
226             cf = null;
227         }
228         if (cf != null) errln(cf.format(5));
229     }
230
231     /* @bug 4106660
232      * ChoiceFormat.ctor(double[], String[]) allows unordered double array.
233      * This is not a bug, added javadoc to emphasize the use of limit
234      * array must be in ascending order.
235      */
236     public void Test4106660()
237     {
238         double[] limits = {3, 1, 2};
239         String[] formats = {"Three", "One", "Two"};
240         ChoiceFormat cf = new ChoiceFormat(limits, formats);
241         double d = 5.0;
242         String str = cf.format(d);
243         if (!str.equals("Two"))
244             errln("format(" + d + ") = " + cf.format(d));
245     }
246
247     /* @bug 4111739
248      * MessageFormat is incorrectly serialized/deserialized.
249      */
250     public void Test4111739()
251     {
252         MessageFormat format1 = null;
253         MessageFormat format2 = null;
254         ObjectOutputStream ostream = null;
255         ByteArrayOutputStream baos = null;
256         ObjectInputStream istream = null;
257
258         try {
259             baos = new ByteArrayOutputStream();
260             ostream = new ObjectOutputStream(baos);
261         } catch(IOException e) {
262             errln("Unexpected exception : " + e.getMessage());
263             return;
264         }
265
266         try {
267             format1 = new MessageFormat("pattern{0}");
268             ostream.writeObject(format1);
269             ostream.flush();
270
271             byte bytes[] = baos.toByteArray();
272
273             istream = new ObjectInputStream(new ByteArrayInputStream(bytes));
274             format2 = (MessageFormat)istream.readObject();
275         } catch(Exception e) {
276             errln("Unexpected exception : " + e.getMessage());
277         }
278
279         if (!format1.equals(format2)) {
280             errln("MessageFormats before and after serialization are not" +
281                 " equal\nformat1 = " + format1 + "(" + format1.toPattern() + ")\nformat2 = " +
282                 format2 + "(" + format2.toPattern() + ")");
283         } else {
284             logln("Serialization for MessageFormat is OK.");
285         }
286     }
287     /* @bug 4114743
288      * MessageFormat.applyPattern allows illegal patterns.
289      */
290     public void Test4114743()
291     {
292         String originalPattern = "initial pattern";
293         MessageFormat mf = new MessageFormat(originalPattern);
294         String illegalPattern = "ab { '}' de";
295         try {
296             mf.applyPattern(illegalPattern);
297             errln("illegal pattern: \"" + illegalPattern + "\"");
298         } catch (IllegalArgumentException foo) {
299             if (illegalPattern.equals(mf.toPattern()))
300                 errln("pattern after: \"" + mf.toPattern() + "\"");
301         }
302     }
303
304     /* @bug 4116444
305      * MessageFormat.parse has different behavior in case of null.
306      */
307     public void Test4116444()
308     {
309         String[] patterns = {"", "one", "{0,date,short}"};
310         MessageFormat mf = new MessageFormat("");
311
312         for (int i = 0; i < patterns.length; i++) {
313             String pattern = patterns[i];
314             mf.applyPattern(pattern);
315             try {
316                 Object[] array = mf.parse(null, new ParsePosition(0));
317                 logln("pattern: \"" + pattern + "\"");
318                 log(" parsedObjects: ");
319                 if (array != null) {
320                     log("{");
321                     for (int j = 0; j < array.length; j++) {
322                         if (array[j] != null)
323                             err("\"" + array[j].toString() + "\"");
324                         else
325                             log("null");
326                         if (j < array.length - 1) log(",");
327                     }
328                     log("}") ;
329                 } else {
330                     log("null");
331                 }
332                 logln("");
333             } catch (Exception e) {
334                 errln("pattern: \"" + pattern + "\"");
335                 errln("  Exception: " + e.getMessage());
336             }
337         }
338
339     }
340     /* @bug 4114739 (FIX and add javadoc)
341      * MessageFormat.format has undocumented behavior about empty format objects.
342      */
343     public void Test4114739()
344     {
345
346         MessageFormat mf = new MessageFormat("<{0}>");
347         Object[] objs1 = null;
348         Object[] objs2 = {};
349         Object[] objs3 = {null};
350         try {
351             logln("pattern: \"" + mf.toPattern() + "\"");
352             log("format(null) : ");
353             logln("\"" + mf.format(objs1) + "\"");
354             log("format({})   : ");
355             logln("\"" + mf.format(objs2) + "\"");
356             log("format({null}) :");
357             logln("\"" + mf.format(objs3) + "\"");
358         } catch (Exception e) {
359             errln("Exception thrown for null argument tests.");
360         }
361     }
362
363     /* @bug 4113018
364      * MessageFormat.applyPattern works wrong with illegal patterns.
365      */
366     public void Test4113018()
367     {
368         String originalPattern = "initial pattern";
369         MessageFormat mf = new MessageFormat(originalPattern);
370         String illegalPattern = "format: {0, xxxYYY}";
371         logln("pattern before: \"" + mf.toPattern() + "\"");
372         logln("illegal pattern: \"" + illegalPattern + "\"");
373         try {
374             mf.applyPattern(illegalPattern);
375             errln("Should have thrown IllegalArgumentException for pattern : " + illegalPattern);
376         } catch (IllegalArgumentException e) {
377             if (illegalPattern.equals(mf.toPattern()))
378                 errln("pattern after: \"" + mf.toPattern() + "\"");
379         }
380     }
381     /* @bug 4106661
382      * ChoiceFormat is silent about the pattern usage in javadoc.
383      */
384     public void Test4106661()
385     {
386         ChoiceFormat fmt = new ChoiceFormat(
387           "-1#are negative| 0#are no or fraction | 1#is one |1.0<is 1+ |2#are two |2<are more than 2.");
388         logln("Formatter Pattern : " + fmt.toPattern());
389
390         logln("Format with -INF : " + fmt.format(Double.NEGATIVE_INFINITY));
391         logln("Format with -1.0 : " + fmt.format(-1.0));
392         logln("Format with 0 : " + fmt.format(0));
393         logln("Format with 0.9 : " + fmt.format(0.9));
394         logln("Format with 1.0 : " + fmt.format(1));
395         logln("Format with 1.5 : " + fmt.format(1.5));
396         logln("Format with 2 : " + fmt.format(2));
397         logln("Format with 2.1 : " + fmt.format(2.1));
398         logln("Format with NaN : " + fmt.format(Double.NaN));
399         logln("Format with +INF : " + fmt.format(Double.POSITIVE_INFINITY));
400     }
401     /* @bug 4094906
402      * ChoiceFormat should accept \u221E as eq. to INF.
403      */
404     public void Test4094906()
405     {
406         ChoiceFormat fmt = new ChoiceFormat(
407           "-\u221E<are negative|0<are no or fraction|1#is one|1.0<is 1+|\u221E<are many.");
408         if (!fmt.toPattern().startsWith("-\u221E<are negative|0.0<are no or fraction|1.0#is one|1.0<is 1+|\u221E<are many."))
409             errln("Formatter Pattern : " + fmt.toPattern());
410         logln("Format with -INF : " + fmt.format(Double.NEGATIVE_INFINITY));
411         logln("Format with -1.0 : " + fmt.format(-1.0));
412         logln("Format with 0 : " + fmt.format(0));
413         logln("Format with 0.9 : " + fmt.format(0.9));
414         logln("Format with 1.0 : " + fmt.format(1));
415         logln("Format with 1.5 : " + fmt.format(1.5));
416         logln("Format with 2 : " + fmt.format(2));
417         logln("Format with +INF : " + fmt.format(Double.POSITIVE_INFINITY));
418     }
419
420     /* @bug 4118592
421      * MessageFormat.parse fails with ChoiceFormat.
422      */
423     public void Test4118592()
424     {
425         MessageFormat mf = new MessageFormat("");
426         String pattern = "{0,choice,1#YES|2#NO}";
427         String prefix = "";
428         for (int i = 0; i < 5; i++) {
429             String formatted = prefix + "YES";
430             mf.applyPattern(prefix + pattern);
431             prefix += "x";
432             Object[] objs = mf.parse(formatted, new ParsePosition(0));
433             logln(i + ". pattern :\"" + mf.toPattern() + "\"");
434             log(" \"" + formatted + "\" parsed as ");
435             if (objs == null) logln("  null");
436             else logln("  " + objs[0]);
437         }
438     }
439     /* @bug 4118594
440      * MessageFormat.parse fails for some patterns.
441      */
442     public void Test4118594()
443     {
444         MessageFormat mf = new MessageFormat("{0}, {0}, {0}");
445         String forParsing = "x, y, z";
446         Object[] objs = mf.parse(forParsing, new ParsePosition(0));
447         logln("pattern: \"" + mf.toPattern() + "\"");
448         logln("text for parsing: \"" + forParsing + "\"");
449         if (!objs[0].toString().equals("z"))
450             errln("argument0: \"" + objs[0] + "\"");
451         mf.setLocale(Locale.US);
452         mf.applyPattern("{0,number,#.##}, {0,number,#.#}");
453         Object[] oldobjs = {new Double(3.1415)};
454         String result = mf.format( oldobjs );
455         logln("pattern: \"" + mf.toPattern() + "\"");
456         logln("text for parsing: \"" + result + "\"");
457         // result now equals "3.14, 3.1"
458         if (!result.equals("3.14, 3.1"))
459             errln("result = " + result);
460         Object[] newobjs = mf.parse(result, new ParsePosition(0));
461         // newobjs now equals {new Double(3.1)}
462         if (((Number)newobjs[0]).doubleValue() != 3.1) // was (Double) [alan]
463             errln( "newobjs[0] = " + newobjs[0]);
464     }
465     /* @bug 4105380
466      * When using ChoiceFormat, MessageFormat is not good for I18n.
467      */
468     public void Test4105380()
469     {
470         String patternText1 = "The disk \"{1}\" contains {0}.";
471         String patternText2 = "There are {0} on the disk \"{1}\"";
472         MessageFormat form1 = new MessageFormat(patternText1);
473         MessageFormat form2 = new MessageFormat(patternText2);
474         double[] filelimits = {0,1,2};
475         String[] filepart = {"no files","one file","{0,number} files"};
476         ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
477         form1.setFormat(1, fileform);
478         form2.setFormat(0, fileform);
479         Object[] testArgs = {new Long(12373), "MyDisk"};
480         logln(form1.format(testArgs));
481         logln(form2.format(testArgs));
482     }
483     /* @bug 4120552
484      * MessageFormat.parse incorrectly sets errorIndex.
485      */
486     public void Test4120552()
487     {
488         MessageFormat mf = new MessageFormat("pattern");
489         String texts[] = {"pattern", "pat", "1234"};
490         logln("pattern: \"" + mf.toPattern() + "\"");
491         for (int i = 0; i < texts.length; i++) {
492             ParsePosition pp = new ParsePosition(0);
493             Object[] objs = mf.parse(texts[i], pp);
494             log("  text for parsing: \"" + texts[i] + "\"");
495             if (objs == null) {
496                 logln("  (incorrectly formatted string)");
497                 if (pp.getErrorIndex() == -1)
498                     errln("Incorrect error index: " + pp.getErrorIndex());
499             } else {
500                 logln("  (correctly formatted string)");
501             }
502         }
503     }
504
505     /**
506      * @bug 4142938
507      * MessageFormat handles single quotes in pattern wrong.
508      * This is actually a problem in ChoiceFormat; it doesn't
509      * understand single quotes.
510      */
511     public void Test4142938() {
512         String pat = "''Vous'' {0,choice,0#n''|1#}avez s\u00E9lectionne\u00E9 " + 
513             "{0,choice,0#aucun|1#{0}} client{0,choice,0#s|1#|2#s} " + 
514             "personnel{0,choice,0#s|1#|2#s}.";
515         MessageFormat mf = new MessageFormat(pat);
516
517         String[] PREFIX = {
518             "'Vous' n'avez s\u00E9lectionne\u00E9 aucun clients personnels.",
519             "'Vous' avez s\u00E9lectionne\u00E9 ",
520             "'Vous' avez s\u00E9lectionne\u00E9 "
521         };  
522         String[] SUFFIX = {
523             null,
524             " client personnel.",
525             " clients personnels."
526         };
527     
528         for (int i=0; i<3; i++) {
529             String out = mf.format(new Object[]{new Integer(i)});
530             if (SUFFIX[i] == null) {
531                 if (!out.equals(PREFIX[i]))
532                     errln("" + i + ": Got \"" + out + "\"; Want \"" + PREFIX[i] + "\"");
533             }
534             else {
535                 if (!out.startsWith(PREFIX[i]) ||
536                     !out.endsWith(SUFFIX[i]))
537                     errln("" + i + ": Got \"" + out + "\"; Want \"" + PREFIX[i] + "\"...\"" +
538                           SUFFIX[i] + "\"");
539             }
540         }
541     }
542
543     /**
544      * @bug 4142938
545      * Test the applyPattern and toPattern handling of single quotes
546      * by ChoiceFormat.  (This is in here because this was a bug reported
547      * against MessageFormat.)  The single quote is used to quote the
548      * pattern characters '|', '#', '<', and '\u2264'.  Two quotes in a row
549      * is a quote literal.
550      */
551     public void TestChoicePatternQuote() {
552         String[] DATA = {
553             // Pattern                  0 value           1 value
554             "0#can''t|1#can",           "can't",          "can",
555             "0#'pound(#)=''#'''|1#xyz", "pound(#)='#'",   "xyz",
556             "0#'1<2 | 1\u22641'|1#''",  "1<2 | 1\u22641", "'",
557         };
558         for (int i=0; i<DATA.length; i+=3) {
559             try {
560                 ChoiceFormat cf = new ChoiceFormat(DATA[i]);
561                 for (int j=0; j<=1; ++j) {
562                     String out = cf.format(j);
563                     if (!out.equals(DATA[i+1+j]))
564                         errln("Fail: Pattern \"" + DATA[i] + "\" x "+j+" -> " +
565                               out + "; want \"" + DATA[i+1+j] + '"');
566                 }
567                 String pat = cf.toPattern();
568                 String pat2 = new ChoiceFormat(pat).toPattern();
569                 if (!pat.equals(pat2))
570                     errln("Fail: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"');
571                 else
572                     logln("Ok: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"');
573             }
574             catch (IllegalArgumentException e) {
575                 errln("Fail: Pattern \"" + DATA[i] + "\" -> " + e);
576             }
577         }
578     }
579
580     /**
581      * @bug 4112104
582      * MessageFormat.equals(null) throws a NullPointerException.  The JLS states
583      * that it should return false.
584      */
585     public void Test4112104() {
586         MessageFormat format = new MessageFormat("");
587         try {
588             // This should NOT throw an exception
589             if (format.equals(null)) {
590                 // It also should return false
591                 errln("MessageFormat.equals(null) returns false");
592             }
593         }
594         catch (NullPointerException e) {
595             errln("MessageFormat.equals(null) throws " + e);
596         }
597     }
598
599     /**
600      * @bug 4169959
601      * MessageFormat does not format null objects. CANNOT REPRODUCE THIS BUG.
602      */
603     public void Test4169959() {
604         // This works
605         logln(MessageFormat.format("This will {0}", new Object[]{"work"}));
606
607         // This fails
608         logln(MessageFormat.format("This will {0}", new Object[]{ null }));
609     }
610
611     public void test4232154() {
612         boolean gotException = false;
613         try {
614             new MessageFormat("The date is {0:date}");
615         } catch (Exception e) {
616             gotException = true;
617             if (!(e instanceof IllegalArgumentException)) {
618                 throw new RuntimeException("got wrong exception type");
619             }
620             if ("argument number too large at ".equals(e.getMessage())) {
621                 throw new RuntimeException("got wrong exception message");
622             }
623         }
624         if (!gotException) {
625             throw new RuntimeException("didn't get exception for invalid input");
626         }
627     }
628     
629     public void test4293229() {
630         MessageFormat format = new MessageFormat("'''{'0}'' '''{0}'''");
631         Object[] args = { null };
632         String expected = "'{0}' '{0}'";
633         String result = format.format(args);
634         if (!result.equals(expected)) {
635             throw new RuntimeException("wrong format result - expected \"" +
636                     expected + "\", got \"" + result + "\"");
637         }
638     }
639      
640     // This test basically ensures that the tests defined above also work with
641     // valid named arguments.
642     public void testBugTestsWithNamesArguments() {
643         
644       { // Taken from Test4031438().
645         String pattern1 = "Impossible {arg1} has occurred -- status code is {arg0} and message is {arg2}.";
646         String pattern2 = "Double '' Quotes {ARG_ZERO} test and quoted '{ARG_ONE}' test plus 'other {ARG_TWO} stuff'.";
647
648         MessageFormat messageFormatter = new MessageFormat("");
649
650         try {
651             logln("Apply with pattern : " + pattern1);
652             messageFormatter.applyPattern(pattern1);
653             HashMap paramsMap = new HashMap();
654             paramsMap.put("arg0", new Integer(7));
655             String tempBuffer = messageFormatter.format(paramsMap);
656             if (!tempBuffer.equals("Impossible {arg1} has occurred -- status code is 7 and message is {arg2}."))
657                 errln("Tests arguments < substitution failed");
658             logln("Formatted with 7 : " + tempBuffer);
659             ParsePosition status = new ParsePosition(0);
660             Map objs = messageFormatter.parseToMap(tempBuffer, status);
661             if (objs.get("arg1") != null || objs.get("arg2") != null)
662                 errln("Parse failed with more than expected arguments");
663             for (Iterator keyIter = objs.keySet().iterator();
664                  keyIter.hasNext();) {
665                 String key = (String) keyIter.next();
666                 if (objs.get(key) != null && !objs.get(key).toString().equals(paramsMap.get(key).toString())) {
667                     errln("Parse failed on object " + objs.get(key) + " with argument name : " + key );
668                 }
669             }
670             tempBuffer = messageFormatter.format(null);
671             if (!tempBuffer.equals("Impossible {arg1} has occurred -- status code is {arg0} and message is {arg2}."))
672                 errln("Tests with no arguments failed");
673             logln("Formatted with null : " + tempBuffer);
674             logln("Apply with pattern : " + pattern2);
675             messageFormatter.applyPattern(pattern2);
676             paramsMap.clear();
677             paramsMap.put("ARG_ZERO", new Integer(7));
678             tempBuffer = messageFormatter.format(paramsMap);
679             if (!tempBuffer.equals("Double ' Quotes 7 test and quoted {ARG_ONE} test plus 'other {ARG_TWO} stuff'."))
680                 errln("quote format test (w/ params) failed.");
681             logln("Formatted with params : " + tempBuffer);
682             tempBuffer = messageFormatter.format(null);
683             if (!tempBuffer.equals("Double ' Quotes {ARG_ZERO} test and quoted {ARG_ONE} test plus 'other {ARG_TWO} stuff'."))
684                 errln("quote format test (w/ null) failed.");
685             logln("Formatted with null : " + tempBuffer);
686             logln("toPattern : " + messageFormatter.toPattern());
687         } catch (Exception foo) {
688             warnln("Exception when formatting in bug 4031438. "+foo.getMessage());
689         }
690       }{ // Taken from Test4052223().
691         ParsePosition pos = new ParsePosition(0);
692         if (pos.getErrorIndex() != -1) {
693             errln("ParsePosition.getErrorIndex initialization failed.");
694         }
695         MessageFormat fmt = new MessageFormat("There are {numberOfApples} apples growing on the {whatKindOfTree} tree.");
696         String str = new String("There is one apple growing on the peach tree.");
697         Map objs = fmt.parseToMap(str, pos);
698         logln("unparsable string , should fail at " + pos.getErrorIndex());
699         if (pos.getErrorIndex() == -1)
700             errln("Bug 4052223 failed : parsing string " + str);
701         pos.setErrorIndex(4);
702         if (pos.getErrorIndex() != 4)
703             errln("setErrorIndex failed, got " + pos.getErrorIndex() + " instead of 4");
704         if (objs != null)
705             errln("unparsable string, should return null");
706     }{ // Taken from Test4111739().
707         MessageFormat format1 = null;
708         MessageFormat format2 = null;
709         ObjectOutputStream ostream = null;
710         ByteArrayOutputStream baos = null;
711         ObjectInputStream istream = null;
712
713         try {
714             baos = new ByteArrayOutputStream();
715             ostream = new ObjectOutputStream(baos);
716         } catch(IOException e) {
717             errln("Unexpected exception : " + e.getMessage());
718             return;
719         }
720
721         try {
722             format1 = new MessageFormat("pattern{argument}");
723             ostream.writeObject(format1);
724             ostream.flush();
725
726             byte bytes[] = baos.toByteArray();
727
728             istream = new ObjectInputStream(new ByteArrayInputStream(bytes));
729             format2 = (MessageFormat)istream.readObject();
730         } catch(Exception e) {
731             errln("Unexpected exception : " + e.getMessage());
732         }
733
734         if (!format1.equals(format2)) {
735             errln("MessageFormats before and after serialization are not" +
736                 " equal\nformat1 = " + format1 + "(" + format1.toPattern() + ")\nformat2 = " +
737                 format2 + "(" + format2.toPattern() + ")");
738         } else {
739             logln("Serialization for MessageFormat is OK.");
740         }
741     }{ // Taken from Test4116444().
742         String[] patterns = {"", "one", "{namedArgument,date,short}"};
743         MessageFormat mf = new MessageFormat("");
744
745         for (int i = 0; i < patterns.length; i++) {
746             String pattern = patterns[i];
747             mf.applyPattern(pattern);
748             try {
749                 Map objs = mf.parseToMap(null, new ParsePosition(0));
750                 logln("pattern: \"" + pattern + "\"");
751                 log(" parsedObjects: ");
752                 if (objs != null) {
753                     log("{");
754                     for (Iterator keyIter = objs.keySet().iterator();
755                          keyIter.hasNext();) {
756                         String key = (String)keyIter.next();
757                         if (objs.get(key) != null) {
758                             err("\"" + objs.get(key).toString() + "\"");
759                         } else {
760                             log("null");
761                         }
762                         if (keyIter.hasNext()) {
763                             log(",");
764                         }
765                     }
766                     log("}") ;
767                 } else {
768                     log("null");
769                 }
770                 logln("");
771             } catch (Exception e) {
772                 errln("pattern: \"" + pattern + "\"");
773                 errln("  Exception: " + e.getMessage());
774             }
775         }
776     }{ // Taken from Test4114739().
777         MessageFormat mf = new MessageFormat("<{arg}>");
778         Map objs1 = null;
779         Map objs2 = new HashMap();
780         Map objs3 = new HashMap();
781         objs3.put("arg", null);
782         try {
783             logln("pattern: \"" + mf.toPattern() + "\"");
784             log("format(null) : ");
785             logln("\"" + mf.format(objs1) + "\"");
786             log("format({})   : ");
787             logln("\"" + mf.format(objs2) + "\"");
788             log("format({null}) :");
789             logln("\"" + mf.format(objs3) + "\"");
790         } catch (Exception e) {
791             errln("Exception thrown for null argument tests.");
792         } 
793     }{ // Taken from Test4118594().
794         String argName = "something_stupid";
795         MessageFormat mf = new MessageFormat("{"+ argName + "}, {" + argName + "}, {" + argName + "}");
796         String forParsing = "x, y, z";
797         Map objs = mf.parseToMap(forParsing, new ParsePosition(0));
798         logln("pattern: \"" + mf.toPattern() + "\"");
799         logln("text for parsing: \"" + forParsing + "\"");
800         if (!objs.get(argName).toString().equals("z"))
801             errln("argument0: \"" + objs.get(argName) + "\"");
802         mf.setLocale(Locale.US);
803         mf.applyPattern("{" + argName + ",number,#.##}, {" + argName + ",number,#.#}");
804         Map oldobjs = new HashMap();
805         oldobjs.put(argName, new Double(3.1415));
806         String result = mf.format( oldobjs );
807         logln("pattern: \"" + mf.toPattern() + "\"");
808         logln("text for parsing: \"" + result + "\"");
809         // result now equals "3.14, 3.1"
810         if (!result.equals("3.14, 3.1"))
811             errln("result = " + result);
812         Map newobjs = mf.parseToMap(result, new ParsePosition(0));
813         // newobjs now equals {new Double(3.1)}
814         if (((Number)newobjs.get(argName)).doubleValue() != 3.1) // was (Double) [alan]
815             errln( "newobjs.get(argName) = " + newobjs.get(argName));
816     }{ // Taken from Test4105380().
817         String patternText1 = "The disk \"{diskName}\" contains {numberOfFiles}.";
818         String patternText2 = "There are {numberOfFiles} on the disk \"{diskName}\"";
819         MessageFormat form1 = new MessageFormat(patternText1);
820         MessageFormat form2 = new MessageFormat(patternText2);
821         double[] filelimits = {0,1,2};
822         String[] filepart = {"no files","one file","{numberOfFiles,number} files"};
823         ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
824         form1.setFormat(1, fileform);
825         form2.setFormat(0, fileform);
826         Map testArgs = new HashMap();
827         testArgs.put("diskName", "MyDisk");
828         testArgs.put("numberOfFiles", new Long(12373));
829         logln(form1.format(testArgs));
830         logln(form2.format(testArgs));
831     }{ // Taken from test4293229().
832         MessageFormat format = new MessageFormat("'''{'myNamedArgument}'' '''{myNamedArgument}'''");
833         Map args = new HashMap();
834         String expected = "'{myNamedArgument}' '{myNamedArgument}'";
835         String result = format.format(args);
836         if (!result.equals(expected)) {
837             throw new RuntimeException("wrong format result - expected \"" +
838                     expected + "\", got \"" + result + "\"");
839         }
840     }
841   }
842
843     private MessageFormat serializeAndDeserialize(MessageFormat original) {
844         try {
845             ByteArrayOutputStream baos = new ByteArrayOutputStream();
846             ObjectOutputStream ostream = new ObjectOutputStream(baos);
847             ostream.writeObject(original);
848             ostream.flush();
849             byte bytes[] = baos.toByteArray();
850     
851             ObjectInputStream istream = new ObjectInputStream(new ByteArrayInputStream(bytes));
852             MessageFormat reconstituted = (MessageFormat)istream.readObject();
853             return reconstituted;
854         } catch(IOException e) {
855             throw new RuntimeException(e);
856         } catch (ClassNotFoundException e) {
857             throw new RuntimeException(e);
858         }
859     }
860
861     public void TestSerialization() {
862         MessageFormat format1 = null;
863         MessageFormat format2 = null;
864
865         format1 = new MessageFormat("", ULocale.GERMAN);
866         format2 = serializeAndDeserialize(format1);
867         assertEquals("MessageFormats (empty pattern) before and after serialization are not equal", format1, format2);
868
869         format1.applyPattern("ab{1}cd{0,number}ef{3,date}gh");
870         format1.setFormat(2, null);
871         format1.setFormatByArgumentIndex(1, NumberFormat.getInstance(ULocale.ENGLISH));
872         format2 = serializeAndDeserialize(format1);
873         assertEquals("MessageFormats (with custom formats) before and after serialization are not equal", format1, format2);
874         assertEquals(
875                 "MessageFormat (with custom formats) does not "+
876                 "format correctly after serialization",
877                 "ab3.3cd4,4ef***gh",
878                 format2.format(new Object[] { 4.4, 3.3, "+++", "***" }));
879     }
880 }