Home | History | Annotate | Download | only in text
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package org.apache.harmony.tests.java.text;
     19 
     20 import java.io.ByteArrayInputStream;
     21 import java.io.ByteArrayOutputStream;
     22 import java.io.IOException;
     23 import java.io.ObjectInputStream;
     24 import java.io.ObjectOutputStream;
     25 import java.text.ChoiceFormat;
     26 import java.text.DateFormat;
     27 import java.text.DecimalFormat;
     28 import java.text.DecimalFormatSymbols;
     29 import java.text.FieldPosition;
     30 import java.text.Format;
     31 import java.text.MessageFormat;
     32 import java.text.NumberFormat;
     33 import java.text.ParseException;
     34 import java.text.ParsePosition;
     35 import java.text.SimpleDateFormat;
     36 import java.util.Calendar;
     37 import java.util.Date;
     38 import java.util.GregorianCalendar;
     39 import java.util.Locale;
     40 import java.util.TimeZone;
     41 
     42 import junit.framework.TestCase;
     43 
     44 public class MessageFormatTest extends TestCase {
     45 
     46   private MessageFormat format1, format2, format3;
     47 
     48   private Locale defaultLocale;
     49 
     50   private void checkSerialization(MessageFormat format) {
     51     try {
     52       ByteArrayOutputStream ba = new ByteArrayOutputStream();
     53       ObjectOutputStream out = new ObjectOutputStream(ba);
     54       out.writeObject(format);
     55       out.close();
     56       ObjectInputStream in = new ObjectInputStream(
     57           new ByteArrayInputStream(ba.toByteArray()));
     58       MessageFormat read = (MessageFormat) in.readObject();
     59       assertTrue("Not equal: " + format.toPattern(), format.equals(read));
     60     } catch (IOException e) {
     61       fail("Format: " + format.toPattern()
     62           + " caused IOException: " + e);
     63     } catch (ClassNotFoundException e) {
     64       fail("Format: " + format.toPattern()
     65           + " caused ClassNotFoundException: " + e);
     66     }
     67   }
     68 
     69   public void test_formatToCharacterIteratorLjava_lang_Object() {
     70     new Support_MessageFormat("test_formatToCharacterIteratorLjava_lang_Object").t_formatToCharacterIterator();
     71 
     72     try {
     73       new MessageFormat("{1, number}").formatToCharacterIterator(null);
     74       fail();
     75     } catch (NullPointerException expected) {
     76     }
     77 
     78     try {
     79       new MessageFormat("{0, time}").formatToCharacterIterator(new Object[]{""});
     80       fail();
     81     } catch (IllegalArgumentException expected) {
     82     }
     83   }
     84 
     85 
     86   public void test_getLocale() throws Exception {
     87     Locale[] l = {
     88       Locale.FRANCE,
     89       Locale.KOREA,
     90       new Locale("FR", "fr"), // Deliberately backwards.
     91       new Locale("mk"),
     92       new Locale("mk", "MK"),
     93       Locale.US,
     94       new Locale("#ru", "@31230") // Deliberately nonsense.
     95     };
     96 
     97     String pattern = "getLocale test {0,number,#,####}";
     98 
     99     for (int i = 0; i < 0; i++) {
    100       MessageFormat mf = new MessageFormat(pattern, l[i]);
    101       Locale result = mf.getLocale();
    102       assertEquals(l[i], result);
    103       assertEquals(l[i].getLanguage(), result.getLanguage());
    104       assertEquals(l[i].getCountry(), result.getCountry());
    105     }
    106 
    107     MessageFormat mf = new MessageFormat(pattern);
    108     mf.setLocale(null);
    109     Locale result = mf.getLocale();
    110     assertEquals(null, result);
    111   }
    112 
    113   public void test_setFormatILjava_text_Format() throws Exception {
    114     // case 1: Compare getFormats() results after calls to setFormat()
    115     MessageFormat f1 = (MessageFormat) format1.clone();
    116     f1.setFormat(0, DateFormat.getTimeInstance());
    117     f1.setFormat(1, DateFormat.getTimeInstance());
    118     f1.setFormat(2, NumberFormat.getInstance());
    119     f1.setFormat(3, new ChoiceFormat("0#off|1#on"));
    120     f1.setFormat(4, new ChoiceFormat("1#few|2#ok|3#a lot"));
    121     f1.setFormat(5, DateFormat.getTimeInstance());
    122 
    123     Format[] formats = f1.getFormats();
    124     formats = f1.getFormats();
    125 
    126     Format[] correctFormats = new Format[] {
    127       DateFormat.getTimeInstance(),
    128       DateFormat.getTimeInstance(),
    129       NumberFormat.getInstance(),
    130       new ChoiceFormat("0#off|1#on"),
    131       new ChoiceFormat("1#few|2#ok|3#a lot"),
    132       DateFormat.getTimeInstance()
    133     };
    134 
    135     assertEquals(correctFormats.length, formats.length);
    136     for (int i = 0; i < correctFormats.length; i++) {
    137       assertEquals("Test1B:wrong format for pattern index " + i + ":", correctFormats[i], formats[i]);
    138     }
    139 
    140     // case 2: Try to setFormat using incorrect index
    141     try {
    142       f1.setFormat(-1, DateFormat.getDateInstance());
    143       fail();
    144     } catch (ArrayIndexOutOfBoundsException expected) {
    145     }
    146     try {
    147       f1.setFormat(f1.getFormats().length, DateFormat.getDateInstance());
    148       fail();
    149     } catch (ArrayIndexOutOfBoundsException expected) {
    150     }
    151   }
    152 
    153   public void test_parseObjectLjava_lang_StringLjavajava_text_ParsePosition() throws Exception {
    154     MessageFormat mf = new MessageFormat("{0,number,#.##}, {0,number,#.#}");
    155     // case 1: Try to parse correct data string.
    156     Object[] objs = { new Double(3.1415) };
    157     String result = mf.format(objs);
    158     // result now equals "3.14, 3.1"
    159     Object[] res = null;
    160     ParsePosition pp = new ParsePosition(0);
    161     int parseIndex = pp.getIndex();
    162     res = (Object[]) mf.parseObject(result, pp);
    163     assertTrue("Parse operation return null", res != null);
    164     assertTrue("parse operation return array with incorrect length", 1 == res.length);
    165     assertTrue("ParseIndex is incorrect", pp.getIndex() != parseIndex);
    166     assertTrue("Result object is incorrect", new Double(3.1).equals(res[0]));
    167 
    168     // case 2: Try to parse partially correct data string.
    169     pp.setIndex(0);
    170     char[] cur = result.toCharArray();
    171     cur[cur.length / 2] = 'Z';
    172     String partialCorrect = new String(cur);
    173     res = (Object[]) mf.parseObject(partialCorrect, pp);
    174     assertTrue("Parse operation return null", res == null);
    175     assertTrue("ParseIndex is incorrect", pp.getIndex() == 0);
    176     assertTrue("ParseErrorIndex is incorrect", pp.getErrorIndex() == cur.length / 2);
    177 
    178     // case 3: Try to use argument ParsePosition as null.
    179     try {
    180       mf.parseObject(result, null);
    181       fail();
    182     } catch (NullPointerException expected) {
    183     }
    184   }
    185 
    186   public void test_parseLjava_lang_String() throws ParseException {
    187     // This test assumes a default DateFormat.is24Hour setting.
    188     DateFormat.is24Hour = null;
    189 
    190     String pattern = "A {3, number, currency} B {2, time} C {0, number, percent} D {4}  E {1,choice,0#off|1#on} F {0, date}";
    191     MessageFormat mf = new MessageFormat(pattern);
    192     String sToParse = "A $12,345.00 B 9:56:07 AM C 3,200% D 1/15/70 9:56 AM  E on F Jan 1, 1970";
    193     Object[] result = mf.parse(sToParse);
    194 
    195     assertTrue("No result: " + result.length, result.length == 5);
    196     assertTrue("Object 0 is not date", result[0] instanceof Date);
    197     assertEquals("Object 1 is not stringr", result[1].toString(), "1.0");
    198     assertTrue("Object 2 is not date", result[2] instanceof Date);
    199     assertEquals("Object 3 is not number", result[3].toString(), "12345");
    200     assertEquals("Object 4 is not string", result[4].toString(), "1/15/70 9:56 AM");
    201 
    202     sToParse = "xxdate is Feb 28, 1999";
    203     try {
    204       result = format1.parse(sToParse);
    205       fail();
    206     } catch (java.text.ParseException expected) {
    207     }
    208 
    209     sToParse = "vm=Test, @3 4 6, 3   ";
    210     mf = new MessageFormat("vm={0},{1},{2}");
    211     result = mf.parse(sToParse);
    212     assertTrue("No result: " + result.length, result.length == 3);
    213     assertEquals("Object 0 is not string", result[0].toString(), "Test");
    214     assertEquals("Object 1 is not string", result[1].toString(), " @3 4 6");
    215     assertEquals("Object 2 is not string", result[2].toString(), " 3   ");
    216 
    217     try {
    218       result = mf.parse(null);
    219       fail();
    220     } catch (java.text.ParseException expected) {
    221     }
    222   }
    223 
    224   public void test_setFormats$Ljava_text_Format() throws Exception {
    225     MessageFormat f1 = (MessageFormat) format1.clone();
    226 
    227     // case 1: Test with repeating formats and max argument index < max
    228     // offset
    229     // compare getFormats() results after calls to setFormats(Format[])
    230     Format[] correctFormats = new Format[] {
    231       DateFormat.getTimeInstance(),
    232       new ChoiceFormat("0#off|1#on"),
    233       DateFormat.getTimeInstance(),
    234       NumberFormat.getCurrencyInstance(),
    235       new ChoiceFormat("1#few|2#ok|3#a lot")
    236     };
    237 
    238     f1.setFormats(correctFormats);
    239     Format[] formats = f1.getFormats();
    240 
    241     assertTrue("Test1A:Returned wrong number of formats:", correctFormats.length <= formats.length);
    242     for (int i = 0; i < correctFormats.length; i++) {
    243       assertEquals("Test1B:wrong format for argument index " + i + ":", correctFormats[i], formats[i]);
    244     }
    245 
    246     // case 2: Try to pass null argument to setFormats().
    247     try {
    248       f1.setFormats(null);
    249       fail();
    250     } catch (NullPointerException expected) {
    251     }
    252   }
    253 
    254   public void test_formatLjava_lang_StringLjava_lang_Object() {
    255     TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    256     int iCurrency = 123;
    257     int iInteger  = Integer.MIN_VALUE;
    258 
    259     Date     date     = new Date(12345678);
    260     Object[] args     = { date, iCurrency, iInteger };
    261     String   resStr   = "Date: Jan 1, 1970 Currency: $" + iCurrency + ".00 Integer: -2,147,483,648";
    262     String   pattern  = "Date: {0,date} Currency: {1, number, currency} Integer: {2, number, integer}";
    263     String   sFormat  = MessageFormat.format(pattern, (Object[]) args);
    264     assertEquals(
    265         "format(String, Object[]) with valid parameters returns incorrect string: case 1",
    266         sFormat, resStr);
    267 
    268     pattern = "abc {4, number, integer} def {3,date} ghi {2,number} jkl {1,choice,0#low|1#high} mnop {0}";
    269     resStr  = "abc -2,147,483,648 def Jan 1, 1970 ghi -2,147,483,648 jkl high mnop -2,147,483,648";
    270     Object[] args_ = { iInteger, 1, iInteger, date, iInteger };
    271     sFormat = MessageFormat.format(pattern, args_);
    272     assertEquals(
    273         "format(String, Object[]) with valid parameters returns incorrect string: case 1",
    274         sFormat, resStr);
    275 
    276     try {
    277       args = null;
    278       MessageFormat.format(null, args);
    279       fail();
    280     } catch (Exception expected) {
    281     }
    282 
    283     try {
    284       MessageFormat.format("Invalid {1,foobar} format descriptor!", new Object[] {iInteger} );
    285       fail();
    286     } catch (IllegalArgumentException expected) {
    287     }
    288 
    289     try {
    290       MessageFormat.format("Invalid {1,date,invalid-spec} format descriptor!", new Object[]{""});
    291       fail();
    292     } catch (IllegalArgumentException expected) {
    293     }
    294 
    295     try {
    296       MessageFormat.format("{0,number,integer", new Object[] {iInteger});
    297       fail();
    298     } catch (IllegalArgumentException expected) {
    299     }
    300 
    301     try {
    302       MessageFormat.format("Valid {1, date} format {0, number} descriptor!", new Object[]{ "" } );
    303       fail();
    304     } catch (IllegalArgumentException expected) {
    305     }
    306   }
    307 
    308   public void test_ConstructorLjava_lang_StringLjava_util_Locale() {
    309     Locale mk = new Locale("mk", "MK");
    310     MessageFormat format = new MessageFormat("Date: {0,date} Currency: {1, number, currency} Integer: {2, number, integer}", mk);
    311     assertEquals(format.getLocale(), mk);
    312     assertEquals(format.getFormats()[0], DateFormat.getDateInstance(DateFormat.DEFAULT, mk));
    313     assertEquals(format.getFormats()[1], NumberFormat.getCurrencyInstance(mk));
    314     assertEquals(format.getFormats()[2], NumberFormat.getIntegerInstance(mk));
    315   }
    316 
    317   public void test_ConstructorLjava_lang_String() {
    318     MessageFormat format = new MessageFormat(
    319         "abc {4,time} def {3,date} ghi {2,number} jkl {1,choice,0#low|1#high} mnop {0}");
    320     assertTrue("Not a MessageFormat",
    321                format.getClass() == MessageFormat.class);
    322     Format[] formats = format.getFormats();
    323     assertNotNull("null formats", formats);
    324     assertTrue("Wrong format count: " + formats.length, formats.length >= 5);
    325     assertTrue("Wrong time format", formats[0].equals(DateFormat
    326                                                           .getTimeInstance()));
    327     assertTrue("Wrong date format", formats[1].equals(DateFormat
    328                                                           .getDateInstance()));
    329     assertTrue("Wrong number format", formats[2].equals(NumberFormat
    330                                                             .getInstance()));
    331     assertTrue("Wrong choice format", formats[3].equals(new ChoiceFormat(
    332                                                             "0.0#low|1.0#high")));
    333     assertNull("Wrong string format", formats[4]);
    334 
    335     Date date = new Date();
    336     FieldPosition pos = new FieldPosition(-1);
    337     StringBuffer buffer = new StringBuffer();
    338     format.format(new Object[] { "123", new Double(1.6), new Double(7.2),
    339         date, date }, buffer, pos);
    340     String result = buffer.toString();
    341     buffer.setLength(0);
    342     buffer.append("abc ");
    343     buffer.append(DateFormat.getTimeInstance().format(date));
    344     buffer.append(" def ");
    345     buffer.append(DateFormat.getDateInstance().format(date));
    346     buffer.append(" ghi ");
    347     buffer.append(NumberFormat.getInstance().format(new Double(7.2)));
    348     buffer.append(" jkl high mnop 123");
    349     assertTrue("Wrong answer:\n" + result + "\n" + buffer, result
    350                    .equals(buffer.toString()));
    351 
    352     assertEquals("Simple string", "Test message", new MessageFormat("Test message").format(
    353         new Object[0]));
    354 
    355     result = new MessageFormat("Don't").format(new Object[0]);
    356     assertTrue("Should not throw IllegalArgumentException: " + result,
    357                "Dont".equals(result));
    358 
    359     try {
    360       new MessageFormat("Invalid {1,foobar} format descriptor!");
    361       fail("Expected test_ConstructorLjava_lang_String to throw IAE.");
    362     } catch (IllegalArgumentException ex) {
    363       // expected
    364     }
    365 
    366     try {
    367       new MessageFormat(
    368           "Invalid {1,date,invalid-spec} format descriptor!");
    369     } catch (IllegalArgumentException ex) {
    370       // expected
    371     }
    372 
    373     checkSerialization(new MessageFormat(""));
    374     checkSerialization(new MessageFormat("noargs"));
    375     checkSerialization(new MessageFormat("{0}"));
    376     checkSerialization(new MessageFormat("a{0}"));
    377     checkSerialization(new MessageFormat("{0}b"));
    378     checkSerialization(new MessageFormat("a{0}b"));
    379 
    380     // Regression for HARMONY-65
    381     try {
    382       new MessageFormat("{0,number,integer");
    383       fail("Assert 0: Failed to detect unmatched brackets.");
    384     } catch (IllegalArgumentException e) {
    385       // expected
    386     }
    387   }
    388 
    389     public void test_applyPatternLjava_lang_String() {
    390         MessageFormat format = new MessageFormat("test");
    391         format.applyPattern("xx {0}");
    392 		assertEquals("Invalid number", "xx 46", format.format(
    393 				new Object[] { new Integer(46) }));
    394         Date date = new Date();
    395         String result = format.format(new Object[] { date });
    396         String expected = "xx " + DateFormat.getInstance().format(date);
    397         assertTrue("Invalid date:\n" + result + "\n" + expected, result
    398                 .equals(expected));
    399         format = new MessageFormat("{0,date}{1,time}{2,number,integer}");
    400         format.applyPattern("nothing");
    401 		assertEquals("Found formats", "nothing", format.toPattern());
    402 
    403         format.applyPattern("{0}");
    404 		assertNull("Wrong format", format.getFormats()[0]);
    405 		assertEquals("Wrong pattern", "{0}", format.toPattern());
    406 
    407         format.applyPattern("{0, \t\u001ftime }");
    408         assertTrue("Wrong time format", format.getFormats()[0]
    409                 .equals(DateFormat.getTimeInstance()));
    410 		assertEquals("Wrong time pattern", "{0,time}", format.toPattern());
    411         format.applyPattern("{0,Time, Short\n}");
    412         assertTrue("Wrong short time format", format.getFormats()[0]
    413                 .equals(DateFormat.getTimeInstance(DateFormat.SHORT)));
    414 		assertEquals("Wrong short time pattern",
    415 				"{0,time,short}", format.toPattern());
    416         format.applyPattern("{0,TIME,\nmedium  }");
    417         assertTrue("Wrong medium time format", format.getFormats()[0]
    418                 .equals(DateFormat.getTimeInstance(DateFormat.MEDIUM)));
    419 		assertEquals("Wrong medium time pattern",
    420 				"{0,time}", format.toPattern());
    421         format.applyPattern("{0,time,LONG}");
    422         assertTrue("Wrong long time format", format.getFormats()[0]
    423                 .equals(DateFormat.getTimeInstance(DateFormat.LONG)));
    424 		assertEquals("Wrong long time pattern",
    425 				"{0,time,long}", format.toPattern());
    426         format.setLocale(Locale.FRENCH); // use French since English has the
    427         // same LONG and FULL time patterns
    428         format.applyPattern("{0,time, Full}");
    429         assertTrue("Wrong full time format", format.getFormats()[0]
    430                 .equals(DateFormat.getTimeInstance(DateFormat.FULL,
    431                         Locale.FRENCH)));
    432 		assertEquals("Wrong full time pattern",
    433 				"{0,time,full}", format.toPattern());
    434         format.setLocale(Locale.getDefault());
    435 
    436         format.applyPattern("{0, date}");
    437         assertTrue("Wrong date format", format.getFormats()[0]
    438                 .equals(DateFormat.getDateInstance()));
    439 		assertEquals("Wrong date pattern", "{0,date}", format.toPattern());
    440         format.applyPattern("{0, date, short}");
    441         assertTrue("Wrong short date format", format.getFormats()[0]
    442                 .equals(DateFormat.getDateInstance(DateFormat.SHORT)));
    443 		assertEquals("Wrong short date pattern",
    444 				"{0,date,short}", format.toPattern());
    445         format.applyPattern("{0, date, medium}");
    446         assertTrue("Wrong medium date format", format.getFormats()[0]
    447                 .equals(DateFormat.getDateInstance(DateFormat.MEDIUM)));
    448 		assertEquals("Wrong medium date pattern",
    449 				"{0,date}", format.toPattern());
    450         format.applyPattern("{0, date, long}");
    451         assertTrue("Wrong long date format", format.getFormats()[0]
    452                 .equals(DateFormat.getDateInstance(DateFormat.LONG)));
    453 		assertEquals("Wrong long date pattern",
    454 				"{0,date,long}", format.toPattern());
    455         format.applyPattern("{0, date, full}");
    456         assertTrue("Wrong full date format", format.getFormats()[0]
    457                 .equals(DateFormat.getDateInstance(DateFormat.FULL)));
    458 		assertEquals("Wrong full date pattern",
    459 				"{0,date,full}", format.toPattern());
    460 
    461         format.applyPattern("{0, date, MMM d {hh:mm:ss}}");
    462 		assertEquals("Wrong time/date format", " MMM d {hh:mm:ss}", ((SimpleDateFormat) (format
    463 				.getFormats()[0])).toPattern());
    464 		assertEquals("Wrong time/date pattern",
    465 				"{0,date, MMM d {hh:mm:ss}}", format.toPattern());
    466 
    467         format.applyPattern("{0, number}");
    468         assertTrue("Wrong number format", format.getFormats()[0]
    469                 .equals(NumberFormat.getNumberInstance()));
    470 		assertEquals("Wrong number pattern",
    471 				"{0,number}", format.toPattern());
    472         format.applyPattern("{0, number, currency}");
    473         assertTrue("Wrong currency number format", format.getFormats()[0]
    474                 .equals(NumberFormat.getCurrencyInstance()));
    475 		assertEquals("Wrong currency number pattern",
    476 				"{0,number,currency}", format.toPattern());
    477         format.applyPattern("{0, number, percent}");
    478         assertTrue("Wrong percent number format", format.getFormats()[0]
    479                 .equals(NumberFormat.getPercentInstance()));
    480 		assertEquals("Wrong percent number pattern",
    481 				"{0,number,percent}", format.toPattern());
    482         format.applyPattern("{0, number, integer}");
    483 
    484         DecimalFormat expectedNumberFormat = (DecimalFormat) NumberFormat.getIntegerInstance();
    485         DecimalFormat actualNumberFormat = (DecimalFormat) format.getFormats()[0];
    486         assertEquals(expectedNumberFormat.getDecimalFormatSymbols(), actualNumberFormat.getDecimalFormatSymbols());
    487         assertEquals(expectedNumberFormat.isParseIntegerOnly(), actualNumberFormat.isParseIntegerOnly());
    488         assertEquals("Wrong integer number pattern", "{0,number,integer}", format.toPattern());
    489         assertEquals(expectedNumberFormat, format.getFormats()[0]);
    490 
    491         format.applyPattern("{0, number, {'#'}##0.0E0}");
    492 
    493         /*
    494          * TODO validate these assertions
    495          * String actual = ((DecimalFormat)(format.getFormats()[0])).toPattern();
    496          * assertEquals("Wrong pattern number format", "' {#}'##0.0E0", actual);
    497          * assertEquals("Wrong pattern number pattern", "{0,number,' {#}'##0.0E0}", format.toPattern());
    498          *
    499          */
    500 
    501         format.applyPattern("{0, choice,0#no|1#one|2#{1,number}}");
    502 		assertEquals("Wrong choice format",
    503 
    504 						"0.0#no|1.0#one|2.0#{1,number}", ((ChoiceFormat) format.getFormats()[0]).toPattern());
    505 		assertEquals("Wrong choice pattern",
    506 				"{0,choice,0.0#no|1.0#one|2.0#{1,number}}", format.toPattern());
    507 		assertEquals("Wrong formatted choice", "3.6", format.format(
    508 				new Object[] { new Integer(2), new Float(3.6) }));
    509 
    510         try {
    511             format.applyPattern("WRONG MESSAGE FORMAT {0,number,{}");
    512             fail("Expected IllegalArgumentException for invalid pattern");
    513         } catch (IllegalArgumentException e) {
    514         }
    515 
    516         // Regression for HARMONY-65
    517         MessageFormat mf = new MessageFormat("{0,number,integer}");
    518         String badpattern = "{0,number,#";
    519         try {
    520             mf.applyPattern(badpattern);
    521             fail("Assert 0: Failed to detect unmatched brackets.");
    522         } catch (IllegalArgumentException e) {
    523             // expected
    524         }
    525     }
    526 
    527     public void test_clone() {
    528         MessageFormat format = new MessageFormat("'{'choice'}'{0}");
    529         MessageFormat clone = (MessageFormat) format.clone();
    530         assertTrue("Clone not equal", format.equals(clone));
    531 		assertEquals("Wrong answer",
    532 				"{choice}{0}", format.format(new Object[] {}));
    533         clone.setFormat(0, DateFormat.getInstance());
    534         assertTrue("Clone shares format data", !format.equals(clone));
    535         format = (MessageFormat) clone.clone();
    536         Format[] formats = clone.getFormats();
    537         ((SimpleDateFormat) formats[0]).applyPattern("adk123");
    538         assertTrue("Clone shares format data", !format.equals(clone));
    539     }
    540 
    541     public void test_equalsLjava_lang_Object() {
    542         MessageFormat format1 = new MessageFormat("{0}");
    543         MessageFormat format2 = new MessageFormat("{1}");
    544         assertTrue("Should not be equal", !format1.equals(format2));
    545         format2.applyPattern("{0}");
    546         assertTrue("Should be equal", format1.equals(format2));
    547         SimpleDateFormat date = (SimpleDateFormat) DateFormat.getTimeInstance();
    548         format1.setFormat(0, DateFormat.getTimeInstance());
    549         format2.setFormat(0, new SimpleDateFormat(date.toPattern()));
    550         assertTrue("Should be equal2", format1.equals(format2));
    551     }
    552 
    553   public void test_hashCode() {
    554       assertEquals("Should be equal", 3648, new MessageFormat("rr", null).hashCode());
    555   }
    556 
    557   public void test_format$Ljava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition() {
    558     MessageFormat format = new MessageFormat("{1,number,integer}");
    559     StringBuffer buffer = new StringBuffer();
    560     format.format(new Object[] { "0", new Double(53.863) }, buffer,
    561                   new FieldPosition(0));
    562     assertEquals("Wrong result", "54", buffer.toString());
    563 
    564     format.format(new Object[] { "0", new Double(53.863) }, buffer,
    565                   new FieldPosition(MessageFormat.Field.ARGUMENT));
    566     assertEquals("Wrong result", "5454", buffer.toString());
    567 
    568     buffer = new StringBuffer();
    569     format.applyPattern("{0,choice,0#zero|1#one '{1,choice,2#two {2,time}}'}");
    570     Date date = new Date();
    571     String expectedText = "one two " + DateFormat.getTimeInstance().format(date);
    572     format.format(new Object[] { new Double(1.6), new Integer(3), date }, buffer, new FieldPosition(MessageFormat.Field.ARGUMENT));
    573     assertEquals("Choice not recursive:\n" + expectedText + "\n" + buffer, expectedText, buffer.toString());
    574 
    575     StringBuffer str = format.format(new Object[] { new Double(0.6),
    576         new Integer(3)}, buffer, null);
    577     assertEquals(expectedText + "zero", str.toString());
    578     assertEquals(expectedText + "zero", buffer.toString());
    579 
    580     try {
    581       format.format(new Object[] { "0", new Double(1), "" }, buffer,
    582                     new FieldPosition(MessageFormat.Field.ARGUMENT));
    583       fail();
    584     } catch (IllegalArgumentException expected) {
    585     }
    586 
    587     try {
    588       format.format(new Object[] { "",  new Integer(3)}, buffer,
    589                     new FieldPosition(MessageFormat.Field.ARGUMENT));
    590       fail();
    591     } catch (IllegalArgumentException expected) {
    592     }
    593   }
    594 
    595   public void test_formatLjava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition() {
    596     new Support_MessageFormat(
    597         "test_formatLjava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition")
    598         .t_format_with_FieldPosition();
    599 
    600     String pattern = "On {4,date} at {3,time}, he ate {2,number, integer} hamburger{2,choice,1#|1<s}.";
    601     MessageFormat format = new MessageFormat(pattern, Locale.US);
    602     Object[] objects = new Object[] { "", new Integer(3), 8, ""};
    603     try {
    604       format.format(objects, new StringBuffer(), new FieldPosition(DateFormat.Field.AM_PM));
    605       fail();
    606     } catch (IllegalArgumentException expected) {
    607     }
    608   }
    609 
    610   public void test_getFormats() {
    611     // test with repeating formats and max argument index < max offset
    612     Format[] formats = format1.getFormats();
    613     Format[] correctFormats = new Format[] {
    614       NumberFormat.getCurrencyInstance(),
    615       DateFormat.getTimeInstance(),
    616       NumberFormat.getPercentInstance(), null,
    617       new ChoiceFormat("0#off|1#on"), DateFormat.getDateInstance(), };
    618 
    619     assertEquals("Test1:Returned wrong number of formats:",
    620                  correctFormats.length, formats.length);
    621     for (int i = 0; i < correctFormats.length; i++) {
    622       assertEquals("Test1:wrong format for pattern index " + i + ":",
    623                    correctFormats[i], formats[i]);
    624     }
    625 
    626     // test with max argument index > max offset
    627     formats = format2.getFormats();
    628     correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
    629         DateFormat.getTimeInstance(),
    630         NumberFormat.getPercentInstance(), null,
    631         new ChoiceFormat("0#off|1#on"), DateFormat.getDateInstance() };
    632 
    633     assertEquals("Test2:Returned wrong number of formats:",
    634                  correctFormats.length, formats.length);
    635     for (int i = 0; i < correctFormats.length; i++) {
    636       assertEquals("Test2:wrong format for pattern index " + i + ":",
    637                    correctFormats[i], formats[i]);
    638     }
    639 
    640     // test with argument number being zero
    641     formats = format3.getFormats();
    642     assertEquals("Test3: Returned wrong number of formats:", 0,
    643                  formats.length);
    644   }
    645 
    646     public void test_getFormatsByArgumentIndex() {
    647         // test with repeating formats and max argument index < max offset
    648         Format[] formats = format1.getFormatsByArgumentIndex();
    649         Format[] correctFormats = new Format[] { DateFormat.getDateInstance(),
    650                 new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(),
    651                 NumberFormat.getCurrencyInstance(), null };
    652 
    653         assertEquals("Test1:Returned wrong number of formats:",
    654                 correctFormats.length, formats.length);
    655         for (int i = 0; i < correctFormats.length; i++) {
    656             assertEquals("Test1:wrong format for argument index " + i + ":",
    657                     correctFormats[i], formats[i]);
    658         }
    659 
    660         // test with max argument index > max offset
    661         formats = format2.getFormatsByArgumentIndex();
    662         correctFormats = new Format[] { DateFormat.getDateInstance(),
    663                 new ChoiceFormat("0#off|1#on"), null,
    664                 NumberFormat.getCurrencyInstance(), null, null, null, null,
    665                 DateFormat.getTimeInstance() };
    666 
    667         assertEquals("Test2:Returned wrong number of formats:",
    668                 correctFormats.length, formats.length);
    669         for (int i = 0; i < correctFormats.length; i++) {
    670             assertEquals("Test2:wrong format for argument index " + i + ":",
    671                     correctFormats[i], formats[i]);
    672         }
    673 
    674         // test with argument number being zero
    675         formats = format3.getFormatsByArgumentIndex();
    676         assertEquals("Test3: Returned wrong number of formats:", 0,
    677                 formats.length);
    678     }
    679 
    680     public void test_setFormatByArgumentIndexILjava_text_Format() {
    681         // test for method setFormatByArgumentIndex(int, Format)
    682         MessageFormat f1 = (MessageFormat) format1.clone();
    683         f1.setFormatByArgumentIndex(0, DateFormat.getTimeInstance());
    684         f1.setFormatByArgumentIndex(4, new ChoiceFormat("1#few|2#ok|3#a lot"));
    685 
    686         // test with repeating formats and max argument index < max offset
    687         // compare getFormatsByArgumentIndex() results after calls to
    688         // setFormatByArgumentIndex()
    689         Format[] formats = f1.getFormatsByArgumentIndex();
    690 
    691         Format[] correctFormats = new Format[] { DateFormat.getTimeInstance(),
    692                 new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(),
    693                 NumberFormat.getCurrencyInstance(),
    694                 new ChoiceFormat("1#few|2#ok|3#a lot") };
    695 
    696         assertEquals("Test1A:Returned wrong number of formats:",
    697                 correctFormats.length, formats.length);
    698         for (int i = 0; i < correctFormats.length; i++) {
    699             assertEquals("Test1B:wrong format for argument index " + i + ":",
    700                     correctFormats[i], formats[i]);
    701         }
    702 
    703         // compare getFormats() results after calls to
    704         // setFormatByArgumentIndex()
    705         formats = f1.getFormats();
    706 
    707         correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
    708                 DateFormat.getTimeInstance(), DateFormat.getTimeInstance(),
    709                 new ChoiceFormat("1#few|2#ok|3#a lot"),
    710                 new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(), };
    711 
    712         assertEquals("Test1C:Returned wrong number of formats:",
    713                 correctFormats.length, formats.length);
    714         for (int i = 0; i < correctFormats.length; i++) {
    715             assertEquals("Test1D:wrong format for pattern index " + i + ":",
    716                     correctFormats[i], formats[i]);
    717         }
    718 
    719         // test setting argumentIndexes that are not used
    720         MessageFormat f2 = (MessageFormat) format2.clone();
    721         f2.setFormatByArgumentIndex(2, NumberFormat.getPercentInstance());
    722         f2.setFormatByArgumentIndex(4, DateFormat.getTimeInstance());
    723 
    724         formats = f2.getFormatsByArgumentIndex();
    725         correctFormats = format2.getFormatsByArgumentIndex();
    726 
    727         assertEquals("Test2A:Returned wrong number of formats:",
    728                 correctFormats.length, formats.length);
    729         for (int i = 0; i < correctFormats.length; i++) {
    730             assertEquals("Test2B:wrong format for argument index " + i + ":",
    731                     correctFormats[i], formats[i]);
    732         }
    733 
    734         formats = f2.getFormats();
    735         correctFormats = format2.getFormats();
    736 
    737         assertEquals("Test2C:Returned wrong number of formats:",
    738                 correctFormats.length, formats.length);
    739         for (int i = 0; i < correctFormats.length; i++) {
    740             assertEquals("Test2D:wrong format for pattern index " + i + ":",
    741                     correctFormats[i], formats[i]);
    742         }
    743 
    744         // test exceeding the argumentIndex number
    745         MessageFormat f3 = (MessageFormat) format3.clone();
    746         f3.setFormatByArgumentIndex(1, NumberFormat.getCurrencyInstance());
    747 
    748         formats = f3.getFormatsByArgumentIndex();
    749         assertEquals("Test3A:Returned wrong number of formats:", 0,
    750                 formats.length);
    751 
    752         formats = f3.getFormats();
    753         assertEquals("Test3B:Returned wrong number of formats:", 0,
    754                 formats.length);
    755     }
    756 
    757     public void test_setFormatsByArgumentIndex$Ljava_text_Format() {
    758         MessageFormat f1 = (MessageFormat) format1.clone();
    759 
    760         // test with repeating formats and max argument index < max offset
    761         // compare getFormatsByArgumentIndex() results after calls to
    762         // setFormatsByArgumentIndex(Format[])
    763         Format[] correctFormats = new Format[] { DateFormat.getTimeInstance(),
    764                 new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(),
    765                 NumberFormat.getCurrencyInstance(),
    766                 new ChoiceFormat("1#few|2#ok|3#a lot") };
    767 
    768         f1.setFormatsByArgumentIndex(correctFormats);
    769         Format[] formats = f1.getFormatsByArgumentIndex();
    770 
    771         assertEquals("Test1A:Returned wrong number of formats:",
    772                 correctFormats.length, formats.length);
    773         for (int i = 0; i < correctFormats.length; i++) {
    774             assertEquals("Test1B:wrong format for argument index " + i + ":",
    775                     correctFormats[i], formats[i]);
    776         }
    777 
    778         // compare getFormats() results after calls to
    779         // setFormatByArgumentIndex()
    780         formats = f1.getFormats();
    781         correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
    782                 DateFormat.getTimeInstance(), DateFormat.getTimeInstance(),
    783                 new ChoiceFormat("1#few|2#ok|3#a lot"),
    784                 new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(), };
    785 
    786         assertEquals("Test1C:Returned wrong number of formats:",
    787                 correctFormats.length, formats.length);
    788         for (int i = 0; i < correctFormats.length; i++) {
    789             assertEquals("Test1D:wrong format for pattern index " + i + ":",
    790                     correctFormats[i], formats[i]);
    791         }
    792 
    793         // test setting argumentIndexes that are not used
    794         MessageFormat f2 = (MessageFormat) format2.clone();
    795         Format[] inputFormats = new Format[] { DateFormat.getDateInstance(),
    796                 new ChoiceFormat("0#off|1#on"),
    797                 NumberFormat.getPercentInstance(),
    798                 NumberFormat.getCurrencyInstance(),
    799                 DateFormat.getTimeInstance(), null, null, null,
    800                 DateFormat.getTimeInstance() };
    801         f2.setFormatsByArgumentIndex(inputFormats);
    802 
    803         formats = f2.getFormatsByArgumentIndex();
    804         correctFormats = format2.getFormatsByArgumentIndex();
    805 
    806         assertEquals("Test2A:Returned wrong number of formats:",
    807                 correctFormats.length, formats.length);
    808         for (int i = 0; i < correctFormats.length; i++) {
    809             assertEquals("Test2B:wrong format for argument index " + i + ":",
    810                     correctFormats[i], formats[i]);
    811         }
    812 
    813         formats = f2.getFormats();
    814         correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
    815                 DateFormat.getTimeInstance(), DateFormat.getDateInstance(),
    816                 null, new ChoiceFormat("0#off|1#on"),
    817                 DateFormat.getDateInstance() };
    818 
    819         assertEquals("Test2C:Returned wrong number of formats:",
    820                 correctFormats.length, formats.length);
    821         for (int i = 0; i < correctFormats.length; i++) {
    822             assertEquals("Test2D:wrong format for pattern index " + i + ":",
    823                     correctFormats[i], formats[i]);
    824         }
    825 
    826         // test exceeding the argumentIndex number
    827         MessageFormat f3 = (MessageFormat) format3.clone();
    828         f3.setFormatsByArgumentIndex(inputFormats);
    829 
    830         formats = f3.getFormatsByArgumentIndex();
    831         assertEquals("Test3A:Returned wrong number of formats:", 0,
    832                 formats.length);
    833 
    834         formats = f3.getFormats();
    835         assertEquals("Test3B:Returned wrong number of formats:", 0,
    836                 formats.length);
    837 
    838     }
    839 
    840     public void test_parseLjava_lang_StringLjava_text_ParsePosition() {
    841         MessageFormat format = new MessageFormat("date is {0,date,MMM d, yyyy}");
    842         ParsePosition pos = new ParsePosition(2);
    843         Object[] result = (Object[]) format
    844                 .parse("xxdate is Feb 28, 1999", pos);
    845         assertTrue("No result: " + result.length, result.length >= 1);
    846         assertTrue("Wrong answer", ((Date) result[0])
    847                 .equals(new GregorianCalendar(1999, Calendar.FEBRUARY, 28)
    848                         .getTime()));
    849 
    850         MessageFormat mf = new MessageFormat("vm={0},{1},{2}");
    851         result = mf.parse("vm=win,foo,bar", new ParsePosition(0));
    852         assertTrue("Invalid parse", result[0].equals("win")
    853                 && result[1].equals("foo") && result[2].equals("bar"));
    854 
    855         mf = new MessageFormat("{0}; {0}; {0}");
    856         String parse = "a; b; c";
    857         result = mf.parse(parse, new ParsePosition(0));
    858         assertEquals("Wrong variable result", "c", result[0]);
    859 
    860         mf = new MessageFormat("before {0}, after {1,number}");
    861         parse = "before you, after 42";
    862         pos.setIndex(0);
    863         pos.setErrorIndex(8);
    864         result = mf.parse(parse, pos);
    865         assertEquals(2, result.length);
    866 
    867         try {
    868             mf.parse(parse, null);
    869             fail();
    870         } catch (NullPointerException expected) {
    871         }
    872 
    873         // This should _not_ throw.
    874         mf.parse(null, pos);
    875     }
    876 
    877   public void test_setLocaleLjava_util_Locale() {
    878     MessageFormat format = new MessageFormat("date {0,date}");
    879     format.setLocale(Locale.CHINA);
    880     assertEquals("Wrong locale1", Locale.CHINA, format.getLocale());
    881     format.applyPattern("{1,date}");
    882     assertEquals("Wrong locale3", DateFormat.getDateInstance(DateFormat.DEFAULT,
    883                                                              Locale.CHINA), format.getFormats()[0]);
    884   }
    885 
    886   public void test_toPattern() {
    887     String pattern = "[{0}]";
    888     MessageFormat mf = new MessageFormat(pattern);
    889     assertTrue("Wrong pattern", mf.toPattern().equals(pattern));
    890 
    891     // Regression for HARMONY-59
    892     new MessageFormat("CHOICE {1,choice}").toPattern();
    893   }
    894 
    895   protected void setUp() {
    896     defaultLocale = Locale.getDefault();
    897     Locale.setDefault(Locale.US);
    898 
    899     // test with repeating formats and max argument index < max offset
    900     String pattern = "A {3, number, currency} B {2, time} C {0, number, percent} D {4}  E {1,choice,0#off|1#on} F {0, date}";
    901     format1 = new MessageFormat(pattern);
    902 
    903     // test with max argument index > max offset
    904     pattern = "A {3, number, currency} B {8, time} C {0, number, percent} D {6}  E {1,choice,0#off|1#on} F {0, date}";
    905     format2 = new MessageFormat(pattern);
    906 
    907     // test with argument number being zero
    908     pattern = "A B C D E F";
    909     format3 = new MessageFormat(pattern);
    910   }
    911 
    912   protected void tearDown() {
    913     Locale.setDefault(defaultLocale);
    914   }
    915 
    916   public void test_ConstructorLjava_util_Locale() {
    917     // Regression for HARMONY-65
    918     try {
    919       new MessageFormat("{0,number,integer", Locale.US);
    920       fail("Assert 0: Failed to detect unmatched brackets.");
    921     } catch (IllegalArgumentException e) {
    922       // expected
    923     }
    924   }
    925 
    926   public void test_parse() throws ParseException {
    927     // Regression for HARMONY-63
    928     MessageFormat mf = new MessageFormat("{0,number,#,##}", Locale.US);
    929     Object[] res = mf.parse("1,00,00");
    930     assertEquals("Assert 0: incorrect size of parsed data ", 1, res.length);
    931     assertEquals("Assert 1: parsed value incorrectly", new Long(10000), (Long)res[0]);
    932   }
    933 
    934   public void test_format_Object() {
    935     // Regression for HARMONY-1875
    936     Locale.setDefault(Locale.CANADA);
    937     TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    938     String pat="text here {0, date, yyyyyyyyy } and here";
    939     String etalon="text here  000002007  and here";
    940     MessageFormat obj = new MessageFormat(pat);
    941     assertEquals(etalon, obj.format(new Object[]{new Date(1198141737640L)}));
    942 
    943     assertEquals("{0}", MessageFormat.format("{0}", (Object[]) null));
    944     assertEquals("nullABC", MessageFormat.format("{0}{1}", (Object[]) new String[]{null, "ABC"}));
    945   }
    946 
    947   public void testHARMONY5323() {
    948     Object[] messageArgs = new Object[11];
    949     for (int i = 0; i < messageArgs.length; i++) {
    950       messageArgs[i] = "example" + i;
    951     }
    952 
    953     String res = MessageFormat.format("bgcolor=\"{10}\"", messageArgs);
    954     assertEquals(res, "bgcolor=\"example10\"");
    955   }
    956 
    957   // http://b/19011159
    958   public void test19011159() {
    959     final String pattern = "ab{0,choice,0#1'2''3'''4''''.}yz";
    960     final MessageFormat format = new MessageFormat(pattern, Locale.ENGLISH);
    961     final Object[] zero0 = new Object[] { 0 };
    962     assertEquals("ab12'3'4''.yz", format.format(zero0));
    963   }
    964 }
    965