< prev index next >

test/jdk/java/text/Format/MessageFormat/MessageRegression.java

Print this page

  1 /*
  2  * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 /*
 25  * @test
 26  * @bug 4031438 4058973 4074764 4094906 4104976 4105380 4106659 4106660 4106661
 27  * 4111739 4112104 4113018 4114739 4114743 4116444 4118592 4118594 4120552
 28  * 4142938 4169959 4232154 4293229 8187551
 29  * @summary Regression tests for MessageFormat and associated classes
 30  * @library /java/text/testlib
 31  * @run main MessageRegression
 32  */
 33 /*
 34 (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
 35 (C) Copyright IBM Corp. 1996 - All Rights Reserved
 36 
 37   The original version of this source code and documentation is copyrighted and
 38 owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are
 39 provided under terms of a License Agreement between Taligent and Sun. This
 40 technology is protected by multiple US and International patents. This notice and
 41 attribution to Taligent may not be removed.
 42   Taligent is a registered trademark of Taligent, Inc.
 43 */
 44 
 45 import java.text.*;
 46 import java.util.*;
 47 import java.io.IOException;
 48 import java.io.FileOutputStream;
 49 import java.io.FileInputStream;
 50 import java.io.ByteArrayInputStream;
 51 import java.io.ByteArrayOutputStream;
 52 import java.io.ObjectOutputStream;
 53 import java.io.ObjectInputStream;
 54 import java.io.Serializable;
 55 
 56 public class MessageRegression extends IntlTest {
 57 
 58     public static void main(String[] args) throws Exception {
 59         new MessageRegression().run(args);
 60     }
 61 
 62     /* @bug 4074764
 63      * Null exception when formatting pattern with MessageFormat
 64      * with no parameters.
 65      */

 66     public void Test4074764() {
 67         String[] pattern = {"Message without param",
 68         "Message with param:{0}",
 69         "Longer Message with param {0}"};
 70         //difference between the two param strings are that
 71         //in the first one, the param position is within the
 72         //length of the string without param while it is not so
 73         //in the other case.
 74 
 75         MessageFormat messageFormatter = new MessageFormat("");
 76 
 77         try {
 78             //Apply pattern with param and print the result
 79             messageFormatter.applyPattern(pattern[1]);
 80             Object[] params = {new String("BUG"), new Date()};
 81             String tempBuffer = messageFormatter.format(params);
 82             if (!tempBuffer.equals("Message with param:BUG"))
 83                 errln("MessageFormat with one param test failed.");
 84             logln("Formatted with one extra param : " + tempBuffer);
 85 
 86             //Apply pattern without param and print the result
 87             messageFormatter.applyPattern(pattern[0]);
 88             tempBuffer = messageFormatter.format(null);
 89             if (!tempBuffer.equals("Message without param"))
 90                 errln("MessageFormat with no param test failed.");
 91             logln("Formatted with no params : " + tempBuffer);
 92 
 93              tempBuffer = messageFormatter.format(params);
 94              if (!tempBuffer.equals("Message without param"))
 95                 errln("Formatted with arguments > subsitution failed. result = " + tempBuffer.toString());
 96              logln("Formatted with extra params : " + tempBuffer);
 97             //This statement gives an exception while formatting...
 98             //If we use pattern[1] for the message with param,
 99             //we get an NullPointerException in MessageFormat.java(617)
100             //If we use pattern[2] for the message with param,
101             //we get an StringArrayIndexOutOfBoundsException in MessageFormat.java(614)
102             //Both are due to maxOffset not being reset to -1
103             //in applyPattern() when the pattern does not
104             //contain any param.
105         } catch (Exception foo) {
106             errln("Exception when formatting with no params.");
107         }
108     }
109 
110     /* @bug 4058973
111      * MessageFormat.toPattern has weird rounding behavior.
112      */

113     public void Test4058973() {
114 
115         MessageFormat fmt = new MessageFormat("{0,choice,0#no files|1#one file|1< {0,number,integer} files}");
116         String pat = fmt.toPattern();
117         if (!pat.equals("{0,choice,0.0#no files|1.0#one file|1.0< {0,number,integer} files}")) {
118             errln("MessageFormat.toPattern failed");
119         }
120     }
121     /* @bug 4031438
122      * More robust message formats.
123      */

124     public void Test4031438() {
125         Locale locale = Locale.getDefault();
126         if (!TestUtils.usesAsciiDigits(locale)) {
127             logln("Skipping this test because locale is " + locale);
128             return;
129         }
130 
131         String pattern1 = "Impossible {1} has occurred -- status code is {0} and message is {2}.";
132         String pattern2 = "Double '' Quotes {0} test and quoted '{1}' test plus 'other {2} stuff'.";
133 
134         MessageFormat messageFormatter = new MessageFormat("");
135 
136         try {
137             logln("Apply with pattern : " + pattern1);
138             messageFormatter.applyPattern(pattern1);
139             Object[] params = {7};
140             String tempBuffer = messageFormatter.format(params);
141             if (!tempBuffer.equals("Impossible {1} has occurred -- status code is 7 and message is {2}."))
142                 errln("Tests arguments < substitution failed. Formatted text=" +
143                       "<" + tempBuffer + ">");
144             logln("Formatted with 7 : " + tempBuffer);
145             ParsePosition status = new ParsePosition(0);
146             Object[] objs = messageFormatter.parse(tempBuffer, status);
147             if (objs[params.length] != null)
148                 errln("Parse failed with more than expected arguments");
149             for (int i = 0; i < objs.length; i++) {
150                 if (objs[i] != null && !objs[i].toString().equals(params[i].toString())) {
151                     errln("Parse failed on object " + objs[i] + " at index : " + i);
152                 }
153             }
154             tempBuffer = messageFormatter.format(null);
155             if (!tempBuffer.equals("Impossible {1} has occurred -- status code is {0} and message is {2}."))
156                 errln("Tests with no arguments failed");
157             logln("Formatted with null : " + tempBuffer);
158             logln("Apply with pattern : " + pattern2);
159             messageFormatter.applyPattern(pattern2);
160             tempBuffer = messageFormatter.format(params);
161             if (!tempBuffer.equals("Double ' Quotes 7 test and quoted {1} test plus other {2} stuff."))
162                 errln("quote format test (w/ params) failed.");
163             logln("Formatted with params : " + tempBuffer);
164             tempBuffer = messageFormatter.format(null);
165             if (!tempBuffer.equals("Double ' Quotes {0} test and quoted {1} test plus other {2} stuff."))
166                 errln("quote format test (w/ null) failed.");
167             logln("Formatted with null : " + tempBuffer);
168             logln("toPattern : " + messageFormatter.toPattern());
169         } catch (Exception foo) {
170             errln("Exception when formatting in bug 4031438. "+foo.getMessage());
171         }
172     }

173     public void Test4052223()
174     {
175         ParsePosition pos = new ParsePosition(0);
176         if (pos.getErrorIndex() != -1) {
177             errln("ParsePosition.getErrorIndex initialization failed.");
178         }
179         MessageFormat fmt = new MessageFormat("There are {0} apples growing on the {1} tree.");
180         String str = new String("There is one apple growing on the peach tree.");
181         Object[] objs = fmt.parse(str, pos);
182         logln("unparsable string , should fail at " + pos.getErrorIndex());
183         if (pos.getErrorIndex() == -1)
184             errln("Bug 4052223 failed : parsing string " + str);
185         pos.setErrorIndex(4);
186         if (pos.getErrorIndex() != 4)
187             errln("setErrorIndex failed, got " + pos.getErrorIndex() + " instead of 4");
188         ChoiceFormat f = new ChoiceFormat(
189             "-1#are negative|0#are no or fraction|1#is one|1.0<is 1+|2#are two|2<are more than 2.");
190         pos.setIndex(0); pos.setErrorIndex(-1);
191         Number obj = f.parse("are negative", pos);
192         if (pos.getErrorIndex() != -1 && obj.doubleValue() == -1.0)
193             errln("Parse with \"are negative\" failed, at " + pos.getErrorIndex());
194         pos.setIndex(0); pos.setErrorIndex(-1);
195         obj = f.parse("are no or fraction ", pos);
196         if (pos.getErrorIndex() != -1 && obj.doubleValue() == 0.0)
197             errln("Parse with \"are no or fraction\" failed, at " + pos.getErrorIndex());
198         pos.setIndex(0); pos.setErrorIndex(-1);
199         obj = f.parse("go postal", pos);
200         if (pos.getErrorIndex() == -1 && !Double.isNaN(obj.doubleValue()))
201             errln("Parse with \"go postal\" failed, at " + pos.getErrorIndex());
202     }
203     /* @bug 4104976
204      * ChoiceFormat.equals(null) throws NullPointerException
205      */

206     public void Test4104976()
207     {
208         double[] limits = {1, 20};
209         String[] formats = {"xyz", "abc"};
210         ChoiceFormat cf = new ChoiceFormat(limits, formats);
211         try {
212             log("Compares to null is always false, returned : ");
213             logln(cf.equals(null) ? "TRUE" : "FALSE");
214         } catch (Exception foo) {
215             errln("ChoiceFormat.equals(null) throws exception.");
216         }
217     }
218     /* @bug 4106659
219      * ChoiceFormat.ctor(double[], String[]) doesn't check
220      * whether lengths of input arrays are equal.
221      */

222     public void Test4106659()
223     {
224         double[] limits = {1, 2, 3};
225         String[] formats = {"one", "two"};
226         ChoiceFormat cf = null;
227         try {
228             cf = new ChoiceFormat(limits, formats);
229         } catch (Exception foo) {
230             logln("ChoiceFormat constructor should check for the array lengths");
231             cf = null;
232         }
233         if (cf != null) errln(cf.format(5));
234     }
235 
236     /* @bug 4106660
237      * ChoiceFormat.ctor(double[], String[]) allows unordered double array.
238      * This is not a bug, added javadoc to emphasize the use of limit
239      * array must be in ascending order.
240      */

241     public void Test4106660()
242     {
243         double[] limits = {3, 1, 2};
244         String[] formats = {"Three", "One", "Two"};
245         ChoiceFormat cf = new ChoiceFormat(limits, formats);
246         double d = 5.0;
247         String str = cf.format(d);
248         if (!str.equals("Two"))
249             errln("format(" + d + ") = " + cf.format(d));
250     }
251 
252     /* @bug 4111739
253      * MessageFormat is incorrectly serialized/deserialized.
254      */

255     public void Test4111739()
256     {
257         MessageFormat format1 = null;
258         MessageFormat format2 = null;
259         ObjectOutputStream ostream = null;
260         ByteArrayOutputStream baos = null;
261         ObjectInputStream istream = null;
262 
263         try {
264             baos = new ByteArrayOutputStream();
265             ostream = new ObjectOutputStream(baos);
266         } catch(IOException e) {
267             errln("Unexpected exception : " + e.getMessage());
268             return;
269         }
270 
271         try {
272             format1 = new MessageFormat("pattern{0}");
273             ostream.writeObject(format1);
274             ostream.flush();
275 
276             byte bytes[] = baos.toByteArray();
277 
278             istream = new ObjectInputStream(new ByteArrayInputStream(bytes));
279             format2 = (MessageFormat)istream.readObject();
280         } catch(Exception e) {
281             errln("Unexpected exception : " + e.getMessage());
282         }
283 
284         if (!format1.equals(format2)) {
285             errln("MessageFormats before and after serialization are not" +
286                 " equal\nformat1 = " + format1 + "(" + format1.toPattern() + ")\nformat2 = " +
287                 format2 + "(" + format2.toPattern() + ")");
288         } else {
289             logln("Serialization for MessageFormat is OK.");
290         }
291     }
292     /* @bug 4114743
293      * MessageFormat.applyPattern allows illegal patterns.
294      */

295     public void Test4114743()
296     {
297         String originalPattern = "initial pattern";
298         MessageFormat mf = new MessageFormat(originalPattern);
299         try {
300             String illegalPattern = "ab { '}' de";
301             mf.applyPattern(illegalPattern);
302             errln("illegal pattern: \"" + illegalPattern + "\"");
303         } catch (IllegalArgumentException foo) {
304             if (!originalPattern.equals(mf.toPattern()))
305                 errln("pattern after: \"" + mf.toPattern() + "\"");
306         }
307     }
308 
309     /* @bug 4116444
310      * MessageFormat.parse has different behavior in case of null.
311      */

312     public void Test4116444()
313     {
314         String[] patterns = {"", "one", "{0,date,short}"};
315         MessageFormat mf = new MessageFormat("");
316 
317         for (int i = 0; i < patterns.length; i++) {
318             String pattern = patterns[i];
319             mf.applyPattern(pattern);
320             try {
321                 Object[] array = mf.parse(null, new ParsePosition(0));
322                 logln("pattern: \"" + pattern + "\"");
323                 log(" parsedObjects: ");
324                 if (array != null) {
325                     log("{");
326                     for (int j = 0; j < array.length; j++) {
327                         if (array[j] != null)
328                             err("\"" + array[j].toString() + "\"");
329                         else
330                             log("null");
331                         if (j < array.length - 1) log(",");
332                     }
333                     log("}") ;
334                 } else {
335                     log("null");
336                 }
337                 logln("");
338             } catch (Exception e) {
339                 errln("pattern: \"" + pattern + "\"");
340                 errln("  Exception: " + e.getMessage());
341             }
342         }
343 
344     }
345     /* @bug 4114739 (FIX and add javadoc)
346      * MessageFormat.format has undocumented behavior about empty format objects.
347      */

348     public void Test4114739()
349     {
350 
351         MessageFormat mf = new MessageFormat("<{0}>");
352         Object[] objs1 = null;
353         Object[] objs2 = {};
354         Object[] objs3 = {null};
355         try {
356             logln("pattern: \"" + mf.toPattern() + "\"");
357             log("format(null) : ");
358             logln("\"" + mf.format(objs1) + "\"");
359             log("format({})   : ");
360             logln("\"" + mf.format(objs2) + "\"");
361             log("format({null}) :");
362             logln("\"" + mf.format(objs3) + "\"");
363         } catch (Exception e) {
364             errln("Exception thrown for null argument tests.");
365         }
366     }
367 
368     /* @bug 4113018
369      * MessageFormat.applyPattern works wrong with illegal patterns.
370      */

371     public void Test4113018()
372     {
373         String originalPattern = "initial pattern";
374         MessageFormat mf = new MessageFormat(originalPattern);
375         String illegalPattern = "format: {0, xxxYYY}";
376         logln("pattern before: \"" + mf.toPattern() + "\"");
377         logln("illegal pattern: \"" + illegalPattern + "\"");
378         try {
379             mf.applyPattern(illegalPattern);
380             errln("Should have thrown IllegalArgumentException for pattern : " + illegalPattern);
381         } catch (IllegalArgumentException e) {
382             if (!originalPattern.equals(mf.toPattern()))
383                 errln("pattern after: \"" + mf.toPattern() + "\"");
384         }
385     }
386     /* @bug 4106661
387      * ChoiceFormat is silent about the pattern usage in javadoc.
388      */

389     public void Test4106661()
390     {
391         ChoiceFormat fmt = new ChoiceFormat(
392           "-1#are negative| 0#are no or fraction | 1#is one |1.0<is 1+ |2#are two |2<are more than 2.");
393         logln("Formatter Pattern : " + fmt.toPattern());
394 
395         logln("Format with -INF : " + fmt.format(Double.NEGATIVE_INFINITY));
396         logln("Format with -1.0 : " + fmt.format(-1.0));
397         logln("Format with 0 : " + fmt.format(0));
398         logln("Format with 0.9 : " + fmt.format(0.9));
399         logln("Format with 1.0 : " + fmt.format(1));
400         logln("Format with 1.5 : " + fmt.format(1.5));
401         logln("Format with 2 : " + fmt.format(2));
402         logln("Format with 2.1 : " + fmt.format(2.1));
403         logln("Format with NaN : " + fmt.format(Double.NaN));
404         logln("Format with +INF : " + fmt.format(Double.POSITIVE_INFINITY));
405     }
406     /* @bug 4094906
407      * ChoiceFormat should accept \u221E as eq. to INF.
408      */

409     public void Test4094906()
410     {
411         ChoiceFormat fmt = new ChoiceFormat(
412           "-\u221E<are negative|0<are no or fraction|1#is one|1.0<is 1+|\u221E<are many.");
413         if (!fmt.toPattern().startsWith("-\u221E<are negative|0.0<are no or fraction|1.0#is one|1.0<is 1+|\u221E<are many."))
414             errln("Formatter Pattern : " + fmt.toPattern());
415         logln("Format with -INF : " + fmt.format(Double.NEGATIVE_INFINITY));
416         logln("Format with -1.0 : " + fmt.format(-1.0));
417         logln("Format with 0 : " + fmt.format(0));
418         logln("Format with 0.9 : " + fmt.format(0.9));
419         logln("Format with 1.0 : " + fmt.format(1));
420         logln("Format with 1.5 : " + fmt.format(1.5));
421         logln("Format with 2 : " + fmt.format(2));
422         logln("Format with +INF : " + fmt.format(Double.POSITIVE_INFINITY));
423     }
424 
425     /* @bug 4118592
426      * MessageFormat.parse fails with ChoiceFormat.
427      */

428     public void Test4118592()
429     {
430         MessageFormat mf = new MessageFormat("");
431         String pattern = "{0,choice,1#YES|2#NO}";
432         String prefix = "";
433         for (int i = 0; i < 5; i++) {
434             String formatted = prefix + "YES";
435             mf.applyPattern(prefix + pattern);
436             prefix += "x";
437             Object[] objs = mf.parse(formatted, new ParsePosition(0));
438             logln(i + ". pattern :\"" + mf.toPattern() + "\"");
439             log(" \"" + formatted + "\" parsed as ");
440             if (objs == null) logln("  null");
441             else logln("  " + objs[0]);
442         }
443     }
444     /* @bug 4118594
445      * MessageFormat.parse fails for some patterns.
446      */

447     public void Test4118594()
448     {
449         MessageFormat mf = new MessageFormat("{0}, {0}, {0}");
450         String forParsing = "x, y, z";
451         Object[] objs = mf.parse(forParsing, new ParsePosition(0));
452         logln("pattern: \"" + mf.toPattern() + "\"");
453         logln("text for parsing: \"" + forParsing + "\"");
454         if (!objs[0].toString().equals("z"))
455             errln("argument0: \"" + objs[0] + "\"");
456         mf.setLocale(Locale.US);
457         mf.applyPattern("{0,number,#.##}, {0,number,#.#}");
458         Object[] oldobjs = {3.1415};
459         String result = mf.format( oldobjs );
460         logln("pattern: \"" + mf.toPattern() + "\"");
461         logln("text for parsing: \"" + result + "\"");
462         // result now equals "3.14, 3.1"
463         if (!result.equals("3.14, 3.1"))
464             errln("result = " + result);
465         Object[] newobjs = mf.parse(result, new ParsePosition(0));
466         // newobjs now equals {new Double(3.1)}
467         if (((Double)newobjs[0]).doubleValue() != 3.1)
468             errln( "newobjs[0] = " + newobjs[0]);
469     }
470     /* @bug 4105380
471      * When using ChoiceFormat, MessageFormat is not good for I18n.
472      */

473     public void Test4105380()
474     {
475         String patternText1 = "The disk \"{1}\" contains {0}.";
476         String patternText2 = "There are {0} on the disk \"{1}\"";
477         MessageFormat form1 = new MessageFormat(patternText1);
478         MessageFormat form2 = new MessageFormat(patternText2);
479         double[] filelimits = {0,1,2};
480         String[] filepart = {"no files","one file","{0,number} files"};
481         ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
482         form1.setFormat(1, fileform);
483         form2.setFormat(0, fileform);
484         Object[] testArgs = {12373L, "MyDisk"};
485         logln(form1.format(testArgs));
486         logln(form2.format(testArgs));
487     }
488     /* @bug 4120552
489      * MessageFormat.parse incorrectly sets errorIndex.
490      */

491     public void Test4120552()
492     {
493         MessageFormat mf = new MessageFormat("pattern");
494         String texts[] = {"pattern", "pat", "1234"};
495         logln("pattern: \"" + mf.toPattern() + "\"");
496         for (int i = 0; i < texts.length; i++) {
497             ParsePosition pp = new ParsePosition(0);
498             Object[] objs = mf.parse(texts[i], pp);
499             log("  text for parsing: \"" + texts[i] + "\"");
500             if (objs == null) {
501                 logln("  (incorrectly formatted string)");
502                 if (pp.getErrorIndex() == -1)
503                     errln("Incorrect error index: " + pp.getErrorIndex());
504             } else {
505                 logln("  (correctly formatted string)");
506             }
507         }
508     }
509 
510     /**
511      * @bug 4142938
512      * MessageFormat handles single quotes in pattern wrong.
513      * This is actually a problem in ChoiceFormat; it doesn't
514      * understand single quotes.
515      */

516     public void Test4142938() {
517         String pat = "''Vous'' {0,choice,0#n''|1#}avez s\u00E9lectionne\u00E9 " +
518             "{0,choice,0#aucun|1#{0}} client{0,choice,0#s|1#|2#s} " +
519             "personnel{0,choice,0#s|1#|2#s}.";
520         MessageFormat mf = new MessageFormat(pat);
521 
522         String[] PREFIX = {
523             "'Vous' n'avez s\u00E9lectionne\u00E9 aucun clients personnels.",
524             "'Vous' avez s\u00E9lectionne\u00E9 ",
525             "'Vous' avez s\u00E9lectionne\u00E9 "
526         };
527         String[] SUFFIX = {
528             null,
529             " client personnel.",
530             " clients personnels."
531         };
532 
533         for (int i=0; i<3; i++) {
534             String out = mf.format(new Object[]{i});
535             if (SUFFIX[i] == null) {
536                 if (!out.equals(PREFIX[i]))
537                     errln("" + i + ": Got \"" + out + "\"; Want \"" + PREFIX[i] + "\"");
538             }
539             else {
540                 if (!out.startsWith(PREFIX[i]) ||
541                     !out.endsWith(SUFFIX[i]))
542                     errln("" + i + ": Got \"" + out + "\"; Want \"" + PREFIX[i] + "\"...\"" +
543                           SUFFIX[i] + "\"");
544             }
545         }
546     }
547 
548     /**
549      * @bug 4142938
550      * Test the applyPattern and toPattern handling of single quotes
551      * by ChoiceFormat.  (This is in here because this was a bug reported
552      * against MessageFormat.)  The single quote is used to quote the
553      * pattern characters '|', '#', '<', and '\u2264'.  Two quotes in a row
554      * is a quote literal.
555      */

556     public void TestChoicePatternQuote() {
557         String[] DATA = {
558             // Pattern                  0 value           1 value
559             "0#can''t|1#can",           "can't",          "can",
560             "0#'pound(#)=''#'''|1#xyz", "pound(#)='#'",   "xyz",
561             "0#'1<2 | 1\u22641'|1#''",  "1<2 | 1\u22641", "'",
562         };
563         for (int i=0; i<DATA.length; i+=3) {
564             try {
565                 ChoiceFormat cf = new ChoiceFormat(DATA[i]);
566                 for (int j=0; j<=1; ++j) {
567                     String out = cf.format(j);
568                     if (!out.equals(DATA[i+1+j]))
569                         errln("Fail: Pattern \"" + DATA[i] + "\" x "+j+" -> " +
570                               out + "; want \"" + DATA[i+1+j] + '"');
571                 }
572                 String pat = cf.toPattern();
573                 String pat2 = new ChoiceFormat(pat).toPattern();
574                 if (!pat.equals(pat2))
575                     errln("Fail: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"');
576                 else
577                     logln("Ok: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"');
578             }
579             catch (IllegalArgumentException e) {
580                 errln("Fail: Pattern \"" + DATA[i] + "\" -> " + e);
581             }
582         }
583     }
584 
585     /**
586      * @bug 4112104
587      * MessageFormat.equals(null) throws a NullPointerException.  The JLS states
588      * that it should return false.
589      */

590     public void Test4112104() {
591         MessageFormat format = new MessageFormat("");
592         try {
593             // This should NOT throw an exception
594             if (format.equals(null)) {
595                 // It also should return false
596                 errln("MessageFormat.equals(null) returns false");
597             }
598         }
599         catch (NullPointerException e) {
600             errln("MessageFormat.equals(null) throws " + e);
601         }
602     }
603 
604     /**
605      * @bug 4169959
606      * MessageFormat does not format null objects. CANNOT REPRODUCE THIS BUG.
607      */

608     public void Test4169959() {
609         // This works
610         logln(MessageFormat.format( "This will {0}", "work"));
611 
612         // This fails
613         logln(MessageFormat.format( "This will {0}",
614                                     new Object[]{ null } ) );
615     }
616 

617     public void test4232154() {
618         boolean gotException = false;
619         try {
620             MessageFormat format = new MessageFormat("The date is {0:date}");
621         } catch (Exception e) {
622             gotException = true;
623             if (!(e instanceof IllegalArgumentException)) {
624                 throw new RuntimeException("got wrong exception type");
625             }
626             if ("argument number too large at ".equals(e.getMessage())) {
627                 throw new RuntimeException("got wrong exception message");
628             }
629         }
630         if (!gotException) {
631             throw new RuntimeException("didn't get exception for invalid input");
632         }
633     }
634 

635     public void test4293229() {
636         MessageFormat format = new MessageFormat("'''{'0}'' '''{0}'''");
637         Object[] args = { null };
638         String expected = "'{0}' '{0}'";
639         String result = format.format(args);
640         if (!result.equals(expected)) {
641             throw new RuntimeException("wrong format result - expected \"" +
642                     expected + "\", got \"" + result + "\"");
643         }
644     }
645 
646     /**
647      * @bug 8187551
648      * test MessageFormat.setFormat() method to throw AIOOBE on invalid index.
649      */

650     public void test8187551() {
651         //invalid cases ("pattern", "invalid format element index")
652         String[][] invalidCases = {{"The disk \"{1}\" contains {0}.", "2"},
653                 {"The disk \"{1}\" contains {0}.", "9"},
654                 {"On {1}, there are {0} and {2} folders", "3"}};
655 
656         //invalid cases (must throw exception)
657         Arrays.stream(invalidCases).forEach(entry -> messageSetFormat(entry[0],
658                 Integer.valueOf(entry[1])));
659     }
660 
661     // test MessageFormat.setFormat() method for the given pattern and
662     // format element index
663     private void messageSetFormat(String pattern, int elemIndex) {
664         MessageFormat form = new MessageFormat(pattern);
665 
666         double[] fileLimits = {0, 1, 2};
667         String[] filePart = {"no files", "one file", "{0,number} files"};
668         ChoiceFormat fileForm = new ChoiceFormat(fileLimits, filePart);
669 

  1 /*
  2  * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 /*
 25  * @test
 26  * @bug 4031438 4058973 4074764 4094906 4104976 4105380 4106659 4106660 4106661
 27  * 4111739 4112104 4113018 4114739 4114743 4116444 4118592 4118594 4120552
 28  * 4142938 4169959 4232154 4293229 8187551
 29  * @summary Regression tests for MessageFormat and associated classes
 30  * @library /java/text/testlib
 31  * @run junit MessageRegression
 32  */
 33 /*
 34 (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
 35 (C) Copyright IBM Corp. 1996 - All Rights Reserved
 36 
 37   The original version of this source code and documentation is copyrighted and
 38 owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are
 39 provided under terms of a License Agreement between Taligent and Sun. This
 40 technology is protected by multiple US and International patents. This notice and
 41 attribution to Taligent may not be removed.
 42   Taligent is a registered trademark of Taligent, Inc.
 43 */
 44 
 45 import java.text.*;
 46 import java.util.*;
 47 import java.io.IOException;
 48 import java.io.FileOutputStream;
 49 import java.io.FileInputStream;
 50 import java.io.ByteArrayInputStream;
 51 import java.io.ByteArrayOutputStream;
 52 import java.io.ObjectOutputStream;
 53 import java.io.ObjectInputStream;
 54 import java.io.Serializable;
 55 
 56 import org.junit.jupiter.api.Test;
 57 
 58 import static org.junit.jupiter.api.Assertions.fail;
 59 
 60 public class MessageRegression {
 61 
 62     /* @bug 4074764
 63      * Null exception when formatting pattern with MessageFormat
 64      * with no parameters.
 65      */
 66     @Test
 67     public void Test4074764() {
 68         String[] pattern = {"Message without param",
 69         "Message with param:{0}",
 70         "Longer Message with param {0}"};
 71         //difference between the two param strings are that
 72         //in the first one, the param position is within the
 73         //length of the string without param while it is not so
 74         //in the other case.
 75 
 76         MessageFormat messageFormatter = new MessageFormat("");
 77 
 78         try {
 79             //Apply pattern with param and print the result
 80             messageFormatter.applyPattern(pattern[1]);
 81             Object[] params = {new String("BUG"), new Date()};
 82             String tempBuffer = messageFormatter.format(params);
 83             if (!tempBuffer.equals("Message with param:BUG"))
 84                 fail("MessageFormat with one param test failed.");
 85             System.out.println("Formatted with one extra param : " + tempBuffer);
 86 
 87             //Apply pattern without param and print the result
 88             messageFormatter.applyPattern(pattern[0]);
 89             tempBuffer = messageFormatter.format(null);
 90             if (!tempBuffer.equals("Message without param"))
 91                 fail("MessageFormat with no param test failed.");
 92             System.out.println("Formatted with no params : " + tempBuffer);
 93 
 94              tempBuffer = messageFormatter.format(params);
 95              if (!tempBuffer.equals("Message without param"))
 96                 fail("Formatted with arguments > subsitution failed. result = " + tempBuffer.toString());
 97              System.out.println("Formatted with extra params : " + tempBuffer);
 98             //This statement gives an exception while formatting...
 99             //If we use pattern[1] for the message with param,
100             //we get an NullPointerException in MessageFormat.java(617)
101             //If we use pattern[2] for the message with param,
102             //we get an StringArrayIndexOutOfBoundsException in MessageFormat.java(614)
103             //Both are due to maxOffset not being reset to -1
104             //in applyPattern() when the pattern does not
105             //contain any param.
106         } catch (Exception foo) {
107             fail("Exception when formatting with no params.");
108         }
109     }
110 
111     /* @bug 4058973
112      * MessageFormat.toPattern has weird rounding behavior.
113      */
114     @Test
115     public void Test4058973() {
116 
117         MessageFormat fmt = new MessageFormat("{0,choice,0#no files|1#one file|1< {0,number,integer} files}");
118         String pat = fmt.toPattern();
119         if (!pat.equals("{0,choice,0.0#no files|1.0#one file|1.0< {0,number,integer} files}")) {
120             fail("MessageFormat.toPattern failed");
121         }
122     }
123     /* @bug 4031438
124      * More robust message formats.
125      */
126     @Test
127     public void Test4031438() {
128         Locale locale = Locale.getDefault();
129         if (!TestUtils.usesAsciiDigits(locale)) {
130             System.out.println("Skipping this test because locale is " + locale);
131             return;
132         }
133 
134         String pattern1 = "Impossible {1} has occurred -- status code is {0} and message is {2}.";
135         String pattern2 = "Double '' Quotes {0} test and quoted '{1}' test plus 'other {2} stuff'.";
136 
137         MessageFormat messageFormatter = new MessageFormat("");
138 
139         try {
140             System.out.println("Apply with pattern : " + pattern1);
141             messageFormatter.applyPattern(pattern1);
142             Object[] params = {7};
143             String tempBuffer = messageFormatter.format(params);
144             if (!tempBuffer.equals("Impossible {1} has occurred -- status code is 7 and message is {2}."))
145                 fail("Tests arguments < substitution failed. Formatted text=" +
146                       "<" + tempBuffer + ">");
147             System.out.println("Formatted with 7 : " + tempBuffer);
148             ParsePosition status = new ParsePosition(0);
149             Object[] objs = messageFormatter.parse(tempBuffer, status);
150             if (objs[params.length] != null)
151                 fail("Parse failed with more than expected arguments");
152             for (int i = 0; i < objs.length; i++) {
153                 if (objs[i] != null && !objs[i].toString().equals(params[i].toString())) {
154                     fail("Parse failed on object " + objs[i] + " at index : " + i);
155                 }
156             }
157             tempBuffer = messageFormatter.format(null);
158             if (!tempBuffer.equals("Impossible {1} has occurred -- status code is {0} and message is {2}."))
159                 fail("Tests with no arguments failed");
160             System.out.println("Formatted with null : " + tempBuffer);
161             System.out.println("Apply with pattern : " + pattern2);
162             messageFormatter.applyPattern(pattern2);
163             tempBuffer = messageFormatter.format(params);
164             if (!tempBuffer.equals("Double ' Quotes 7 test and quoted {1} test plus other {2} stuff."))
165                 fail("quote format test (w/ params) failed.");
166             System.out.println("Formatted with params : " + tempBuffer);
167             tempBuffer = messageFormatter.format(null);
168             if (!tempBuffer.equals("Double ' Quotes {0} test and quoted {1} test plus other {2} stuff."))
169                 fail("quote format test (w/ null) failed.");
170             System.out.println("Formatted with null : " + tempBuffer);
171             System.out.println("toPattern : " + messageFormatter.toPattern());
172         } catch (Exception foo) {
173             fail("Exception when formatting in bug 4031438. "+foo.getMessage());
174         }
175     }
176     @Test
177     public void Test4052223()
178     {
179         ParsePosition pos = new ParsePosition(0);
180         if (pos.getErrorIndex() != -1) {
181             fail("ParsePosition.getErrorIndex initialization failed.");
182         }
183         MessageFormat fmt = new MessageFormat("There are {0} apples growing on the {1} tree.");
184         String str = new String("There is one apple growing on the peach tree.");
185         Object[] objs = fmt.parse(str, pos);
186         System.out.println("unparsable string , should fail at " + pos.getErrorIndex());
187         if (pos.getErrorIndex() == -1)
188             fail("Bug 4052223 failed : parsing string " + str);
189         pos.setErrorIndex(4);
190         if (pos.getErrorIndex() != 4)
191             fail("setErrorIndex failed, got " + pos.getErrorIndex() + " instead of 4");
192         ChoiceFormat f = new ChoiceFormat(
193             "-1#are negative|0#are no or fraction|1#is one|1.0<is 1+|2#are two|2<are more than 2.");
194         pos.setIndex(0); pos.setErrorIndex(-1);
195         Number obj = f.parse("are negative", pos);
196         if (pos.getErrorIndex() != -1 && obj.doubleValue() == -1.0)
197             fail("Parse with \"are negative\" failed, at " + pos.getErrorIndex());
198         pos.setIndex(0); pos.setErrorIndex(-1);
199         obj = f.parse("are no or fraction ", pos);
200         if (pos.getErrorIndex() != -1 && obj.doubleValue() == 0.0)
201             fail("Parse with \"are no or fraction\" failed, at " + pos.getErrorIndex());
202         pos.setIndex(0); pos.setErrorIndex(-1);
203         obj = f.parse("go postal", pos);
204         if (pos.getErrorIndex() == -1 && !Double.isNaN(obj.doubleValue()))
205             fail("Parse with \"go postal\" failed, at " + pos.getErrorIndex());
206     }
207     /* @bug 4104976
208      * ChoiceFormat.equals(null) throws NullPointerException
209      */
210     @Test
211     public void Test4104976()
212     {
213         double[] limits = {1, 20};
214         String[] formats = {"xyz", "abc"};
215         ChoiceFormat cf = new ChoiceFormat(limits, formats);
216         try {
217             System.out.println("Compares to null is always false, returned : ");
218             System.out.println(cf.equals(null) ? "TRUE" : "FALSE");
219         } catch (Exception foo) {
220             fail("ChoiceFormat.equals(null) throws exception.");
221         }
222     }
223     /* @bug 4106659
224      * ChoiceFormat.ctor(double[], String[]) doesn't check
225      * whether lengths of input arrays are equal.
226      */
227     @Test
228     public void Test4106659()
229     {
230         double[] limits = {1, 2, 3};
231         String[] formats = {"one", "two"};
232         ChoiceFormat cf = null;
233         try {
234             cf = new ChoiceFormat(limits, formats);
235         } catch (Exception foo) {
236             System.out.println("ChoiceFormat constructor should check for the array lengths");
237             cf = null;
238         }
239         if (cf != null) fail(cf.format(5));
240     }
241 
242     /* @bug 4106660
243      * ChoiceFormat.ctor(double[], String[]) allows unordered double array.
244      * This is not a bug, added javadoc to emphasize the use of limit
245      * array must be in ascending order.
246      */
247     @Test
248     public void Test4106660()
249     {
250         double[] limits = {3, 1, 2};
251         String[] formats = {"Three", "One", "Two"};
252         ChoiceFormat cf = new ChoiceFormat(limits, formats);
253         double d = 5.0;
254         String str = cf.format(d);
255         if (!str.equals("Two"))
256             fail("format(" + d + ") = " + cf.format(d));
257     }
258 
259     /* @bug 4111739
260      * MessageFormat is incorrectly serialized/deserialized.
261      */
262     @Test
263     public void Test4111739()
264     {
265         MessageFormat format1 = null;
266         MessageFormat format2 = null;
267         ObjectOutputStream ostream = null;
268         ByteArrayOutputStream baos = null;
269         ObjectInputStream istream = null;
270 
271         try {
272             baos = new ByteArrayOutputStream();
273             ostream = new ObjectOutputStream(baos);
274         } catch(IOException e) {
275             fail("Unexpected exception : " + e.getMessage());
276             return;
277         }
278 
279         try {
280             format1 = new MessageFormat("pattern{0}");
281             ostream.writeObject(format1);
282             ostream.flush();
283 
284             byte bytes[] = baos.toByteArray();
285 
286             istream = new ObjectInputStream(new ByteArrayInputStream(bytes));
287             format2 = (MessageFormat)istream.readObject();
288         } catch(Exception e) {
289             fail("Unexpected exception : " + e.getMessage());
290         }
291 
292         if (!format1.equals(format2)) {
293             fail("MessageFormats before and after serialization are not" +
294                 " equal\nformat1 = " + format1 + "(" + format1.toPattern() + ")\nformat2 = " +
295                 format2 + "(" + format2.toPattern() + ")");
296         } else {
297             System.out.println("Serialization for MessageFormat is OK.");
298         }
299     }
300     /* @bug 4114743
301      * MessageFormat.applyPattern allows illegal patterns.
302      */
303     @Test
304     public void Test4114743()
305     {
306         String originalPattern = "initial pattern";
307         MessageFormat mf = new MessageFormat(originalPattern);
308         try {
309             String illegalPattern = "ab { '}' de";
310             mf.applyPattern(illegalPattern);
311             fail("illegal pattern: \"" + illegalPattern + "\"");
312         } catch (IllegalArgumentException foo) {
313             if (!originalPattern.equals(mf.toPattern()))
314                 fail("pattern after: \"" + mf.toPattern() + "\"");
315         }
316     }
317 
318     /* @bug 4116444
319      * MessageFormat.parse has different behavior in case of null.
320      */
321     @Test
322     public void Test4116444()
323     {
324         String[] patterns = {"", "one", "{0,date,short}"};
325         MessageFormat mf = new MessageFormat("");
326 
327         for (int i = 0; i < patterns.length; i++) {
328             String pattern = patterns[i];
329             mf.applyPattern(pattern);
330             try {
331                 Object[] array = mf.parse(null, new ParsePosition(0));
332                 System.out.println("pattern: \"" + pattern + "\"");
333                 System.out.println(" parsedObjects: ");
334                 if (array != null) {
335                     System.out.println("{");
336                     for (int j = 0; j < array.length; j++) {
337                         if (array[j] != null)
338                             fail("\"" + array[j].toString() + "\"");
339                         else
340                             System.out.println("null");
341                         if (j < array.length - 1) System.out.println(",");
342                     }
343                     System.out.println("}") ;
344                 } else {
345                     System.out.println("null");
346                 }
347                 System.out.println("");
348             } catch (Exception e) {
349                 fail("pattern: \"" + pattern + "\"");
350                 fail("  Exception: " + e.getMessage());
351             }
352         }
353 
354     }
355     /* @bug 4114739 (FIX and add javadoc)
356      * MessageFormat.format has undocumented behavior about empty format objects.
357      */
358     @Test
359     public void Test4114739()
360     {
361 
362         MessageFormat mf = new MessageFormat("<{0}>");
363         Object[] objs1 = null;
364         Object[] objs2 = {};
365         Object[] objs3 = {null};
366         try {
367             System.out.println("pattern: \"" + mf.toPattern() + "\"");
368             System.out.println("format(null) : ");
369             System.out.println("\"" + mf.format(objs1) + "\"");
370             System.out.println("format({})   : ");
371             System.out.println("\"" + mf.format(objs2) + "\"");
372             System.out.println("format({null}) :");
373             System.out.println("\"" + mf.format(objs3) + "\"");
374         } catch (Exception e) {
375             fail("Exception thrown for null argument tests.");
376         }
377     }
378 
379     /* @bug 4113018
380      * MessageFormat.applyPattern works wrong with illegal patterns.
381      */
382     @Test
383     public void Test4113018()
384     {
385         String originalPattern = "initial pattern";
386         MessageFormat mf = new MessageFormat(originalPattern);
387         String illegalPattern = "format: {0, xxxYYY}";
388         System.out.println("pattern before: \"" + mf.toPattern() + "\"");
389         System.out.println("illegal pattern: \"" + illegalPattern + "\"");
390         try {
391             mf.applyPattern(illegalPattern);
392             fail("Should have thrown IllegalArgumentException for pattern : " + illegalPattern);
393         } catch (IllegalArgumentException e) {
394             if (!originalPattern.equals(mf.toPattern()))
395                 fail("pattern after: \"" + mf.toPattern() + "\"");
396         }
397     }
398     /* @bug 4106661
399      * ChoiceFormat is silent about the pattern usage in javadoc.
400      */
401     @Test
402     public void Test4106661()
403     {
404         ChoiceFormat fmt = new ChoiceFormat(
405           "-1#are negative| 0#are no or fraction | 1#is one |1.0<is 1+ |2#are two |2<are more than 2.");
406         System.out.println("Formatter Pattern : " + fmt.toPattern());
407 
408         System.out.println("Format with -INF : " + fmt.format(Double.NEGATIVE_INFINITY));
409         System.out.println("Format with -1.0 : " + fmt.format(-1.0));
410         System.out.println("Format with 0 : " + fmt.format(0));
411         System.out.println("Format with 0.9 : " + fmt.format(0.9));
412         System.out.println("Format with 1.0 : " + fmt.format(1));
413         System.out.println("Format with 1.5 : " + fmt.format(1.5));
414         System.out.println("Format with 2 : " + fmt.format(2));
415         System.out.println("Format with 2.1 : " + fmt.format(2.1));
416         System.out.println("Format with NaN : " + fmt.format(Double.NaN));
417         System.out.println("Format with +INF : " + fmt.format(Double.POSITIVE_INFINITY));
418     }
419     /* @bug 4094906
420      * ChoiceFormat should accept \u221E as eq. to INF.
421      */
422     @Test
423     public void Test4094906()
424     {
425         ChoiceFormat fmt = new ChoiceFormat(
426           "-\u221E<are negative|0<are no or fraction|1#is one|1.0<is 1+|\u221E<are many.");
427         if (!fmt.toPattern().startsWith("-\u221E<are negative|0.0<are no or fraction|1.0#is one|1.0<is 1+|\u221E<are many."))
428             fail("Formatter Pattern : " + fmt.toPattern());
429         System.out.println("Format with -INF : " + fmt.format(Double.NEGATIVE_INFINITY));
430         System.out.println("Format with -1.0 : " + fmt.format(-1.0));
431         System.out.println("Format with 0 : " + fmt.format(0));
432         System.out.println("Format with 0.9 : " + fmt.format(0.9));
433         System.out.println("Format with 1.0 : " + fmt.format(1));
434         System.out.println("Format with 1.5 : " + fmt.format(1.5));
435         System.out.println("Format with 2 : " + fmt.format(2));
436         System.out.println("Format with +INF : " + fmt.format(Double.POSITIVE_INFINITY));
437     }
438 
439     /* @bug 4118592
440      * MessageFormat.parse fails with ChoiceFormat.
441      */
442     @Test
443     public void Test4118592()
444     {
445         MessageFormat mf = new MessageFormat("");
446         String pattern = "{0,choice,1#YES|2#NO}";
447         String prefix = "";
448         for (int i = 0; i < 5; i++) {
449             String formatted = prefix + "YES";
450             mf.applyPattern(prefix + pattern);
451             prefix += "x";
452             Object[] objs = mf.parse(formatted, new ParsePosition(0));
453             System.out.println(i + ". pattern :\"" + mf.toPattern() + "\"");
454             System.out.println(" \"" + formatted + "\" parsed as ");
455             if (objs == null) System.out.println("  null");
456             else System.out.println("  " + objs[0]);
457         }
458     }
459     /* @bug 4118594
460      * MessageFormat.parse fails for some patterns.
461      */
462     @Test
463     public void Test4118594()
464     {
465         MessageFormat mf = new MessageFormat("{0}, {0}, {0}");
466         String forParsing = "x, y, z";
467         Object[] objs = mf.parse(forParsing, new ParsePosition(0));
468         System.out.println("pattern: \"" + mf.toPattern() + "\"");
469         System.out.println("text for parsing: \"" + forParsing + "\"");
470         if (!objs[0].toString().equals("z"))
471             fail("argument0: \"" + objs[0] + "\"");
472         mf.setLocale(Locale.US);
473         mf.applyPattern("{0,number,#.##}, {0,number,#.#}");
474         Object[] oldobjs = {3.1415};
475         String result = mf.format( oldobjs );
476         System.out.println("pattern: \"" + mf.toPattern() + "\"");
477         System.out.println("text for parsing: \"" + result + "\"");
478         // result now equals "3.14, 3.1"
479         if (!result.equals("3.14, 3.1"))
480             fail("result = " + result);
481         Object[] newobjs = mf.parse(result, new ParsePosition(0));
482         // newobjs now equals {new Double(3.1)}
483         if (((Double)newobjs[0]).doubleValue() != 3.1)
484             fail( "newobjs[0] = " + newobjs[0]);
485     }
486     /* @bug 4105380
487      * When using ChoiceFormat, MessageFormat is not good for I18n.
488      */
489     @Test
490     public void Test4105380()
491     {
492         String patternText1 = "The disk \"{1}\" contains {0}.";
493         String patternText2 = "There are {0} on the disk \"{1}\"";
494         MessageFormat form1 = new MessageFormat(patternText1);
495         MessageFormat form2 = new MessageFormat(patternText2);
496         double[] filelimits = {0,1,2};
497         String[] filepart = {"no files","one file","{0,number} files"};
498         ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
499         form1.setFormat(1, fileform);
500         form2.setFormat(0, fileform);
501         Object[] testArgs = {12373L, "MyDisk"};
502         System.out.println(form1.format(testArgs));
503         System.out.println(form2.format(testArgs));
504     }
505     /* @bug 4120552
506      * MessageFormat.parse incorrectly sets errorIndex.
507      */
508     @Test
509     public void Test4120552()
510     {
511         MessageFormat mf = new MessageFormat("pattern");
512         String texts[] = {"pattern", "pat", "1234"};
513         System.out.println("pattern: \"" + mf.toPattern() + "\"");
514         for (int i = 0; i < texts.length; i++) {
515             ParsePosition pp = new ParsePosition(0);
516             Object[] objs = mf.parse(texts[i], pp);
517             System.out.println("  text for parsing: \"" + texts[i] + "\"");
518             if (objs == null) {
519                 System.out.println("  (incorrectly formatted string)");
520                 if (pp.getErrorIndex() == -1)
521                     fail("Incorrect error index: " + pp.getErrorIndex());
522             } else {
523                 System.out.println("  (correctly formatted string)");
524             }
525         }
526     }
527 
528     /**
529      * @bug 4142938
530      * MessageFormat handles single quotes in pattern wrong.
531      * This is actually a problem in ChoiceFormat; it doesn't
532      * understand single quotes.
533      */
534     @Test
535     public void Test4142938() {
536         String pat = "''Vous'' {0,choice,0#n''|1#}avez s\u00E9lectionne\u00E9 " +
537             "{0,choice,0#aucun|1#{0}} client{0,choice,0#s|1#|2#s} " +
538             "personnel{0,choice,0#s|1#|2#s}.";
539         MessageFormat mf = new MessageFormat(pat);
540 
541         String[] PREFIX = {
542             "'Vous' n'avez s\u00E9lectionne\u00E9 aucun clients personnels.",
543             "'Vous' avez s\u00E9lectionne\u00E9 ",
544             "'Vous' avez s\u00E9lectionne\u00E9 "
545         };
546         String[] SUFFIX = {
547             null,
548             " client personnel.",
549             " clients personnels."
550         };
551 
552         for (int i=0; i<3; i++) {
553             String out = mf.format(new Object[]{i});
554             if (SUFFIX[i] == null) {
555                 if (!out.equals(PREFIX[i]))
556                     fail("" + i + ": Got \"" + out + "\"; Want \"" + PREFIX[i] + "\"");
557             }
558             else {
559                 if (!out.startsWith(PREFIX[i]) ||
560                     !out.endsWith(SUFFIX[i]))
561                     fail("" + i + ": Got \"" + out + "\"; Want \"" + PREFIX[i] + "\"...\"" +
562                           SUFFIX[i] + "\"");
563             }
564         }
565     }
566 
567     /**
568      * @bug 4142938
569      * Test the applyPattern and toPattern handling of single quotes
570      * by ChoiceFormat.  (This is in here because this was a bug reported
571      * against MessageFormat.)  The single quote is used to quote the
572      * pattern characters '|', '#', '<', and '\u2264'.  Two quotes in a row
573      * is a quote literal.
574      */
575     @Test
576     public void TestChoicePatternQuote() {
577         String[] DATA = {
578             // Pattern                  0 value           1 value
579             "0#can''t|1#can",           "can't",          "can",
580             "0#'pound(#)=''#'''|1#xyz", "pound(#)='#'",   "xyz",
581             "0#'1<2 | 1\u22641'|1#''",  "1<2 | 1\u22641", "'",
582         };
583         for (int i=0; i<DATA.length; i+=3) {
584             try {
585                 ChoiceFormat cf = new ChoiceFormat(DATA[i]);
586                 for (int j=0; j<=1; ++j) {
587                     String out = cf.format(j);
588                     if (!out.equals(DATA[i+1+j]))
589                         fail("Fail: Pattern \"" + DATA[i] + "\" x "+j+" -> " +
590                               out + "; want \"" + DATA[i+1+j] + '"');
591                 }
592                 String pat = cf.toPattern();
593                 String pat2 = new ChoiceFormat(pat).toPattern();
594                 if (!pat.equals(pat2))
595                     fail("Fail: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"');
596                 else
597                     System.out.println("Ok: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"');
598             }
599             catch (IllegalArgumentException e) {
600                 fail("Fail: Pattern \"" + DATA[i] + "\" -> " + e);
601             }
602         }
603     }
604 
605     /**
606      * @bug 4112104
607      * MessageFormat.equals(null) throws a NullPointerException.  The JLS states
608      * that it should return false.
609      */
610     @Test
611     public void Test4112104() {
612         MessageFormat format = new MessageFormat("");
613         try {
614             // This should NOT throw an exception
615             if (format.equals(null)) {
616                 // It also should return false
617                 fail("MessageFormat.equals(null) returns false");
618             }
619         }
620         catch (NullPointerException e) {
621             fail("MessageFormat.equals(null) throws " + e);
622         }
623     }
624 
625     /**
626      * @bug 4169959
627      * MessageFormat does not format null objects. CANNOT REPRODUCE THIS BUG.
628      */
629     @Test
630     public void Test4169959() {
631         // This works
632         System.out.println(MessageFormat.format( "This will {0}", "work"));
633 
634         // This fails
635         System.out.println(MessageFormat.format( "This will {0}",
636                                     new Object[]{ null } ) );
637     }
638 
639     @Test
640     public void test4232154() {
641         boolean gotException = false;
642         try {
643             MessageFormat format = new MessageFormat("The date is {0:date}");
644         } catch (Exception e) {
645             gotException = true;
646             if (!(e instanceof IllegalArgumentException)) {
647                 throw new RuntimeException("got wrong exception type");
648             }
649             if ("argument number too large at ".equals(e.getMessage())) {
650                 throw new RuntimeException("got wrong exception message");
651             }
652         }
653         if (!gotException) {
654             throw new RuntimeException("didn't get exception for invalid input");
655         }
656     }
657 
658     @Test
659     public void test4293229() {
660         MessageFormat format = new MessageFormat("'''{'0}'' '''{0}'''");
661         Object[] args = { null };
662         String expected = "'{0}' '{0}'";
663         String result = format.format(args);
664         if (!result.equals(expected)) {
665             throw new RuntimeException("wrong format result - expected \"" +
666                     expected + "\", got \"" + result + "\"");
667         }
668     }
669 
670     /**
671      * @bug 8187551
672      * test MessageFormat.setFormat() method to throw AIOOBE on invalid index.
673      */
674     @Test
675     public void test8187551() {
676         //invalid cases ("pattern", "invalid format element index")
677         String[][] invalidCases = {{"The disk \"{1}\" contains {0}.", "2"},
678                 {"The disk \"{1}\" contains {0}.", "9"},
679                 {"On {1}, there are {0} and {2} folders", "3"}};
680 
681         //invalid cases (must throw exception)
682         Arrays.stream(invalidCases).forEach(entry -> messageSetFormat(entry[0],
683                 Integer.valueOf(entry[1])));
684     }
685 
686     // test MessageFormat.setFormat() method for the given pattern and
687     // format element index
688     private void messageSetFormat(String pattern, int elemIndex) {
689         MessageFormat form = new MessageFormat(pattern);
690 
691         double[] fileLimits = {0, 1, 2};
692         String[] filePart = {"no files", "one file", "{0,number} files"};
693         ChoiceFormat fileForm = new ChoiceFormat(fileLimits, filePart);
694 
< prev index next >