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
18package org.apache.harmony.text.tests.java.text;
19
20import java.io.ByteArrayInputStream;
21import java.io.ByteArrayOutputStream;
22import java.io.IOException;
23import java.io.ObjectInputStream;
24import java.io.ObjectOutputStream;
25import java.text.ChoiceFormat;
26import java.text.DateFormat;
27import java.text.FieldPosition;
28import java.text.Format;
29import java.text.MessageFormat;
30import java.text.NumberFormat;
31import java.text.ParseException;
32import java.text.ParsePosition;
33import java.text.SimpleDateFormat;
34import java.util.Calendar;
35import java.util.Date;
36import java.util.GregorianCalendar;
37import java.util.Locale;
38import java.util.TimeZone;
39
40import junit.framework.TestCase;
41
42public class MessageFormatTest extends TestCase {
43
44    private MessageFormat format1, format2, format3;
45
46    private Locale defaultLocale;
47
48    private void checkSerialization(MessageFormat format) {
49        try {
50            ByteArrayOutputStream ba = new ByteArrayOutputStream();
51            ObjectOutputStream out = new ObjectOutputStream(ba);
52            out.writeObject(format);
53            out.close();
54            ObjectInputStream in = new ObjectInputStream(
55                    new ByteArrayInputStream(ba.toByteArray()));
56            MessageFormat read = (MessageFormat) in.readObject();
57            assertTrue("Not equal: " + format.toPattern(), format.equals(read));
58        } catch (IOException e) {
59            fail("Format: " + format.toPattern()
60                    + " caused IOException: " + e);
61        } catch (ClassNotFoundException e) {
62            fail("Format: " + format.toPattern()
63                    + " caused ClassNotFoundException: " + e);
64        }
65    }
66
67    /**
68     * @tests java.text.MessageFormat#MessageFormat(java.lang.String,
69     *        java.util.Locale)
70     */
71    public void test_ConstructorLjava_lang_StringLjava_util_Locale() {
72        // Test for method java.text.MessageFormat(java.lang.String,
73        // java.util.Locale)
74        Locale mk = new Locale("mk", "MK");
75        MessageFormat format = new MessageFormat(
76                "Date: {0,date} Currency: {1, number, currency} Integer: {2, number, integer}",
77                mk);
78
79        assertTrue("Wrong locale1", format.getLocale().equals(mk));
80        assertTrue("Wrong locale2", format.getFormats()[0].equals(DateFormat
81                .getDateInstance(DateFormat.DEFAULT, mk)));
82        assertTrue("Wrong locale3", format.getFormats()[1].equals(NumberFormat
83                .getCurrencyInstance(mk)));
84        assertTrue("Wrong locale4", format.getFormats()[2].equals(NumberFormat
85                .getIntegerInstance(mk)));
86    }
87
88    /**
89     * @tests java.text.MessageFormat#MessageFormat(java.lang.String)
90     */
91    public void test_ConstructorLjava_lang_String() {
92        // Test for method java.text.MessageFormat(java.lang.String)
93        MessageFormat format = new MessageFormat(
94                "abc {4,time} def {3,date} ghi {2,number} jkl {1,choice,0#low|1#high} mnop {0}");
95        assertTrue("Not a MessageFormat",
96                format.getClass() == MessageFormat.class);
97        Format[] formats = format.getFormats();
98		assertNotNull("null formats", formats);
99        assertTrue("Wrong format count: " + formats.length, formats.length >= 5);
100        assertTrue("Wrong time format", formats[0].equals(DateFormat
101                .getTimeInstance()));
102        assertTrue("Wrong date format", formats[1].equals(DateFormat
103                .getDateInstance()));
104        assertTrue("Wrong number format", formats[2].equals(NumberFormat
105                .getInstance()));
106        assertTrue("Wrong choice format", formats[3].equals(new ChoiceFormat(
107                "0.0#low|1.0#high")));
108		assertNull("Wrong string format", formats[4]);
109
110        Date date = new Date();
111        FieldPosition pos = new FieldPosition(-1);
112        StringBuffer buffer = new StringBuffer();
113        format.format(new Object[] { "123", new Double(1.6), new Double(7.2),
114                date, date }, buffer, pos);
115        String result = buffer.toString();
116        buffer.setLength(0);
117        buffer.append("abc ");
118        buffer.append(DateFormat.getTimeInstance().format(date));
119        buffer.append(" def ");
120        buffer.append(DateFormat.getDateInstance().format(date));
121        buffer.append(" ghi ");
122        buffer.append(NumberFormat.getInstance().format(new Double(7.2)));
123        buffer.append(" jkl high mnop 123");
124        assertTrue("Wrong answer:\n" + result + "\n" + buffer, result
125                .equals(buffer.toString()));
126
127		assertEquals("Simple string", "Test message", new MessageFormat("Test message").format(
128				new Object[0]));
129
130        result = new MessageFormat("Don't").format(new Object[0]);
131        assertTrue("Should not throw IllegalArgumentException: " + result,
132                    "Dont".equals(result));
133
134        try {
135            new MessageFormat("Invalid {1,foobar} format descriptor!");
136            fail("Expected test_ConstructorLjava_lang_String to throw IAE.");
137        } catch (IllegalArgumentException ex) {
138            // expected
139        }
140
141        try {
142            new MessageFormat(
143                    "Invalid {1,date,invalid-spec} format descriptor!");
144        } catch (IllegalArgumentException ex) {
145            // expected
146        }
147
148        checkSerialization(new MessageFormat(""));
149        checkSerialization(new MessageFormat("noargs"));
150        checkSerialization(new MessageFormat("{0}"));
151        checkSerialization(new MessageFormat("a{0}"));
152        checkSerialization(new MessageFormat("{0}b"));
153        checkSerialization(new MessageFormat("a{0}b"));
154
155        // Regression for HARMONY-65
156        try {
157            new MessageFormat("{0,number,integer");
158            fail("Assert 0: Failed to detect unmatched brackets.");
159        } catch (IllegalArgumentException e) {
160            // expected
161        }
162    }
163
164    /**
165     * @tests java.text.MessageFormat#applyPattern(java.lang.String)
166     */
167    public void test_applyPatternLjava_lang_String() {
168        // Test for method void
169        // java.text.MessageFormat.applyPattern(java.lang.String)
170        MessageFormat format = new MessageFormat("test");
171        format.applyPattern("xx {0}");
172		assertEquals("Invalid number", "xx 46", format.format(
173				new Object[] { new Integer(46) }));
174        Date date = new Date();
175        String result = format.format(new Object[] { date });
176        String expected = "xx " + DateFormat.getInstance().format(date);
177        assertTrue("Invalid date:\n" + result + "\n" + expected, result
178                .equals(expected));
179        format = new MessageFormat("{0,date}{1,time}{2,number,integer}");
180        format.applyPattern("nothing");
181		assertEquals("Found formats", "nothing", format.toPattern());
182
183        format.applyPattern("{0}");
184		assertNull("Wrong format", format.getFormats()[0]);
185		assertEquals("Wrong pattern", "{0}", format.toPattern());
186
187        format.applyPattern("{0, \t\u001ftime }");
188        assertTrue("Wrong time format", format.getFormats()[0]
189                .equals(DateFormat.getTimeInstance()));
190		assertEquals("Wrong time pattern", "{0,time}", format.toPattern());
191        format.applyPattern("{0,Time, Short\n}");
192        assertTrue("Wrong short time format", format.getFormats()[0]
193                .equals(DateFormat.getTimeInstance(DateFormat.SHORT)));
194		assertEquals("Wrong short time pattern",
195				"{0,time,short}", format.toPattern());
196        format.applyPattern("{0,TIME,\nmedium  }");
197        assertTrue("Wrong medium time format", format.getFormats()[0]
198                .equals(DateFormat.getTimeInstance(DateFormat.MEDIUM)));
199		assertEquals("Wrong medium time pattern",
200				"{0,time}", format.toPattern());
201        format.applyPattern("{0,time,LONG}");
202        assertTrue("Wrong long time format", format.getFormats()[0]
203                .equals(DateFormat.getTimeInstance(DateFormat.LONG)));
204		assertEquals("Wrong long time pattern",
205				"{0,time,long}", format.toPattern());
206        format.setLocale(Locale.FRENCH); // use French since English has the
207        // same LONG and FULL time patterns
208        format.applyPattern("{0,time, Full}");
209        assertTrue("Wrong full time format", format.getFormats()[0]
210                .equals(DateFormat.getTimeInstance(DateFormat.FULL,
211                        Locale.FRENCH)));
212		assertEquals("Wrong full time pattern",
213				"{0,time,full}", format.toPattern());
214        format.setLocale(Locale.getDefault());
215
216        format.applyPattern("{0, date}");
217        assertTrue("Wrong date format", format.getFormats()[0]
218                .equals(DateFormat.getDateInstance()));
219		assertEquals("Wrong date pattern", "{0,date}", format.toPattern());
220        format.applyPattern("{0, date, short}");
221        assertTrue("Wrong short date format", format.getFormats()[0]
222                .equals(DateFormat.getDateInstance(DateFormat.SHORT)));
223		assertEquals("Wrong short date pattern",
224				"{0,date,short}", format.toPattern());
225        format.applyPattern("{0, date, medium}");
226        assertTrue("Wrong medium date format", format.getFormats()[0]
227                .equals(DateFormat.getDateInstance(DateFormat.MEDIUM)));
228		assertEquals("Wrong medium date pattern",
229				"{0,date}", format.toPattern());
230        format.applyPattern("{0, date, long}");
231        assertTrue("Wrong long date format", format.getFormats()[0]
232                .equals(DateFormat.getDateInstance(DateFormat.LONG)));
233		assertEquals("Wrong long date pattern",
234				"{0,date,long}", format.toPattern());
235        format.applyPattern("{0, date, full}");
236        assertTrue("Wrong full date format", format.getFormats()[0]
237                .equals(DateFormat.getDateInstance(DateFormat.FULL)));
238		assertEquals("Wrong full date pattern",
239				"{0,date,full}", format.toPattern());
240
241        format.applyPattern("{0, date, MMM d {hh:mm:ss}}");
242		assertEquals("Wrong time/date format", " MMM d {hh:mm:ss}", ((SimpleDateFormat) (format
243				.getFormats()[0])).toPattern());
244		assertEquals("Wrong time/date pattern",
245				"{0,date, MMM d {hh:mm:ss}}", format.toPattern());
246
247        format.applyPattern("{0, number}");
248        assertTrue("Wrong number format", format.getFormats()[0]
249                .equals(NumberFormat.getNumberInstance()));
250		assertEquals("Wrong number pattern",
251				"{0,number}", format.toPattern());
252        format.applyPattern("{0, number, currency}");
253        assertTrue("Wrong currency number format", format.getFormats()[0]
254                .equals(NumberFormat.getCurrencyInstance()));
255		assertEquals("Wrong currency number pattern",
256				"{0,number,currency}", format.toPattern());
257        format.applyPattern("{0, number, percent}");
258        assertTrue("Wrong percent number format", format.getFormats()[0]
259                .equals(NumberFormat.getPercentInstance()));
260		assertEquals("Wrong percent number pattern",
261				"{0,number,percent}", format.toPattern());
262        format.applyPattern("{0, number, integer}");
263        NumberFormat nf = NumberFormat.getInstance();
264        nf.setMaximumFractionDigits(0);
265        nf.setParseIntegerOnly(true);
266        assertTrue("Wrong integer number format", format.getFormats()[0]
267                .equals(nf));
268		assertEquals("Wrong integer number pattern",
269				"{0,number,integer}", format.toPattern());
270
271        format.applyPattern("{0, number, {'#'}##0.0E0}");
272
273        /*
274         * TODO validate these assertions
275         * String actual = ((DecimalFormat)(format.getFormats()[0])).toPattern();
276         * assertEquals("Wrong pattern number format", "' {#}'##0.0E0", actual);
277         * assertEquals("Wrong pattern number pattern", "{0,number,' {#}'##0.0E0}", format.toPattern());
278         *
279         */
280
281        format.applyPattern("{0, choice,0#no|1#one|2#{1,number}}");
282		assertEquals("Wrong choice format",
283
284						"0.0#no|1.0#one|2.0#{1,number}", ((ChoiceFormat) format.getFormats()[0]).toPattern());
285		assertEquals("Wrong choice pattern",
286				"{0,choice,0.0#no|1.0#one|2.0#{1,number}}", format.toPattern());
287		assertEquals("Wrong formatted choice", "3.6", format.format(
288				new Object[] { new Integer(2), new Float(3.6) }));
289
290        try {
291            format.applyPattern("WRONG MESSAGE FORMAT {0,number,{}");
292            fail("Expected IllegalArgumentException for invalid pattern");
293        } catch (IllegalArgumentException e) {
294        }
295
296        // Regression for HARMONY-65
297        MessageFormat mf = new MessageFormat("{0,number,integer}");
298        String badpattern = "{0,number,#";
299        try {
300            mf.applyPattern(badpattern);
301            fail("Assert 0: Failed to detect unmatched brackets.");
302        } catch (IllegalArgumentException e) {
303            // expected
304        }
305    }
306
307    /**
308     * @tests java.text.MessageFormat#clone()
309     */
310    public void test_clone() {
311        // Test for method java.lang.Object java.text.MessageFormat.clone()
312        MessageFormat format = new MessageFormat("'{'choice'}'{0}");
313        MessageFormat clone = (MessageFormat) format.clone();
314        assertTrue("Clone not equal", format.equals(clone));
315		assertEquals("Wrong answer",
316				"{choice}{0}", format.format(new Object[] {}));
317        clone.setFormat(0, DateFormat.getInstance());
318        assertTrue("Clone shares format data", !format.equals(clone));
319        format = (MessageFormat) clone.clone();
320        Format[] formats = clone.getFormats();
321        ((SimpleDateFormat) formats[0]).applyPattern("adk123");
322        assertTrue("Clone shares format data", !format.equals(clone));
323    }
324
325    /**
326     * @tests java.text.MessageFormat#equals(java.lang.Object)
327     */
328    public void test_equalsLjava_lang_Object() {
329        // Test for method boolean
330        // java.text.MessageFormat.equals(java.lang.Object)
331        MessageFormat format1 = new MessageFormat("{0}");
332        MessageFormat format2 = new MessageFormat("{1}");
333        assertTrue("Should not be equal", !format1.equals(format2));
334        format2.applyPattern("{0}");
335        assertTrue("Should be equal", format1.equals(format2));
336        SimpleDateFormat date = (SimpleDateFormat) DateFormat.getTimeInstance();
337        format1.setFormat(0, DateFormat.getTimeInstance());
338        format2.setFormat(0, new SimpleDateFormat(date.toPattern()));
339        assertTrue("Should be equal2", format1.equals(format2));
340    }
341
342    /**
343     * @tests java.text.MessageFormat#hashCode()
344     */
345    public void test_hashCode() {
346        // Test for method
347        // int java.text.MessageFormat.hashCode()
348        assertEquals("Should be equal", 3648, new MessageFormat("rr", null).hashCode());
349    }
350
351    /**
352     * @tests java.text.MessageFormat#formatToCharacterIterator(java.lang.Object)
353     */
354    //FIXME This test fails on Harmony ClassLibrary
355    public void failing_test_formatToCharacterIteratorLjava_lang_Object() {
356        // Test for method formatToCharacterIterator(java.lang.Object)
357        new Support_MessageFormat("test_formatToCharacterIteratorLjava_lang_Object").t_formatToCharacterIterator();
358    }
359
360    /**
361     * @tests java.text.MessageFormat#format(java.lang.Object[],
362     *        java.lang.StringBuffer, java.text.FieldPosition)
363     */
364    public void test_format$Ljava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition() {
365        // Test for method java.lang.StringBuffer
366        // java.text.MessageFormat.format(java.lang.Object [],
367        // java.lang.StringBuffer, java.text.FieldPosition)
368        MessageFormat format = new MessageFormat("{1,number,integer}");
369        StringBuffer buffer = new StringBuffer();
370        format.format(new Object[] { "0", new Double(53.863) }, buffer,
371                new FieldPosition(0));
372		assertEquals("Wrong result", "54", buffer.toString());
373        format
374                .applyPattern("{0,choice,0#zero|1#one '{1,choice,2#two {2,time}}'}");
375        Date date = new Date();
376        String expected = "one two "
377                + DateFormat.getTimeInstance().format(date);
378        String result = format.format(new Object[] { new Double(1.6),
379                new Integer(3), date });
380        assertTrue("Choice not recursive:\n" + expected + "\n" + result,
381                expected.equals(result));
382    }
383
384    /**
385     * @tests java.text.MessageFormat#format(java.lang.Object,
386     *        java.lang.StringBuffer, java.text.FieldPosition)
387     */
388    public void test_formatLjava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition() {
389        // Test for method java.lang.StringBuffer
390        // java.text.MessageFormat.format(java.lang.Object,
391        // java.lang.StringBuffer, java.text.FieldPosition)
392        new Support_MessageFormat(
393                "test_formatLjava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition")
394                .t_format_with_FieldPosition();
395    }
396
397    /**
398     * @tests java.text.MessageFormat#getFormats()
399     */
400    public void test_getFormats() {
401        // Test for method java.text.Format []
402        // java.text.MessageFormat.getFormats()
403
404        // test with repeating formats and max argument index < max offset
405        Format[] formats = format1.getFormats();
406        Format[] correctFormats = new Format[] {
407                NumberFormat.getCurrencyInstance(),
408                DateFormat.getTimeInstance(),
409                NumberFormat.getPercentInstance(), null,
410                new ChoiceFormat("0#off|1#on"), DateFormat.getDateInstance(), };
411
412        assertEquals("Test1:Returned wrong number of formats:",
413                correctFormats.length, formats.length);
414        for (int i = 0; i < correctFormats.length; i++) {
415            assertEquals("Test1:wrong format for pattern index " + i + ":",
416                    correctFormats[i], formats[i]);
417        }
418
419        // test with max argument index > max offset
420        formats = format2.getFormats();
421        correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
422                DateFormat.getTimeInstance(),
423                NumberFormat.getPercentInstance(), null,
424                new ChoiceFormat("0#off|1#on"), DateFormat.getDateInstance() };
425
426        assertEquals("Test2:Returned wrong number of formats:",
427                correctFormats.length, formats.length);
428        for (int i = 0; i < correctFormats.length; i++) {
429            assertEquals("Test2:wrong format for pattern index " + i + ":",
430                    correctFormats[i], formats[i]);
431        }
432
433        // test with argument number being zero
434        formats = format3.getFormats();
435        assertEquals("Test3: Returned wrong number of formats:", 0,
436                formats.length);
437    }
438
439    /**
440     * @tests java.text.MessageFormat#getFormatsByArgumentIndex()
441     */
442    public void test_getFormatsByArgumentIndex() {
443        // Test for method java.text.Format [] test_getFormatsByArgumentIndex()
444
445        // test with repeating formats and max argument index < max offset
446        Format[] formats = format1.getFormatsByArgumentIndex();
447        Format[] correctFormats = new Format[] { DateFormat.getDateInstance(),
448                new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(),
449                NumberFormat.getCurrencyInstance(), null };
450
451        assertEquals("Test1:Returned wrong number of formats:",
452                correctFormats.length, formats.length);
453        for (int i = 0; i < correctFormats.length; i++) {
454            assertEquals("Test1:wrong format for argument index " + i + ":",
455                    correctFormats[i], formats[i]);
456        }
457
458        // test with max argument index > max offset
459        formats = format2.getFormatsByArgumentIndex();
460        correctFormats = new Format[] { DateFormat.getDateInstance(),
461                new ChoiceFormat("0#off|1#on"), null,
462                NumberFormat.getCurrencyInstance(), null, null, null, null,
463                DateFormat.getTimeInstance() };
464
465        assertEquals("Test2:Returned wrong number of formats:",
466                correctFormats.length, formats.length);
467        for (int i = 0; i < correctFormats.length; i++) {
468            assertEquals("Test2:wrong format for argument index " + i + ":",
469                    correctFormats[i], formats[i]);
470        }
471
472        // test with argument number being zero
473        formats = format3.getFormatsByArgumentIndex();
474        assertEquals("Test3: Returned wrong number of formats:", 0,
475                formats.length);
476    }
477
478    /**
479     * @tests java.text.MessageFormat#setFormatByArgumentIndex(int,
480     *        java.text.Format)
481     */
482    public void test_setFormatByArgumentIndexILjava_text_Format() {
483        // test for method setFormatByArgumentIndex(int, Format)
484        MessageFormat f1 = (MessageFormat) format1.clone();
485        f1.setFormatByArgumentIndex(0, DateFormat.getTimeInstance());
486        f1.setFormatByArgumentIndex(4, new ChoiceFormat("1#few|2#ok|3#a lot"));
487
488        // test with repeating formats and max argument index < max offset
489        // compare getFormatsByArgumentIndex() results after calls to
490        // setFormatByArgumentIndex()
491        Format[] formats = f1.getFormatsByArgumentIndex();
492
493        Format[] correctFormats = new Format[] { DateFormat.getTimeInstance(),
494                new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(),
495                NumberFormat.getCurrencyInstance(),
496                new ChoiceFormat("1#few|2#ok|3#a lot") };
497
498        assertEquals("Test1A:Returned wrong number of formats:",
499                correctFormats.length, formats.length);
500        for (int i = 0; i < correctFormats.length; i++) {
501            assertEquals("Test1B:wrong format for argument index " + i + ":",
502                    correctFormats[i], formats[i]);
503        }
504
505        // compare getFormats() results after calls to
506        // setFormatByArgumentIndex()
507        formats = f1.getFormats();
508
509        correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
510                DateFormat.getTimeInstance(), DateFormat.getTimeInstance(),
511                new ChoiceFormat("1#few|2#ok|3#a lot"),
512                new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(), };
513
514        assertEquals("Test1C:Returned wrong number of formats:",
515                correctFormats.length, formats.length);
516        for (int i = 0; i < correctFormats.length; i++) {
517            assertEquals("Test1D:wrong format for pattern index " + i + ":",
518                    correctFormats[i], formats[i]);
519        }
520
521        // test setting argumentIndexes that are not used
522        MessageFormat f2 = (MessageFormat) format2.clone();
523        f2.setFormatByArgumentIndex(2, NumberFormat.getPercentInstance());
524        f2.setFormatByArgumentIndex(4, DateFormat.getTimeInstance());
525
526        formats = f2.getFormatsByArgumentIndex();
527        correctFormats = format2.getFormatsByArgumentIndex();
528
529        assertEquals("Test2A:Returned wrong number of formats:",
530                correctFormats.length, formats.length);
531        for (int i = 0; i < correctFormats.length; i++) {
532            assertEquals("Test2B:wrong format for argument index " + i + ":",
533                    correctFormats[i], formats[i]);
534        }
535
536        formats = f2.getFormats();
537        correctFormats = format2.getFormats();
538
539        assertEquals("Test2C:Returned wrong number of formats:",
540                correctFormats.length, formats.length);
541        for (int i = 0; i < correctFormats.length; i++) {
542            assertEquals("Test2D:wrong format for pattern index " + i + ":",
543                    correctFormats[i], formats[i]);
544        }
545
546        // test exceeding the argumentIndex number
547        MessageFormat f3 = (MessageFormat) format3.clone();
548        f3.setFormatByArgumentIndex(1, NumberFormat.getCurrencyInstance());
549
550        formats = f3.getFormatsByArgumentIndex();
551        assertEquals("Test3A:Returned wrong number of formats:", 0,
552                formats.length);
553
554        formats = f3.getFormats();
555        assertEquals("Test3B:Returned wrong number of formats:", 0,
556                formats.length);
557    }
558
559    /**
560     * @tests java.text.MessageFormat#setFormatsByArgumentIndex(java.text.Format[])
561     */
562    public void test_setFormatsByArgumentIndex$Ljava_text_Format() {
563        // test for method setFormatByArgumentIndex(Format[])
564        MessageFormat f1 = (MessageFormat) format1.clone();
565
566        // test with repeating formats and max argument index < max offset
567        // compare getFormatsByArgumentIndex() results after calls to
568        // setFormatsByArgumentIndex(Format[])
569        Format[] correctFormats = new Format[] { DateFormat.getTimeInstance(),
570                new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(),
571                NumberFormat.getCurrencyInstance(),
572                new ChoiceFormat("1#few|2#ok|3#a lot") };
573
574        f1.setFormatsByArgumentIndex(correctFormats);
575        Format[] formats = f1.getFormatsByArgumentIndex();
576
577        assertEquals("Test1A:Returned wrong number of formats:",
578                correctFormats.length, formats.length);
579        for (int i = 0; i < correctFormats.length; i++) {
580            assertEquals("Test1B:wrong format for argument index " + i + ":",
581                    correctFormats[i], formats[i]);
582        }
583
584        // compare getFormats() results after calls to
585        // setFormatByArgumentIndex()
586        formats = f1.getFormats();
587        correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
588                DateFormat.getTimeInstance(), DateFormat.getTimeInstance(),
589                new ChoiceFormat("1#few|2#ok|3#a lot"),
590                new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(), };
591
592        assertEquals("Test1C:Returned wrong number of formats:",
593                correctFormats.length, formats.length);
594        for (int i = 0; i < correctFormats.length; i++) {
595            assertEquals("Test1D:wrong format for pattern index " + i + ":",
596                    correctFormats[i], formats[i]);
597        }
598
599        // test setting argumentIndexes that are not used
600        MessageFormat f2 = (MessageFormat) format2.clone();
601        Format[] inputFormats = new Format[] { DateFormat.getDateInstance(),
602                new ChoiceFormat("0#off|1#on"),
603                NumberFormat.getPercentInstance(),
604                NumberFormat.getCurrencyInstance(),
605                DateFormat.getTimeInstance(), null, null, null,
606                DateFormat.getTimeInstance() };
607        f2.setFormatsByArgumentIndex(inputFormats);
608
609        formats = f2.getFormatsByArgumentIndex();
610        correctFormats = format2.getFormatsByArgumentIndex();
611
612        assertEquals("Test2A:Returned wrong number of formats:",
613                correctFormats.length, formats.length);
614        for (int i = 0; i < correctFormats.length; i++) {
615            assertEquals("Test2B:wrong format for argument index " + i + ":",
616                    correctFormats[i], formats[i]);
617        }
618
619        formats = f2.getFormats();
620        correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
621                DateFormat.getTimeInstance(), DateFormat.getDateInstance(),
622                null, new ChoiceFormat("0#off|1#on"),
623                DateFormat.getDateInstance() };
624
625        assertEquals("Test2C:Returned wrong number of formats:",
626                correctFormats.length, formats.length);
627        for (int i = 0; i < correctFormats.length; i++) {
628            assertEquals("Test2D:wrong format for pattern index " + i + ":",
629                    correctFormats[i], formats[i]);
630        }
631
632        // test exceeding the argumentIndex number
633        MessageFormat f3 = (MessageFormat) format3.clone();
634        f3.setFormatsByArgumentIndex(inputFormats);
635
636        formats = f3.getFormatsByArgumentIndex();
637        assertEquals("Test3A:Returned wrong number of formats:", 0,
638                formats.length);
639
640        formats = f3.getFormats();
641        assertEquals("Test3B:Returned wrong number of formats:", 0,
642                formats.length);
643
644    }
645
646    /**
647     * @tests java.text.MessageFormat#parse(java.lang.String,
648     *        java.text.ParsePosition)
649     */
650    public void test_parseLjava_lang_StringLjava_text_ParsePosition() {
651        MessageFormat format = new MessageFormat("date is {0,date,MMM d, yyyy}");
652        ParsePosition pos = new ParsePosition(2);
653        Object[] result = (Object[]) format
654                .parse("xxdate is Feb 28, 1999", pos);
655        assertTrue("No result: " + result.length, result.length >= 1);
656        assertTrue("Wrong answer", ((Date) result[0])
657                .equals(new GregorianCalendar(1999, Calendar.FEBRUARY, 28)
658                        .getTime()));
659
660        MessageFormat mf = new MessageFormat("vm={0},{1},{2}");
661        result = mf.parse("vm=win,foo,bar", new ParsePosition(0));
662        assertTrue("Invalid parse", result[0].equals("win")
663                && result[1].equals("foo") && result[2].equals("bar"));
664
665        mf = new MessageFormat("{0}; {0}; {0}");
666        String parse = "a; b; c";
667        result = mf.parse(parse, new ParsePosition(0));
668		assertEquals("Wrong variable result", "c", result[0]);
669
670		mf = new MessageFormat("before {0}, after {1,number}");
671		parse = "before you, after 42";
672		pos.setIndex(0);
673		pos.setErrorIndex(8);
674		result = mf.parse(parse, pos);
675		assertEquals(2, result.length);
676    }
677
678    /**
679     * @tests java.text.MessageFormat#setLocale(java.util.Locale)
680     */
681    public void test_setLocaleLjava_util_Locale() {
682        // Test for method void
683        // java.text.MessageFormat.setLocale(java.util.Locale)
684        MessageFormat format = new MessageFormat("date {0,date}");
685        format.setLocale(Locale.CHINA);
686        assertEquals("Wrong locale1", Locale.CHINA, format.getLocale());
687        format.applyPattern("{1,date}");
688        assertEquals("Wrong locale3", DateFormat.getDateInstance(DateFormat.DEFAULT,
689                Locale.CHINA), format.getFormats()[0]);
690    }
691
692    /**
693     * @tests java.text.MessageFormat#toPattern()
694     */
695    public void test_toPattern() {
696        // Test for method java.lang.String java.text.MessageFormat.toPattern()
697        String pattern = "[{0}]";
698        MessageFormat mf = new MessageFormat(pattern);
699        assertTrue("Wrong pattern", mf.toPattern().equals(pattern));
700
701        // Regression for HARMONY-59
702        new MessageFormat("CHOICE {1,choice}").toPattern();
703    }
704
705    /**
706     * Sets up the fixture, for example, open a network connection. This method
707     * is called before a test is executed.
708     */
709    protected void setUp() {
710    	defaultLocale = Locale.getDefault();
711    	Locale.setDefault(Locale.US);
712
713        // test with repeating formats and max argument index < max offset
714        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}";
715        format1 = new MessageFormat(pattern);
716
717        // test with max argument index > max offset
718        pattern = "A {3, number, currency} B {8, time} C {0, number, percent} D {6}  E {1,choice,0#off|1#on} F {0, date}";
719        format2 = new MessageFormat(pattern);
720
721        // test with argument number being zero
722        pattern = "A B C D E F";
723        format3 = new MessageFormat(pattern);
724    }
725
726    /**
727     * Tears down the fixture, for example, close a network connection. This
728     * method is called after a test is executed.
729     */
730    protected void tearDown() {
731    	Locale.setDefault(defaultLocale);
732    }
733
734	/**
735	 * @tests java.text.MessageFormat(java.util.Locale)
736	 */
737	public void test_ConstructorLjava_util_Locale() {
738		// Regression for HARMONY-65
739		try {
740			new MessageFormat("{0,number,integer", Locale.US);
741			fail("Assert 0: Failed to detect unmatched brackets.");
742		} catch (IllegalArgumentException e) {
743			// expected
744		}
745	}
746
747	/**
748	 * @tests java.text.MessageFormat#parse(java.lang.String)
749	 */
750	public void test_parse() throws ParseException {
751		// Regression for HARMONY-63
752		MessageFormat mf = new MessageFormat("{0,number,#,####}", Locale.US);
753		Object[] res = mf.parse("1,00,00");
754		assertEquals("Assert 0: incorrect size of parsed data ", 1, res.length);
755		assertEquals("Assert 1: parsed value incorrectly", new Long(10000), (Long)res[0]);
756	}
757
758	public void test_format_Object() {
759		// Regression for HARMONY-1875
760        Locale.setDefault(Locale.CANADA);
761        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
762        String pat="text here {0, date, yyyyyyyyy } and here";
763        String etalon="text here  000002007  and here";
764        MessageFormat obj = new MessageFormat(pat);
765        assertEquals(etalon, obj.format(new Object[]{new Date(1198141737640L)}));
766
767        assertEquals("{0}", MessageFormat.format("{0}", (Object[])null));
768        assertEquals("nullABC", MessageFormat.format("{0}{1}", new String[]{null, "ABC"}));
769    }
770
771    public void testHARMONY5323() {
772    	Object []messageArgs = new Object[11];
773    	for (int i = 0; i < messageArgs.length; i++)
774    		messageArgs[i] = "dumb"+i;
775
776		String res = MessageFormat.format("bgcolor=\"{10}\"", messageArgs);
777        assertEquals(res, "bgcolor=\"dumb10\"");
778    }
779}
780