2 **********************************************************************
3 * Copyright (c) 2005-2011, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
7 * Created: April 12, 2004
9 **********************************************************************
12 * MessageRegression.java
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
21 (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
22 (C) Copyright IBM Corp. 1996 - All Rights Reserved
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.
31 package com.ibm.icu.dev.test.format;
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;
46 import com.ibm.icu.text.MessageFormat;
47 import com.ibm.icu.text.NumberFormat;
48 import com.ibm.icu.util.ULocale;
50 public class MessageRegression extends com.ibm.icu.dev.test.TestFmwk {
52 public static void main(String[] args) throws Exception {
53 new MessageRegression().run(args);
57 * Null exception when formatting pattern with MessageFormat
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
69 MessageFormat messageFormatter = new MessageFormat("");
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);
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);
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
99 } catch (Exception foo) {
100 errln("Exception when formatting with no params.");
105 * MessageFormat.toPattern has weird rounding behavior.
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.
111 /*public void Test4058973() {
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");
120 * More robust message formats.
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'.";
126 MessageFormat messageFormatter = new MessageFormat("");
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);
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());
164 public void Test4052223()
166 ParsePosition pos = new ParsePosition(0);
167 if (pos.getErrorIndex() != -1) {
168 errln("ParsePosition.getErrorIndex initialization failed.");
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");
181 errln("objs should be null");
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());
199 * ChoiceFormat.equals(null) throws NullPointerException
201 public void Test4104976()
203 double[] limits = {1, 20};
204 String[] formats = {"xyz", "abc"};
205 ChoiceFormat cf = new ChoiceFormat(limits, formats);
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.");
214 * ChoiceFormat.ctor(double[], String[]) doesn't check
215 * whether lengths of input arrays are equal.
217 public void Test4106659()
219 double[] limits = {1, 2, 3};
220 String[] formats = {"one", "two"};
221 ChoiceFormat cf = null;
223 cf = new ChoiceFormat(limits, formats);
224 } catch (Exception foo) {
225 logln("ChoiceFormat constructor should check for the array lengths");
228 if (cf != null) errln(cf.format(5));
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.
236 public void Test4106660()
238 double[] limits = {3, 1, 2};
239 String[] formats = {"Three", "One", "Two"};
240 ChoiceFormat cf = new ChoiceFormat(limits, formats);
242 String str = cf.format(d);
243 if (!str.equals("Two"))
244 errln("format(" + d + ") = " + cf.format(d));
248 * MessageFormat is incorrectly serialized/deserialized.
250 public void Test4111739()
252 MessageFormat format1 = null;
253 MessageFormat format2 = null;
254 ObjectOutputStream ostream = null;
255 ByteArrayOutputStream baos = null;
256 ObjectInputStream istream = null;
259 baos = new ByteArrayOutputStream();
260 ostream = new ObjectOutputStream(baos);
261 } catch(IOException e) {
262 errln("Unexpected exception : " + e.getMessage());
267 format1 = new MessageFormat("pattern{0}");
268 ostream.writeObject(format1);
271 byte bytes[] = baos.toByteArray();
273 istream = new ObjectInputStream(new ByteArrayInputStream(bytes));
274 format2 = (MessageFormat)istream.readObject();
275 } catch(Exception e) {
276 errln("Unexpected exception : " + e.getMessage());
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() + ")");
284 logln("Serialization for MessageFormat is OK.");
288 * MessageFormat.applyPattern allows illegal patterns.
290 public void Test4114743()
292 String originalPattern = "initial pattern";
293 MessageFormat mf = new MessageFormat(originalPattern);
294 String illegalPattern = "ab { '}' de";
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() + "\"");
305 * MessageFormat.parse has different behavior in case of null.
307 public void Test4116444()
309 String[] patterns = {"", "one", "{0,date,short}"};
310 MessageFormat mf = new MessageFormat("");
312 for (int i = 0; i < patterns.length; i++) {
313 String pattern = patterns[i];
314 mf.applyPattern(pattern);
316 Object[] array = mf.parse(null, new ParsePosition(0));
317 logln("pattern: \"" + pattern + "\"");
318 log(" parsedObjects: ");
321 for (int j = 0; j < array.length; j++) {
322 if (array[j] != null)
323 err("\"" + array[j].toString() + "\"");
326 if (j < array.length - 1) log(",");
333 } catch (Exception e) {
334 errln("pattern: \"" + pattern + "\"");
335 errln(" Exception: " + e.getMessage());
340 /* @bug 4114739 (FIX and add javadoc)
341 * MessageFormat.format has undocumented behavior about empty format objects.
343 public void Test4114739()
346 MessageFormat mf = new MessageFormat("<{0}>");
347 Object[] objs1 = null;
349 Object[] objs3 = {null};
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.");
364 * MessageFormat.applyPattern works wrong with illegal patterns.
366 public void Test4113018()
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 + "\"");
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() + "\"");
382 * ChoiceFormat is silent about the pattern usage in javadoc.
384 public void Test4106661()
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());
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));
402 * ChoiceFormat should accept \u221E as eq. to INF.
404 public void Test4094906()
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));
421 * MessageFormat.parse fails with ChoiceFormat.
423 public void Test4118592()
425 MessageFormat mf = new MessageFormat("");
426 String pattern = "{0,choice,1#YES|2#NO}";
428 for (int i = 0; i < 5; i++) {
429 String formatted = prefix + "YES";
430 mf.applyPattern(prefix + pattern);
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]);
440 * MessageFormat.parse fails for some patterns.
442 public void Test4118594()
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]);
466 * When using ChoiceFormat, MessageFormat is not good for I18n.
468 public void Test4105380()
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));
484 * MessageFormat.parse incorrectly sets errorIndex.
486 public void Test4120552()
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] + "\"");
496 logln(" (incorrectly formatted string)");
497 if (pp.getErrorIndex() == -1)
498 errln("Incorrect error index: " + pp.getErrorIndex());
500 logln(" (correctly formatted string)");
507 * MessageFormat handles single quotes in pattern wrong.
508 * This is actually a problem in ChoiceFormat; it doesn't
509 * understand single quotes.
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);
518 "'Vous' n'avez s\u00E9lectionne\u00E9 aucun clients personnels.",
519 "'Vous' avez s\u00E9lectionne\u00E9 ",
520 "'Vous' avez s\u00E9lectionne\u00E9 "
524 " client personnel.",
525 " clients personnels."
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] + "\"");
535 if (!out.startsWith(PREFIX[i]) ||
536 !out.endsWith(SUFFIX[i]))
537 errln("" + i + ": Got \"" + out + "\"; Want \"" + PREFIX[i] + "\"...\"" +
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.
551 public void TestChoicePatternQuote() {
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", "'",
558 for (int i=0; i<DATA.length; i+=3) {
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] + '"');
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 + '"');
572 logln("Ok: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"');
574 catch (IllegalArgumentException e) {
575 errln("Fail: Pattern \"" + DATA[i] + "\" -> " + e);
582 * MessageFormat.equals(null) throws a NullPointerException. The JLS states
583 * that it should return false.
585 public void Test4112104() {
586 MessageFormat format = new MessageFormat("");
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");
594 catch (NullPointerException e) {
595 errln("MessageFormat.equals(null) throws " + e);
601 * MessageFormat does not format null objects. CANNOT REPRODUCE THIS BUG.
603 public void Test4169959() {
605 logln(MessageFormat.format("This will {0}", new Object[]{"work"}));
608 logln(MessageFormat.format("This will {0}", new Object[]{ null }));
611 public void test4232154() {
612 boolean gotException = false;
614 new MessageFormat("The date is {0:date}");
615 } catch (Exception e) {
617 if (!(e instanceof IllegalArgumentException)) {
618 throw new RuntimeException("got wrong exception type");
620 if ("argument number too large at ".equals(e.getMessage())) {
621 throw new RuntimeException("got wrong exception message");
625 throw new RuntimeException("didn't get exception for invalid input");
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 + "\"");
640 // This test basically ensures that the tests defined above also work with
641 // valid named arguments.
642 public void testBugTestsWithNamesArguments() {
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'.";
648 MessageFormat messageFormatter = new MessageFormat("");
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 );
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);
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());
690 }{ // Taken from Test4052223().
691 ParsePosition pos = new ParsePosition(0);
692 if (pos.getErrorIndex() != -1) {
693 errln("ParsePosition.getErrorIndex initialization failed.");
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");
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;
714 baos = new ByteArrayOutputStream();
715 ostream = new ObjectOutputStream(baos);
716 } catch(IOException e) {
717 errln("Unexpected exception : " + e.getMessage());
722 format1 = new MessageFormat("pattern{argument}");
723 ostream.writeObject(format1);
726 byte bytes[] = baos.toByteArray();
728 istream = new ObjectInputStream(new ByteArrayInputStream(bytes));
729 format2 = (MessageFormat)istream.readObject();
730 } catch(Exception e) {
731 errln("Unexpected exception : " + e.getMessage());
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() + ")");
739 logln("Serialization for MessageFormat is OK.");
741 }{ // Taken from Test4116444().
742 String[] patterns = {"", "one", "{namedArgument,date,short}"};
743 MessageFormat mf = new MessageFormat("");
745 for (int i = 0; i < patterns.length; i++) {
746 String pattern = patterns[i];
747 mf.applyPattern(pattern);
749 Map objs = mf.parseToMap(null, new ParsePosition(0));
750 logln("pattern: \"" + pattern + "\"");
751 log(" parsedObjects: ");
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() + "\"");
762 if (keyIter.hasNext()) {
771 } catch (Exception e) {
772 errln("pattern: \"" + pattern + "\"");
773 errln(" Exception: " + e.getMessage());
776 }{ // Taken from Test4114739().
777 MessageFormat mf = new MessageFormat("<{arg}>");
779 Map objs2 = new HashMap();
780 Map objs3 = new HashMap();
781 objs3.put("arg", null);
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.");
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 + "\"");
843 private MessageFormat serializeAndDeserialize(MessageFormat original) {
845 ByteArrayOutputStream baos = new ByteArrayOutputStream();
846 ObjectOutputStream ostream = new ObjectOutputStream(baos);
847 ostream.writeObject(original);
849 byte bytes[] = baos.toByteArray();
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);
861 public void TestSerialization() {
862 MessageFormat format1 = null;
863 MessageFormat format2 = null;
865 format1 = new MessageFormat("", ULocale.GERMAN);
866 format2 = serializeAndDeserialize(format1);
867 assertEquals("MessageFormats (empty pattern) before and after serialization are not equal", format1, format2);
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);
875 "MessageFormat (with custom formats) does not "+
876 "format correctly after serialization",
878 format2.format(new Object[] { 4.4, 3.3, "+++", "***" }));