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     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}";
    188     MessageFormat mf = new MessageFormat(pattern);
    189     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";
    190     Object[] result = mf.parse(sToParse);
    191 
    192     assertTrue("No result: " + result.length, result.length == 5);
    193     assertTrue("Object 0 is not date", result[0] instanceof Date);
    194     assertEquals("Object 1 is not stringr", result[1].toString(), "1.0");
    195     assertTrue("Object 2 is not date", result[2] instanceof Date);
    196     assertEquals("Object 3 is not number", result[3].toString(), "12345");
    197     assertEquals("Object 4 is not string", result[4].toString(), "1/15/70 9:56 AM");
    198 
    199     sToParse = "xxdate is Feb 28, 1999";
    200     try {
    201       result = format1.parse(sToParse);
    202       fail();
    203     } catch (java.text.ParseException expected) {
    204     }
    205 
    206     sToParse = "vm=Test, @3 4 6, 3   ";
    207     mf = new MessageFormat("vm={0},{1},{2}");
    208     result = mf.parse(sToParse);
    209     assertTrue("No result: " + result.length, result.length == 3);
    210     assertEquals("Object 0 is not string", result[0].toString(), "Test");
    211     assertEquals("Object 1 is not string", result[1].toString(), " @3 4 6");
    212     assertEquals("Object 2 is not string", result[2].toString(), " 3   ");
    213 
    214     try {
    215       result = mf.parse(null);
    216       fail();
    217     } catch (java.text.ParseException expected) {
    218     }
    219   }
    220 
    221   public void test_setFormats$Ljava_text_Format() throws Exception {
    222     MessageFormat f1 = (MessageFormat) format1.clone();
    223 
    224     // case 1: Test with repeating formats and max argument index < max
    225     // offset
    226     // compare getFormats() results after calls to setFormats(Format[])
    227     Format[] correctFormats = new Format[] {
    228       DateFormat.getTimeInstance(),
    229       new ChoiceFormat("0#off|1#on"),
    230       DateFormat.getTimeInstance(),
    231       NumberFormat.getCurrencyInstance(),
    232       new ChoiceFormat("1#few|2#ok|3#a lot")
    233     };
    234 
    235     f1.setFormats(correctFormats);
    236     Format[] formats = f1.getFormats();
    237 
    238     assertTrue("Test1A:Returned wrong number of formats:", correctFormats.length <= formats.length);
    239     for (int i = 0; i < correctFormats.length; i++) {
    240       assertEquals("Test1B:wrong format for argument index " + i + ":", correctFormats[i], formats[i]);
    241     }
    242 
    243     // case 2: Try to pass null argument to setFormats().
    244     try {
    245       f1.setFormats(null);
    246       fail();
    247     } catch (NullPointerException expected) {
    248     }
    249   }
    250 
    251   public void test_formatLjava_lang_StringLjava_lang_Object() {
    252     TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    253     int iCurrency = 123;
    254     int iInteger  = Integer.MIN_VALUE;
    255 
    256     Date     date     = new Date(12345678);
    257     Object[] args     = { date, iCurrency, iInteger };
    258     String   resStr   = "Date: Jan 1, 1970 Currency: $" + iCurrency + ".00 Integer: -2,147,483,648";
    259     String   pattern  = "Date: {0,date} Currency: {1, number, currency} Integer: {2, number, integer}";
    260     String   sFormat  = MessageFormat.format(pattern, (Object[]) args);
    261     assertEquals(
    262         "format(String, Object[]) with valid parameters returns incorrect string: case 1",
    263         sFormat, resStr);
    264 
    265     pattern = "abc {4, number, integer} def {3,date} ghi {2,number} jkl {1,choice,0#low|1#high} mnop {0}";
    266     resStr  = "abc -2,147,483,648 def Jan 1, 1970 ghi -2,147,483,648 jkl high mnop -2,147,483,648";
    267     Object[] args_ = { iInteger, 1, iInteger, date, iInteger };
    268     sFormat = MessageFormat.format(pattern, args_);
    269     assertEquals(
    270         "format(String, Object[]) with valid parameters returns incorrect string: case 1",
    271         sFormat, resStr);
    272 
    273     try {
    274       args = null;
    275       MessageFormat.format(null, args);
    276       fail();
    277     } catch (Exception expected) {
    278     }
    279 
    280     try {
    281       MessageFormat.format("Invalid {1,foobar} format descriptor!", new Object[] {iInteger} );
    282       fail();
    283     } catch (IllegalArgumentException expected) {
    284     }
    285 
    286     try {
    287       MessageFormat.format("Invalid {1,date,invalid-spec} format descriptor!", new Object[]{""});
    288       fail();
    289     } catch (IllegalArgumentException expected) {
    290     }
    291 
    292     try {
    293       MessageFormat.format("{0,number,integer", new Object[] {iInteger});
    294       fail();
    295     } catch (IllegalArgumentException expected) {
    296     }
    297 
    298     try {
    299       MessageFormat.format("Valid {1, date} format {0, number} descriptor!", new Object[]{ "" } );
    300       fail();
    301     } catch (IllegalArgumentException expected) {
    302     }
    303   }
    304 
    305   public void test_ConstructorLjava_lang_StringLjava_util_Locale() {
    306     Locale mk = new Locale("mk", "MK");
    307     MessageFormat format = new MessageFormat("Date: {0,date} Currency: {1, number, currency} Integer: {2, number, integer}", mk);
    308     assertEquals(format.getLocale(), mk);
    309     assertEquals(format.getFormats()[0], DateFormat.getDateInstance(DateFormat.DEFAULT, mk));
    310     assertEquals(format.getFormats()[1], NumberFormat.getCurrencyInstance(mk));
    311     assertEquals(format.getFormats()[2], NumberFormat.getIntegerInstance(mk));
    312   }
    313 
    314   public void test_ConstructorLjava_lang_String() {
    315     MessageFormat format = new MessageFormat(
    316         "abc {4,time} def {3,date} ghi {2,number} jkl {1,choice,0#low|1#high} mnop {0}");
    317     assertTrue("Not a MessageFormat",
    318                format.getClass() == MessageFormat.class);
    319     Format[] formats = format.getFormats();
    320     assertNotNull("null formats", formats);
    321     assertTrue("Wrong format count: " + formats.length, formats.length >= 5);
    322     assertTrue("Wrong time format", formats[0].equals(DateFormat
    323                                                           .getTimeInstance()));
    324     assertTrue("Wrong date format", formats[1].equals(DateFormat
    325                                                           .getDateInstance()));
    326     assertTrue("Wrong number format", formats[2].equals(NumberFormat
    327                                                             .getInstance()));
    328     assertTrue("Wrong choice format", formats[3].equals(new ChoiceFormat(
    329                                                             "0.0#low|1.0#high")));
    330     assertNull("Wrong string format", formats[4]);
    331 
    332     Date date = new Date();
    333     FieldPosition pos = new FieldPosition(-1);
    334     StringBuffer buffer = new StringBuffer();
    335     format.format(new Object[] { "123", new Double(1.6), new Double(7.2),
    336         date, date }, buffer, pos);
    337     String result = buffer.toString();
    338     buffer.setLength(0);
    339     buffer.append("abc ");
    340     buffer.append(DateFormat.getTimeInstance().format(date));
    341     buffer.append(" def ");
    342     buffer.append(DateFormat.getDateInstance().format(date));
    343     buffer.append(" ghi ");
    344     buffer.append(NumberFormat.getInstance().format(new Double(7.2)));
    345     buffer.append(" jkl high mnop 123");
    346     assertTrue("Wrong answer:\n" + result + "\n" + buffer, result
    347                    .equals(buffer.toString()));
    348 
    349     assertEquals("Simple string", "Test message", new MessageFormat("Test message").format(
    350         new Object[0]));
    351 
    352     result = new MessageFormat("Don't").format(new Object[0]);
    353     assertTrue("Should not throw IllegalArgumentException: " + result,
    354                "Dont".equals(result));
    355 
    356     try {
    357       new MessageFormat("Invalid {1,foobar} format descriptor!");
    358       fail("Expected test_ConstructorLjava_lang_String to throw IAE.");
    359     } catch (IllegalArgumentException ex) {
    360       // expected
    361     }
    362 
    363     try {
    364       new MessageFormat(
    365           "Invalid {1,date,invalid-spec} format descriptor!");
    366     } catch (IllegalArgumentException ex) {
    367       // expected
    368     }
    369 
    370     checkSerialization(new MessageFormat(""));
    371     checkSerialization(new MessageFormat("noargs"));
    372     checkSerialization(new MessageFormat("{0}"));
    373     checkSerialization(new MessageFormat("a{0}"));
    374     checkSerialization(new MessageFormat("{0}b"));
    375     checkSerialization(new MessageFormat("a{0}b"));
    376 
    377     // Regression for HARMONY-65
    378     try {
    379       new MessageFormat("{0,number,integer");
    380       fail("Assert 0: Failed to detect unmatched brackets.");
    381     } catch (IllegalArgumentException e) {
    382       // expected
    383     }
    384   }
    385 
    386     public void test_applyPatternLjava_lang_String() {
    387         MessageFormat format = new MessageFormat("test");
    388         format.applyPattern("xx {0}");
    389 		assertEquals("Invalid number", "xx 46", format.format(
    390 				new Object[] { new Integer(46) }));
    391         Date date = new Date();
    392         String result = format.format(new Object[] { date });
    393         String expected = "xx " + DateFormat.getInstance().format(date);
    394         assertTrue("Invalid date:\n" + result + "\n" + expected, result
    395                 .equals(expected));
    396         format = new MessageFormat("{0,date}{1,time}{2,number,integer}");
    397         format.applyPattern("nothing");
    398 		assertEquals("Found formats", "nothing", format.toPattern());
    399 
    400         format.applyPattern("{0}");
    401 		assertNull("Wrong format", format.getFormats()[0]);
    402 		assertEquals("Wrong pattern", "{0}", format.toPattern());
    403 
    404         format.applyPattern("{0, \t\u001ftime }");
    405         assertTrue("Wrong time format", format.getFormats()[0]
    406                 .equals(DateFormat.getTimeInstance()));
    407 		assertEquals("Wrong time pattern", "{0,time}", format.toPattern());
    408         format.applyPattern("{0,Time, Short\n}");
    409         assertTrue("Wrong short time format", format.getFormats()[0]
    410                 .equals(DateFormat.getTimeInstance(DateFormat.SHORT)));
    411 		assertEquals("Wrong short time pattern",
    412 				"{0,time,short}", format.toPattern());
    413         format.applyPattern("{0,TIME,\nmedium  }");
    414         assertTrue("Wrong medium time format", format.getFormats()[0]
    415                 .equals(DateFormat.getTimeInstance(DateFormat.MEDIUM)));
    416 		assertEquals("Wrong medium time pattern",
    417 				"{0,time}", format.toPattern());
    418         format.applyPattern("{0,time,LONG}");
    419         assertTrue("Wrong long time format", format.getFormats()[0]
    420                 .equals(DateFormat.getTimeInstance(DateFormat.LONG)));
    421 		assertEquals("Wrong long time pattern",
    422 				"{0,time,long}", format.toPattern());
    423         format.setLocale(Locale.FRENCH); // use French since English has the
    424         // same LONG and FULL time patterns
    425         format.applyPattern("{0,time, Full}");
    426         assertTrue("Wrong full time format", format.getFormats()[0]
    427                 .equals(DateFormat.getTimeInstance(DateFormat.FULL,
    428                         Locale.FRENCH)));
    429 		assertEquals("Wrong full time pattern",
    430 				"{0,time,full}", format.toPattern());
    431         format.setLocale(Locale.getDefault());
    432 
    433         format.applyPattern("{0, date}");
    434         assertTrue("Wrong date format", format.getFormats()[0]
    435                 .equals(DateFormat.getDateInstance()));
    436 		assertEquals("Wrong date pattern", "{0,date}", format.toPattern());
    437         format.applyPattern("{0, date, short}");
    438         assertTrue("Wrong short date format", format.getFormats()[0]
    439                 .equals(DateFormat.getDateInstance(DateFormat.SHORT)));
    440 		assertEquals("Wrong short date pattern",
    441 				"{0,date,short}", format.toPattern());
    442         format.applyPattern("{0, date, medium}");
    443         assertTrue("Wrong medium date format", format.getFormats()[0]
    444                 .equals(DateFormat.getDateInstance(DateFormat.MEDIUM)));
    445 		assertEquals("Wrong medium date pattern",
    446 				"{0,date}", format.toPattern());
    447         format.applyPattern("{0, date, long}");
    448         assertTrue("Wrong long date format", format.getFormats()[0]
    449                 .equals(DateFormat.getDateInstance(DateFormat.LONG)));
    450 		assertEquals("Wrong long date pattern",
    451 				"{0,date,long}", format.toPattern());
    452         format.applyPattern("{0, date, full}");
    453         assertTrue("Wrong full date format", format.getFormats()[0]
    454                 .equals(DateFormat.getDateInstance(DateFormat.FULL)));
    455 		assertEquals("Wrong full date pattern",
    456 				"{0,date,full}", format.toPattern());
    457 
    458         format.applyPattern("{0, date, MMM d {hh:mm:ss}}");
    459 		assertEquals("Wrong time/date format", " MMM d {hh:mm:ss}", ((SimpleDateFormat) (format
    460 				.getFormats()[0])).toPattern());
    461 		assertEquals("Wrong time/date pattern",
    462 				"{0,date, MMM d {hh:mm:ss}}", format.toPattern());
    463 
    464         format.applyPattern("{0, number}");
    465         assertTrue("Wrong number format", format.getFormats()[0]
    466                 .equals(NumberFormat.getNumberInstance()));
    467 		assertEquals("Wrong number pattern",
    468 				"{0,number}", format.toPattern());
    469         format.applyPattern("{0, number, currency}");
    470         assertTrue("Wrong currency number format", format.getFormats()[0]
    471                 .equals(NumberFormat.getCurrencyInstance()));
    472 		assertEquals("Wrong currency number pattern",
    473 				"{0,number,currency}", format.toPattern());
    474         format.applyPattern("{0, number, percent}");
    475         assertTrue("Wrong percent number format", format.getFormats()[0]
    476                 .equals(NumberFormat.getPercentInstance()));
    477 		assertEquals("Wrong percent number pattern",
    478 				"{0,number,percent}", format.toPattern());
    479         format.applyPattern("{0, number, integer}");
    480 
    481         DecimalFormat expectedNumberFormat = (DecimalFormat) NumberFormat.getIntegerInstance();
    482         DecimalFormat actualNumberFormat = (DecimalFormat) format.getFormats()[0];
    483         assertEquals(expectedNumberFormat.getDecimalFormatSymbols(), actualNumberFormat.getDecimalFormatSymbols());
    484         assertEquals(expectedNumberFormat.isParseIntegerOnly(), actualNumberFormat.isParseIntegerOnly());
    485         assertEquals("Wrong integer number pattern", "{0,number,integer}", format.toPattern());
    486         assertEquals(expectedNumberFormat, format.getFormats()[0]);
    487 
    488         format.applyPattern("{0, number, {'#'}##0.0E0}");
    489 
    490         /*
    491          * TODO validate these assertions
    492          * String actual = ((DecimalFormat)(format.getFormats()[0])).toPattern();
    493          * assertEquals("Wrong pattern number format", "' {#}'##0.0E0", actual);
    494          * assertEquals("Wrong pattern number pattern", "{0,number,' {#}'##0.0E0}", format.toPattern());
    495          *
    496          */
    497 
    498         format.applyPattern("{0, choice,0#no|1#one|2#{1,number}}");
    499 		assertEquals("Wrong choice format",
    500 
    501 						"0.0#no|1.0#one|2.0#{1,number}", ((ChoiceFormat) format.getFormats()[0]).toPattern());
    502 		assertEquals("Wrong choice pattern",
    503 				"{0,choice,0.0#no|1.0#one|2.0#{1,number}}", format.toPattern());
    504 		assertEquals("Wrong formatted choice", "3.6", format.format(
    505 				new Object[] { new Integer(2), new Float(3.6) }));
    506 
    507         try {
    508             format.applyPattern("WRONG MESSAGE FORMAT {0,number,{}");
    509             fail("Expected IllegalArgumentException for invalid pattern");
    510         } catch (IllegalArgumentException e) {
    511         }
    512 
    513         // Regression for HARMONY-65
    514         MessageFormat mf = new MessageFormat("{0,number,integer}");
    515         String badpattern = "{0,number,#";
    516         try {
    517             mf.applyPattern(badpattern);
    518             fail("Assert 0: Failed to detect unmatched brackets.");
    519         } catch (IllegalArgumentException e) {
    520             // expected
    521         }
    522     }
    523 
    524     public void test_clone() {
    525         MessageFormat format = new MessageFormat("'{'choice'}'{0}");
    526         MessageFormat clone = (MessageFormat) format.clone();
    527         assertTrue("Clone not equal", format.equals(clone));
    528 		assertEquals("Wrong answer",
    529 				"{choice}{0}", format.format(new Object[] {}));
    530         clone.setFormat(0, DateFormat.getInstance());
    531         assertTrue("Clone shares format data", !format.equals(clone));
    532         format = (MessageFormat) clone.clone();
    533         Format[] formats = clone.getFormats();
    534         ((SimpleDateFormat) formats[0]).applyPattern("adk123");
    535         assertTrue("Clone shares format data", !format.equals(clone));
    536     }
    537 
    538     public void test_equalsLjava_lang_Object() {
    539         MessageFormat format1 = new MessageFormat("{0}");
    540         MessageFormat format2 = new MessageFormat("{1}");
    541         assertTrue("Should not be equal", !format1.equals(format2));
    542         format2.applyPattern("{0}");
    543         assertTrue("Should be equal", format1.equals(format2));
    544         SimpleDateFormat date = (SimpleDateFormat) DateFormat.getTimeInstance();
    545         format1.setFormat(0, DateFormat.getTimeInstance());
    546         format2.setFormat(0, new SimpleDateFormat(date.toPattern()));
    547         assertTrue("Should be equal2", format1.equals(format2));
    548     }
    549 
    550   public void test_hashCode() {
    551       assertEquals("Should be equal", 3648, new MessageFormat("rr", null).hashCode());
    552   }
    553 
    554   public void test_format$Ljava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition() {
    555     MessageFormat format = new MessageFormat("{1,number,integer}");
    556     StringBuffer buffer = new StringBuffer();
    557     format.format(new Object[] { "0", new Double(53.863) }, buffer,
    558                   new FieldPosition(0));
    559     assertEquals("Wrong result", "54", buffer.toString());
    560 
    561     format.format(new Object[] { "0", new Double(53.863) }, buffer,
    562                   new FieldPosition(MessageFormat.Field.ARGUMENT));
    563     assertEquals("Wrong result", "5454", buffer.toString());
    564 
    565     buffer = new StringBuffer();
    566     format.applyPattern("{0,choice,0#zero|1#one '{1,choice,2#two {2,time}}'}");
    567     Date date = new Date();
    568     String expectedText = "one two " + DateFormat.getTimeInstance().format(date);
    569     format.format(new Object[] { new Double(1.6), new Integer(3), date }, buffer, new FieldPosition(MessageFormat.Field.ARGUMENT));
    570     assertEquals("Choice not recursive:\n" + expectedText + "\n" + buffer, expectedText, buffer.toString());
    571 
    572     StringBuffer str = format.format(new Object[] { new Double(0.6),
    573         new Integer(3)}, buffer, null);
    574     assertEquals(expectedText + "zero", str.toString());
    575     assertEquals(expectedText + "zero", buffer.toString());
    576 
    577     try {
    578       format.format(new Object[] { "0", new Double(1), "" }, buffer,
    579                     new FieldPosition(MessageFormat.Field.ARGUMENT));
    580       fail();
    581     } catch (IllegalArgumentException expected) {
    582     }
    583 
    584     try {
    585       format.format(new Object[] { "",  new Integer(3)}, buffer,
    586                     new FieldPosition(MessageFormat.Field.ARGUMENT));
    587       fail();
    588     } catch (IllegalArgumentException expected) {
    589     }
    590   }
    591 
    592   public void test_formatLjava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition() {
    593     new Support_MessageFormat(
    594         "test_formatLjava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition")
    595         .t_format_with_FieldPosition();
    596 
    597     String pattern = "On {4,date} at {3,time}, he ate {2,number, integer} hamburger{2,choice,1#|1<s}.";
    598     MessageFormat format = new MessageFormat(pattern, Locale.US);
    599     Object[] objects = new Object[] { "", new Integer(3), 8, ""};
    600     try {
    601       format.format(objects, new StringBuffer(), new FieldPosition(DateFormat.Field.AM_PM));
    602       fail();
    603     } catch (IllegalArgumentException expected) {
    604     }
    605   }
    606 
    607   public void test_getFormats() {
    608     // test with repeating formats and max argument index < max offset
    609     Format[] formats = format1.getFormats();
    610     Format[] correctFormats = new Format[] {
    611       NumberFormat.getCurrencyInstance(),
    612       DateFormat.getTimeInstance(),
    613       NumberFormat.getPercentInstance(), null,
    614       new ChoiceFormat("0#off|1#on"), DateFormat.getDateInstance(), };
    615 
    616     assertEquals("Test1:Returned wrong number of formats:",
    617                  correctFormats.length, formats.length);
    618     for (int i = 0; i < correctFormats.length; i++) {
    619       assertEquals("Test1:wrong format for pattern index " + i + ":",
    620                    correctFormats[i], formats[i]);
    621     }
    622 
    623     // test with max argument index > max offset
    624     formats = format2.getFormats();
    625     correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
    626         DateFormat.getTimeInstance(),
    627         NumberFormat.getPercentInstance(), null,
    628         new ChoiceFormat("0#off|1#on"), DateFormat.getDateInstance() };
    629 
    630     assertEquals("Test2:Returned wrong number of formats:",
    631                  correctFormats.length, formats.length);
    632     for (int i = 0; i < correctFormats.length; i++) {
    633       assertEquals("Test2:wrong format for pattern index " + i + ":",
    634                    correctFormats[i], formats[i]);
    635     }
    636 
    637     // test with argument number being zero
    638     formats = format3.getFormats();
    639     assertEquals("Test3: Returned wrong number of formats:", 0,
    640                  formats.length);
    641   }
    642 
    643     public void test_getFormatsByArgumentIndex() {
    644         // test with repeating formats and max argument index < max offset
    645         Format[] formats = format1.getFormatsByArgumentIndex();
    646         Format[] correctFormats = new Format[] { DateFormat.getDateInstance(),
    647                 new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(),
    648                 NumberFormat.getCurrencyInstance(), null };
    649 
    650         assertEquals("Test1:Returned wrong number of formats:",
    651                 correctFormats.length, formats.length);
    652         for (int i = 0; i < correctFormats.length; i++) {
    653             assertEquals("Test1:wrong format for argument index " + i + ":",
    654                     correctFormats[i], formats[i]);
    655         }
    656 
    657         // test with max argument index > max offset
    658         formats = format2.getFormatsByArgumentIndex();
    659         correctFormats = new Format[] { DateFormat.getDateInstance(),
    660                 new ChoiceFormat("0#off|1#on"), null,
    661                 NumberFormat.getCurrencyInstance(), null, null, null, null,
    662                 DateFormat.getTimeInstance() };
    663 
    664         assertEquals("Test2:Returned wrong number of formats:",
    665                 correctFormats.length, formats.length);
    666         for (int i = 0; i < correctFormats.length; i++) {
    667             assertEquals("Test2:wrong format for argument index " + i + ":",
    668                     correctFormats[i], formats[i]);
    669         }
    670 
    671         // test with argument number being zero
    672         formats = format3.getFormatsByArgumentIndex();
    673         assertEquals("Test3: Returned wrong number of formats:", 0,
    674                 formats.length);
    675     }
    676 
    677     public void test_setFormatByArgumentIndexILjava_text_Format() {
    678         // test for method setFormatByArgumentIndex(int, Format)
    679         MessageFormat f1 = (MessageFormat) format1.clone();
    680         f1.setFormatByArgumentIndex(0, DateFormat.getTimeInstance());
    681         f1.setFormatByArgumentIndex(4, new ChoiceFormat("1#few|2#ok|3#a lot"));
    682 
    683         // test with repeating formats and max argument index < max offset
    684         // compare getFormatsByArgumentIndex() results after calls to
    685         // setFormatByArgumentIndex()
    686         Format[] formats = f1.getFormatsByArgumentIndex();
    687 
    688         Format[] correctFormats = new Format[] { DateFormat.getTimeInstance(),
    689                 new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(),
    690                 NumberFormat.getCurrencyInstance(),
    691                 new ChoiceFormat("1#few|2#ok|3#a lot") };
    692 
    693         assertEquals("Test1A:Returned wrong number of formats:",
    694                 correctFormats.length, formats.length);
    695         for (int i = 0; i < correctFormats.length; i++) {
    696             assertEquals("Test1B:wrong format for argument index " + i + ":",
    697                     correctFormats[i], formats[i]);
    698         }
    699 
    700         // compare getFormats() results after calls to
    701         // setFormatByArgumentIndex()
    702         formats = f1.getFormats();
    703 
    704         correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
    705                 DateFormat.getTimeInstance(), DateFormat.getTimeInstance(),
    706                 new ChoiceFormat("1#few|2#ok|3#a lot"),
    707                 new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(), };
    708 
    709         assertEquals("Test1C:Returned wrong number of formats:",
    710                 correctFormats.length, formats.length);
    711         for (int i = 0; i < correctFormats.length; i++) {
    712             assertEquals("Test1D:wrong format for pattern index " + i + ":",
    713                     correctFormats[i], formats[i]);
    714         }
    715 
    716         // test setting argumentIndexes that are not used
    717         MessageFormat f2 = (MessageFormat) format2.clone();
    718         f2.setFormatByArgumentIndex(2, NumberFormat.getPercentInstance());
    719         f2.setFormatByArgumentIndex(4, DateFormat.getTimeInstance());
    720 
    721         formats = f2.getFormatsByArgumentIndex();
    722         correctFormats = format2.getFormatsByArgumentIndex();
    723 
    724         assertEquals("Test2A:Returned wrong number of formats:",
    725                 correctFormats.length, formats.length);
    726         for (int i = 0; i < correctFormats.length; i++) {
    727             assertEquals("Test2B:wrong format for argument index " + i + ":",
    728                     correctFormats[i], formats[i]);
    729         }
    730 
    731         formats = f2.getFormats();
    732         correctFormats = format2.getFormats();
    733 
    734         assertEquals("Test2C:Returned wrong number of formats:",
    735                 correctFormats.length, formats.length);
    736         for (int i = 0; i < correctFormats.length; i++) {
    737             assertEquals("Test2D:wrong format for pattern index " + i + ":",
    738                     correctFormats[i], formats[i]);
    739         }
    740 
    741         // test exceeding the argumentIndex number
    742         MessageFormat f3 = (MessageFormat) format3.clone();
    743         f3.setFormatByArgumentIndex(1, NumberFormat.getCurrencyInstance());
    744 
    745         formats = f3.getFormatsByArgumentIndex();
    746         assertEquals("Test3A:Returned wrong number of formats:", 0,
    747                 formats.length);
    748 
    749         formats = f3.getFormats();
    750         assertEquals("Test3B:Returned wrong number of formats:", 0,
    751                 formats.length);
    752     }
    753 
    754     public void test_setFormatsByArgumentIndex$Ljava_text_Format() {
    755         MessageFormat f1 = (MessageFormat) format1.clone();
    756 
    757         // test with repeating formats and max argument index < max offset
    758         // compare getFormatsByArgumentIndex() results after calls to
    759         // setFormatsByArgumentIndex(Format[])
    760         Format[] correctFormats = new Format[] { DateFormat.getTimeInstance(),
    761                 new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(),
    762                 NumberFormat.getCurrencyInstance(),
    763                 new ChoiceFormat("1#few|2#ok|3#a lot") };
    764 
    765         f1.setFormatsByArgumentIndex(correctFormats);
    766         Format[] formats = f1.getFormatsByArgumentIndex();
    767 
    768         assertEquals("Test1A:Returned wrong number of formats:",
    769                 correctFormats.length, formats.length);
    770         for (int i = 0; i < correctFormats.length; i++) {
    771             assertEquals("Test1B:wrong format for argument index " + i + ":",
    772                     correctFormats[i], formats[i]);
    773         }
    774 
    775         // compare getFormats() results after calls to
    776         // setFormatByArgumentIndex()
    777         formats = f1.getFormats();
    778         correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
    779                 DateFormat.getTimeInstance(), DateFormat.getTimeInstance(),
    780                 new ChoiceFormat("1#few|2#ok|3#a lot"),
    781                 new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(), };
    782 
    783         assertEquals("Test1C:Returned wrong number of formats:",
    784                 correctFormats.length, formats.length);
    785         for (int i = 0; i < correctFormats.length; i++) {
    786             assertEquals("Test1D:wrong format for pattern index " + i + ":",
    787                     correctFormats[i], formats[i]);
    788         }
    789 
    790         // test setting argumentIndexes that are not used
    791         MessageFormat f2 = (MessageFormat) format2.clone();
    792         Format[] inputFormats = new Format[] { DateFormat.getDateInstance(),
    793                 new ChoiceFormat("0#off|1#on"),
    794                 NumberFormat.getPercentInstance(),
    795                 NumberFormat.getCurrencyInstance(),
    796                 DateFormat.getTimeInstance(), null, null, null,
    797                 DateFormat.getTimeInstance() };
    798         f2.setFormatsByArgumentIndex(inputFormats);
    799 
    800         formats = f2.getFormatsByArgumentIndex();
    801         correctFormats = format2.getFormatsByArgumentIndex();
    802 
    803         assertEquals("Test2A:Returned wrong number of formats:",
    804                 correctFormats.length, formats.length);
    805         for (int i = 0; i < correctFormats.length; i++) {
    806             assertEquals("Test2B:wrong format for argument index " + i + ":",
    807                     correctFormats[i], formats[i]);
    808         }
    809 
    810         formats = f2.getFormats();
    811         correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
    812                 DateFormat.getTimeInstance(), DateFormat.getDateInstance(),
    813                 null, new ChoiceFormat("0#off|1#on"),
    814                 DateFormat.getDateInstance() };
    815 
    816         assertEquals("Test2C:Returned wrong number of formats:",
    817                 correctFormats.length, formats.length);
    818         for (int i = 0; i < correctFormats.length; i++) {
    819             assertEquals("Test2D:wrong format for pattern index " + i + ":",
    820                     correctFormats[i], formats[i]);
    821         }
    822 
    823         // test exceeding the argumentIndex number
    824         MessageFormat f3 = (MessageFormat) format3.clone();
    825         f3.setFormatsByArgumentIndex(inputFormats);
    826 
    827         formats = f3.getFormatsByArgumentIndex();
    828         assertEquals("Test3A:Returned wrong number of formats:", 0,
    829                 formats.length);
    830 
    831         formats = f3.getFormats();
    832         assertEquals("Test3B:Returned wrong number of formats:", 0,
    833                 formats.length);
    834 
    835     }
    836 
    837     public void test_parseLjava_lang_StringLjava_text_ParsePosition() {
    838         MessageFormat format = new MessageFormat("date is {0,date,MMM d, yyyy}");
    839         ParsePosition pos = new ParsePosition(2);
    840         Object[] result = (Object[]) format
    841                 .parse("xxdate is Feb 28, 1999", pos);
    842         assertTrue("No result: " + result.length, result.length >= 1);
    843         assertTrue("Wrong answer", ((Date) result[0])
    844                 .equals(new GregorianCalendar(1999, Calendar.FEBRUARY, 28)
    845                         .getTime()));
    846 
    847         MessageFormat mf = new MessageFormat("vm={0},{1},{2}");
    848         result = mf.parse("vm=win,foo,bar", new ParsePosition(0));
    849         assertTrue("Invalid parse", result[0].equals("win")
    850                 && result[1].equals("foo") && result[2].equals("bar"));
    851 
    852         mf = new MessageFormat("{0}; {0}; {0}");
    853         String parse = "a; b; c";
    854         result = mf.parse(parse, new ParsePosition(0));
    855         assertEquals("Wrong variable result", "c", result[0]);
    856 
    857         mf = new MessageFormat("before {0}, after {1,number}");
    858         parse = "before you, after 42";
    859         pos.setIndex(0);
    860         pos.setErrorIndex(8);
    861         result = mf.parse(parse, pos);
    862         assertEquals(2, result.length);
    863 
    864         try {
    865             mf.parse(parse, null);
    866             fail();
    867         } catch (NullPointerException expected) {
    868         }
    869 
    870         // This should _not_ throw.
    871         mf.parse(null, pos);
    872     }
    873 
    874   public void test_setLocaleLjava_util_Locale() {
    875     MessageFormat format = new MessageFormat("date {0,date}");
    876     format.setLocale(Locale.CHINA);
    877     assertEquals("Wrong locale1", Locale.CHINA, format.getLocale());
    878     format.applyPattern("{1,date}");
    879     assertEquals("Wrong locale3", DateFormat.getDateInstance(DateFormat.DEFAULT,
    880                                                              Locale.CHINA), format.getFormats()[0]);
    881   }
    882 
    883   public void test_toPattern() {
    884     String pattern = "[{0}]";
    885     MessageFormat mf = new MessageFormat(pattern);
    886     assertTrue("Wrong pattern", mf.toPattern().equals(pattern));
    887 
    888     // Regression for HARMONY-59
    889     new MessageFormat("CHOICE {1,choice}").toPattern();
    890   }
    891 
    892   protected void setUp() {
    893     defaultLocale = Locale.getDefault();
    894     Locale.setDefault(Locale.US);
    895 
    896     // test with repeating formats and max argument index < max offset
    897     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}";
    898     format1 = new MessageFormat(pattern);
    899 
    900     // test with max argument index > max offset
    901     pattern = "A {3, number, currency} B {8, time} C {0, number, percent} D {6}  E {1,choice,0#off|1#on} F {0, date}";
    902     format2 = new MessageFormat(pattern);
    903 
    904     // test with argument number being zero
    905     pattern = "A B C D E F";
    906     format3 = new MessageFormat(pattern);
    907   }
    908 
    909   protected void tearDown() {
    910     Locale.setDefault(defaultLocale);
    911   }
    912 
    913   public void test_ConstructorLjava_util_Locale() {
    914     // Regression for HARMONY-65
    915     try {
    916       new MessageFormat("{0,number,integer", Locale.US);
    917       fail("Assert 0: Failed to detect unmatched brackets.");
    918     } catch (IllegalArgumentException e) {
    919       // expected
    920     }
    921   }
    922 
    923   public void test_parse() throws ParseException {
    924     // Regression for HARMONY-63
    925     MessageFormat mf = new MessageFormat("{0,number,#,##}", Locale.US);
    926     Object[] res = mf.parse("1,00,00");
    927     assertEquals("Assert 0: incorrect size of parsed data ", 1, res.length);
    928     assertEquals("Assert 1: parsed value incorrectly", new Long(10000), (Long)res[0]);
    929   }
    930 
    931   public void test_format_Object() {
    932     // Regression for HARMONY-1875
    933     Locale.setDefault(Locale.CANADA);
    934     TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    935     String pat="text here {0, date, yyyyyyyyy } and here";
    936     String etalon="text here  000002007  and here";
    937     MessageFormat obj = new MessageFormat(pat);
    938     assertEquals(etalon, obj.format(new Object[]{new Date(1198141737640L)}));
    939 
    940     assertEquals("{0}", MessageFormat.format("{0}", (Object[]) null));
    941     assertEquals("nullABC", MessageFormat.format("{0}{1}", (Object[]) new String[]{null, "ABC"}));
    942   }
    943 
    944   public void testHARMONY5323() {
    945     Object[] messageArgs = new Object[11];
    946     for (int i = 0; i < messageArgs.length; i++) {
    947       messageArgs[i] = "example" + i;
    948     }
    949 
    950     String res = MessageFormat.format("bgcolor=\"{10}\"", messageArgs);
    951     assertEquals(res, "bgcolor=\"example10\"");
    952   }
    953 }
    954