1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements.  See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License.  You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.apache.harmony.tests.java.util;
17
18import java.io.BufferedOutputStream;
19import java.io.Closeable;
20import java.io.File;
21import java.io.FileNotFoundException;
22import java.io.FileOutputStream;
23import java.io.FilePermission;
24import java.io.Flushable;
25import java.io.IOException;
26import java.io.OutputStream;
27import java.io.PipedOutputStream;
28import java.io.PrintStream;
29import java.io.UnsupportedEncodingException;
30import java.math.BigDecimal;
31import java.math.BigInteger;
32import java.math.MathContext;
33import java.nio.charset.Charset;
34import java.security.Permission;
35import java.util.Arrays;
36import java.util.Calendar;
37import java.util.Date;
38import java.util.GregorianCalendar;
39import java.util.DuplicateFormatFlagsException;
40import java.util.FormatFlagsConversionMismatchException;
41import java.util.Formattable;
42import java.util.FormattableFlags;
43import java.util.Formatter;
44import java.util.FormatterClosedException;
45import java.util.IllegalFormatCodePointException;
46import java.util.IllegalFormatConversionException;
47import java.util.IllegalFormatException;
48import java.util.IllegalFormatFlagsException;
49import java.util.IllegalFormatPrecisionException;
50import java.util.IllegalFormatWidthException;
51import java.util.Locale;
52import java.util.MissingFormatArgumentException;
53import java.util.MissingFormatWidthException;
54import java.util.TimeZone;
55import java.util.UnknownFormatConversionException;
56import java.util.Formatter.BigDecimalLayoutForm;
57
58import junit.framework.TestCase;
59
60@SuppressWarnings("FormatString")  // This test tests illegal format strings.
61public class FormatterTest extends TestCase {
62    private boolean root;
63
64    class MockAppendable implements Appendable {
65        public Appendable append(CharSequence arg0) throws IOException {
66            return null;
67        }
68
69        public Appendable append(char arg0) throws IOException {
70            return null;
71        }
72
73        public Appendable append(CharSequence arg0, int arg1, int arg2)
74                throws IOException {
75            return null;
76        }
77    }
78
79    class MockFormattable implements Formattable {
80        public void formatTo(Formatter formatter, int flags, int width,
81                int precision) throws IllegalFormatException {
82            if ((flags & FormattableFlags.UPPERCASE) != 0) {
83                formatter.format("CUSTOMIZED FORMAT FUNCTION" + " WIDTH: "
84                        + width + " PRECISION: " + precision);
85            } else {
86                formatter.format("customized format function" + " width: "
87                        + width + " precision: " + precision);
88            }
89        }
90
91        public String toString() {
92            return "formattable object";
93        }
94
95        public int hashCode() {
96            return 0xf;
97        }
98    }
99
100    class MockDestination implements Appendable, Flushable {
101
102        private StringBuilder data = new StringBuilder();
103
104        private boolean enabled = false;
105
106        public Appendable append(char c) throws IOException {
107            if (enabled) {
108                data.append(c);
109                enabled = true; // enable it after the first append
110            } else {
111                throw new IOException();
112            }
113            return this;
114        }
115
116        public Appendable append(CharSequence csq) throws IOException {
117            if (enabled) {
118                data.append(csq);
119                enabled = true; // enable it after the first append
120            } else {
121                throw new IOException();
122            }
123            return this;
124        }
125
126        public Appendable append(CharSequence csq, int start, int end)
127                throws IOException {
128            if (enabled) {
129                data.append(csq, start, end);
130                enabled = true; // enable it after the first append
131            } else {
132                throw new IOException();
133            }
134            return this;
135        }
136
137        public void flush() throws IOException {
138            throw new IOException("Always throw IOException");
139        }
140
141        public String toString() {
142            return data.toString();
143        }
144    }
145
146    private File notExist;
147
148    private File fileWithContent;
149
150    private File readOnly;
151
152    private File secret;
153
154    private TimeZone defaultTimeZone;
155
156    private Locale defaultLocale;
157
158    /**
159     * java.util.Formatter#Formatter()
160     */
161    public void test_Constructor() {
162        Formatter f = new Formatter();
163        assertNotNull(f);
164        assertTrue(f.out() instanceof StringBuilder);
165        assertEquals(f.locale(), Locale.getDefault());
166        assertNotNull(f.toString());
167    }
168
169    /**
170     * java.util.Formatter#Formatter(Appendable)
171     */
172    public void test_ConstructorLjava_lang_Appendable() {
173        MockAppendable ma = new MockAppendable();
174        Formatter f1 = new Formatter(ma);
175        assertEquals(ma, f1.out());
176        assertEquals(f1.locale(), Locale.getDefault());
177        assertNotNull(f1.toString());
178
179        Formatter f2 = new Formatter((Appendable) null);
180        /*
181         * If a(the input param) is null then a StringBuilder will be created
182         * and the output can be attained by invoking the out() method. But RI
183         * raises an error of FormatterClosedException when invoking out() or
184         * toString().
185         */
186        Appendable sb = f2.out();
187        assertTrue(sb instanceof StringBuilder);
188        assertNotNull(f2.toString());
189    }
190
191    /**
192     * java.util.Formatter#Formatter(Locale)
193     */
194    public void test_ConstructorLjava_util_Locale() {
195        Formatter f1 = new Formatter(Locale.FRANCE);
196        assertTrue(f1.out() instanceof StringBuilder);
197        assertEquals(f1.locale(), Locale.FRANCE);
198        assertNotNull(f1.toString());
199
200        Formatter f2 = new Formatter((Locale) null);
201        assertNull(f2.locale());
202        assertTrue(f2.out() instanceof StringBuilder);
203        assertNotNull(f2.toString());
204    }
205
206    /**
207     * java.util.Formatter#Formatter(Appendable, Locale)
208     */
209    public void test_ConstructorLjava_lang_AppendableLjava_util_Locale() {
210        MockAppendable ma = new MockAppendable();
211        Formatter f1 = new Formatter(ma, Locale.CANADA);
212        assertEquals(ma, f1.out());
213        assertEquals(f1.locale(), Locale.CANADA);
214
215        Formatter f2 = new Formatter(ma, null);
216        assertNull(f2.locale());
217        assertEquals(ma, f1.out());
218
219        Formatter f3 = new Formatter(null, Locale.GERMAN);
220        assertEquals(f3.locale(), Locale.GERMAN);
221        assertTrue(f3.out() instanceof StringBuilder);
222    }
223
224    /**
225     * java.util.Formatter#Formatter(String)
226     */
227    public void test_ConstructorLjava_lang_String() throws IOException {
228        Formatter f = null;
229        try {
230            f = new Formatter((String) null);
231            fail("should throw NullPointerException");
232        } catch (NullPointerException e1) {
233            // expected
234        }
235
236        f = new Formatter(notExist.getPath());
237        assertEquals(f.locale(), Locale.getDefault());
238        f.close();
239
240        f = new Formatter(fileWithContent.getPath());
241        assertEquals(0, fileWithContent.length());
242        f.close();
243
244        if (!root) {
245            try {
246                f = new Formatter(readOnly.getPath());
247                fail("should throw FileNotFoundException");
248            } catch (FileNotFoundException e) {
249                // expected
250            }
251        }
252    }
253
254    /**
255     * java.util.Formatter#Formatter(String, String)
256     */
257    public void test_ConstructorLjava_lang_StringLjava_lang_String()
258            throws IOException {
259        Formatter f = null;
260        try {
261            f = new Formatter((String) null, Charset.defaultCharset().name());
262            fail("should throw NullPointerException");
263        } catch (NullPointerException e1) {
264            // expected
265        }
266
267        try {
268            f = new Formatter(notExist.getPath(), null);
269            fail("should throw NullPointerException");
270        } catch (NullPointerException e2) {
271            // expected
272        }
273
274        f = new Formatter(notExist.getPath(), Charset.defaultCharset().name());
275        assertEquals(f.locale(), Locale.getDefault());
276        f.close();
277
278        try {
279            f = new Formatter(notExist.getPath(), "ISO 1111-1");
280            fail("should throw UnsupportedEncodingException");
281        } catch (UnsupportedEncodingException e1) {
282            // expected
283        }
284
285        f = new Formatter(fileWithContent.getPath(), "UTF-16BE");
286        assertEquals(0, fileWithContent.length());
287        f.close();
288
289        if (!root) {
290            try {
291                f = new Formatter(readOnly.getPath(), "UTF-16BE");
292                fail("should throw FileNotFoundException");
293            } catch (FileNotFoundException e) {
294                // expected
295            }
296        }
297    }
298
299    /**
300     * java.util.Formatter#Formatter(String, String, Locale)
301     */
302    public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_util_Locale()
303            throws IOException {
304        Formatter f = null;
305        try {
306            f = new Formatter((String) null, Charset.defaultCharset().name(),
307                    Locale.KOREA);
308            fail("should throw NullPointerException");
309        } catch (NullPointerException e1) {
310            // expected
311        }
312
313        try {
314            f = new Formatter(notExist.getPath(), null, Locale.KOREA);
315            fail("should throw NullPointerException");
316        } catch (NullPointerException e2) {
317            // expected
318        }
319
320        f = new Formatter(notExist.getPath(), Charset.defaultCharset().name(),
321                null);
322        assertNotNull(f);
323        f.close();
324
325        f = new Formatter(notExist.getPath(), Charset.defaultCharset().name(),
326                Locale.KOREA);
327        assertEquals(f.locale(), Locale.KOREA);
328        f.close();
329
330        try {
331            f = new Formatter(notExist.getPath(), "ISO 1111-1", Locale.CHINA);
332            fail("should throw UnsupportedEncodingException");
333        } catch (UnsupportedEncodingException e1) {
334            // expected
335        }
336
337        f = new Formatter(fileWithContent.getPath(), "UTF-16BE",
338                Locale.CANADA_FRENCH);
339        assertEquals(0, fileWithContent.length());
340        f.close();
341
342        if (!root) {
343            try {
344                f = new Formatter(readOnly.getPath(), Charset.defaultCharset()
345                        .name(), Locale.ITALY);
346                fail("should throw FileNotFoundException");
347            } catch (FileNotFoundException e) {
348                // expected
349            }
350        }
351    }
352
353    /**
354     * java.util.Formatter#Formatter(File)
355     */
356    public void test_ConstructorLjava_io_File() throws IOException {
357        Formatter f = null;
358        try {
359            f = new Formatter((File) null);
360            fail("should throw NullPointerException");
361        } catch (NullPointerException e1) {
362            // expected
363        }
364
365        f = new Formatter(notExist);
366        assertEquals(f.locale(), Locale.getDefault());
367        f.close();
368
369        f = new Formatter(fileWithContent);
370        assertEquals(0, fileWithContent.length());
371        f.close();
372
373        if (!root) {
374            try {
375                f = new Formatter(readOnly);
376                fail("should throw FileNotFoundException");
377            } catch (FileNotFoundException e) {
378                // expected
379            }
380        }
381    }
382
383    /**
384     * java.util.Formatter#Formatter(File, String)
385     */
386    public void test_ConstructorLjava_io_FileLjava_lang_String()
387            throws IOException {
388        Formatter f = null;
389        try {
390            f = new Formatter((File) null, Charset.defaultCharset().name());
391            fail("should throw NullPointerException");
392        } catch (NullPointerException e1) {
393            // expected
394        }
395
396        f = new Formatter(notExist, Charset.defaultCharset().name());
397        assertEquals(f.locale(), Locale.getDefault());
398        f.close();
399
400        f = new Formatter(fileWithContent, "UTF-16BE");
401        assertEquals(0, fileWithContent.length());
402        f.close();
403
404        if (!root) {
405            try {
406                f = new Formatter(readOnly, Charset.defaultCharset().name());
407                fail("should throw FileNotFoundException");
408            } catch (FileNotFoundException e) {
409                // expected
410            }
411        }
412
413        try {
414            f = new Formatter(notExist, null);
415            fail("should throw NullPointerException");
416        } catch (NullPointerException e2) {
417            // expected
418        } finally {
419            if (notExist.exists()) {
420                // Fail on RI on Windows, because output stream is created and
421                // not closed when exception thrown
422                assertTrue(notExist.delete());
423            }
424        }
425
426        try {
427            f = new Formatter(notExist, "ISO 1111-1");
428            fail("should throw UnsupportedEncodingException");
429        } catch (UnsupportedEncodingException e1) {
430            // expected
431        } finally {
432            if (notExist.exists()) {
433                // Fail on RI on Windows, because output stream is created and
434                // not closed when exception thrown
435                assertTrue(notExist.delete());
436            }
437        }
438    }
439
440    /**
441     * java.util.Formatter#Formatter(File, String, Locale)
442     */
443    public void test_ConstructorLjava_io_FileLjava_lang_StringLjava_util_Locale()
444            throws IOException {
445        Formatter f = null;
446        try {
447            f = new Formatter((File) null, Charset.defaultCharset().name(),
448                    Locale.KOREA);
449            fail("should throw NullPointerException");
450        } catch (NullPointerException e1) {
451            // expected
452        }
453
454        try {
455            f = new Formatter(notExist, null, Locale.KOREA);
456            fail("should throw NullPointerException");
457        } catch (NullPointerException e2) {
458            // expected
459        }
460
461        f = new Formatter(notExist, Charset.defaultCharset().name(), null);
462        assertNotNull(f);
463        f.close();
464
465        f = new Formatter(notExist, Charset.defaultCharset().name(),
466                Locale.KOREA);
467        assertEquals(f.locale(), Locale.KOREA);
468        f.close();
469
470        try {
471            f = new Formatter(notExist, "ISO 1111-1", Locale.CHINA);
472            fail("should throw UnsupportedEncodingException");
473        } catch (UnsupportedEncodingException e1) {
474            // expected
475        }
476        f = new Formatter(fileWithContent.getPath(), "UTF-16BE",
477                Locale.CANADA_FRENCH);
478        assertEquals(0, fileWithContent.length());
479        f.close();
480
481        if (!root) {
482            try {
483                f = new Formatter(readOnly.getPath(), Charset.defaultCharset()
484                        .name(), Locale.ITALY);
485                fail("should throw FileNotFoundException");
486            } catch (FileNotFoundException e) {
487                // expected
488            }
489        }
490    }
491
492    /**
493     * java.util.Formatter#Formatter(PrintStream)
494     */
495    public void test_ConstructorLjava_io_PrintStream() throws IOException {
496        Formatter f = null;
497        try {
498            f = new Formatter((PrintStream) null);
499            fail("should throw NullPointerException");
500        } catch (NullPointerException e1) {
501            // expected
502        }
503
504        PrintStream ps = new PrintStream(notExist, "UTF-16BE");
505        f = new Formatter(ps);
506        assertEquals(Locale.getDefault(), f.locale());
507        f.close();
508    }
509
510    /**
511     * java.util.Formatter#Formatter(OutputStream)
512     */
513    public void test_ConstructorLjava_io_OutputStream() throws IOException {
514        Formatter f = null;
515        try {
516            f = new Formatter((OutputStream) null);
517            fail("should throw NullPointerException");
518        } catch (NullPointerException e1) {
519            // expected
520        }
521
522        OutputStream os = new FileOutputStream(notExist);
523        f = new Formatter(os);
524        assertEquals(Locale.getDefault(), f.locale());
525        f.close();
526    }
527
528    /**
529     * java.util.Formatter#Formatter(OutputStream, String)
530     */
531    public void test_ConstructorLjava_io_OutputStreamLjava_lang_String()
532            throws IOException {
533        Formatter f = null;
534        try {
535            f = new Formatter((OutputStream) null, Charset.defaultCharset()
536                    .name());
537            fail("should throw NullPointerException");
538        } catch (NullPointerException e1) {
539            // expected
540        }
541
542        OutputStream os = null;
543        try {
544            os = new FileOutputStream(notExist);
545            f = new Formatter(os, null);
546            fail("should throw NullPointerException");
547        } catch (NullPointerException e2) {
548            // expected
549        } finally {
550            os.close();
551        }
552
553        try {
554            os = new PipedOutputStream();
555            f = new Formatter(os, "TMP-1111");
556            fail("should throw UnsupportedEncodingException");
557        } catch (UnsupportedEncodingException e1) {
558            // expected
559        } finally {
560            os.close();
561        }
562
563        os = new FileOutputStream(fileWithContent);
564        f = new Formatter(os, "UTF-16BE");
565        assertEquals(Locale.getDefault(), f.locale());
566        f.close();
567    }
568
569    /**
570     * Test method for 'java.util.Formatter.Formatter(OutputStream, String,
571     * Locale)
572     */
573    public void test_ConstructorLjava_io_OutputStreamLjava_lang_StringLjava_util_Locale()
574            throws IOException {
575        Formatter f = null;
576        try {
577            f = new Formatter((OutputStream) null, Charset.defaultCharset()
578                    .name(), Locale.getDefault());
579            fail("should throw NullPointerException");
580        } catch (NullPointerException e1) {
581            // expected
582        }
583
584        OutputStream os = null;
585        try {
586            os = new FileOutputStream(notExist);
587            f = new Formatter(os, null, Locale.getDefault());
588            fail("should throw NullPointerException");
589        } catch (NullPointerException e2) {
590            // expected
591        } finally {
592            os.close();
593        }
594
595        os = new FileOutputStream(notExist);
596        f = new Formatter(os, Charset.defaultCharset().name(), null);
597        f.close();
598
599        try {
600            os = new PipedOutputStream();
601            f = new Formatter(os, "TMP-1111", Locale.getDefault());
602            fail("should throw UnsupportedEncodingException");
603        } catch (UnsupportedEncodingException e1) {
604            // expected
605        }
606
607        os = new FileOutputStream(fileWithContent);
608        f = new Formatter(os, "UTF-16BE", Locale.ENGLISH);
609        assertEquals(Locale.ENGLISH, f.locale());
610        f.close();
611    }
612
613    /**
614     * java.util.Formatter#locale()
615     */
616    public void test_locale() {
617        Formatter f = null;
618        f = new Formatter((Locale) null);
619        assertNull(f.locale());
620
621        f.close();
622        try {
623            f.locale();
624            fail("should throw FormatterClosedException");
625        } catch (FormatterClosedException e) {
626            // expected
627        }
628    }
629
630    /**
631     * java.util.Formatter#out()
632     */
633    public void test_out() {
634        Formatter f = null;
635        f = new Formatter();
636        assertNotNull(f.out());
637        assertTrue(f.out() instanceof StringBuilder);
638        f.close();
639        try {
640            f.out();
641            fail("should throw FormatterClosedException");
642        } catch (FormatterClosedException e) {
643            // expected
644        }
645
646    }
647
648    /**
649     * java.util.Formatter#flush()
650     */
651    public void test_flush() throws IOException {
652        Formatter f = null;
653        f = new Formatter(notExist);
654        assertTrue(f instanceof Flushable);
655        f.close();
656        try {
657            f.flush();
658            fail("should throw FormatterClosedException");
659        } catch (FormatterClosedException e) {
660            // expected
661        }
662
663        f = new Formatter();
664        // For destination that does not implement Flushable
665        // No exception should be thrown
666        f.flush();
667    }
668
669    /**
670     * java.util.Formatter#close()
671     */
672    public void test_close() throws IOException {
673        Formatter f = new Formatter(notExist);
674        assertTrue(f instanceof Closeable);
675        f.close();
676        // close next time will not throw exception
677        f.close();
678        assertNull(f.ioException());
679    }
680
681    /**
682     * java.util.Formatter#toString()
683     */
684    public void test_toString() {
685        Formatter f = new Formatter();
686        assertNotNull(f.toString());
687        assertEquals(f.out().toString(), f.toString());
688        f.close();
689        try {
690            f.toString();
691            fail("should throw FormatterClosedException");
692        } catch (FormatterClosedException e) {
693            // expected
694        }
695    }
696
697    /**
698     * java.util.Formatter#ioException()
699     */
700    public void test_ioException() throws IOException {
701        Formatter f = null;
702        f = new Formatter(new MockDestination());
703        assertNull(f.ioException());
704        f.flush();
705        assertNotNull(f.ioException());
706        f.close();
707
708        MockDestination md = new MockDestination();
709        f = new Formatter(md);
710        f.format("%s%s", "1", "2");
711        // format stop working after IOException
712        assertNotNull(f.ioException());
713        assertEquals("", f.toString());
714    }
715
716    /**
717     * java.util.Formatter#format(String, Object...) for null parameter
718     */
719    public void test_formatLjava_lang_String$Ljava_lang_Object_null() {
720        Formatter f = new Formatter();
721        try {
722            f.format((String) null, "parameter");
723            fail("should throw NullPointerException");
724        } catch (NullPointerException e) {
725            // expected
726        }
727
728        f = new Formatter();
729        f.format("hello", (Object[]) null);
730        assertEquals("hello", f.toString());
731    }
732
733    /**
734     * java.util.Formatter#format(String, Object...) for argument index
735     */
736    public void test_formatLjava_lang_String$Ljava_lang_Object_ArgIndex() {
737        Formatter formatter = new Formatter(Locale.US);
738        formatter.format("%1$s%2$s%3$s%4$s%5$s%6$s%7$s%8$s%9$s%11$s%10$s", "1",
739                "2", "3", "4", "5", "6", "7", "8", "9", "10", "11");
740        assertEquals("1234567891110", formatter.toString());
741
742        formatter = new Formatter(Locale.JAPAN);
743        formatter.format("%0$s", "hello");
744        assertEquals("hello", formatter.toString());
745
746        try {
747            formatter = new Formatter(Locale.US);
748            formatter.format("%-1$s", "1", "2");
749            fail("should throw UnknownFormatConversionException");
750        } catch (UnknownFormatConversionException e) {
751            // expected
752        }
753
754        try {
755            formatter = new Formatter(Locale.US);
756            formatter.format("%$s", "hello", "2");
757            fail("should throw UnknownFormatConversionException");
758        } catch (UnknownFormatConversionException e) {
759            // expected
760        }
761
762        try {
763            Formatter f = new Formatter(Locale.US);
764            f.format("%", "string");
765            fail("should throw UnknownFormatConversionException");
766        } catch (UnknownFormatConversionException e) {
767            // expected
768        }
769
770        formatter = new Formatter(Locale.FRANCE);
771        formatter.format("%1$s%2$s%3$s%4$s%5$s%6$s%7$s%8$s%<s%s%s%<s", "1",
772                "2", "3", "4", "5", "6", "7", "8", "9", "10", "11");
773        assertEquals("123456788122", formatter.toString());
774
775        formatter = new Formatter(Locale.FRANCE);
776        formatter.format(
777                "xx%1$s22%2$s%s%<s%5$s%<s&%7$h%2$s%8$s%<s%s%s%<ssuffix", "1",
778                "2", "3", "4", "5", "6", 7, "8", "9", "10", "11");
779        assertEquals("xx12221155&7288233suffix", formatter.toString());
780
781        try {
782            formatter.format("%<s", "hello");
783            fail("should throw MissingFormatArgumentException");
784        } catch (MissingFormatArgumentException e) {
785            // expected
786        }
787
788        formatter = new Formatter(Locale.US);
789        try {
790            formatter.format("%123$s", "hello");
791            fail("should throw MissingFormatArgumentException");
792        } catch (MissingFormatArgumentException e) {
793            // expected
794        }
795
796        formatter = new Formatter(Locale.US);
797        try {
798            // 2147483648 is the value of Integer.MAX_VALUE + 1
799            formatter.format("%2147483648$s", "hello");
800            fail("should throw MissingFormatArgumentException");
801        } catch (MissingFormatArgumentException e) {
802            // expected
803        }
804
805        try {
806            // 2147483647 is the value of Integer.MAX_VALUE
807            formatter.format("%2147483647$s", "hello");
808            fail("should throw MissingFormatArgumentException");
809        } catch (MissingFormatArgumentException e) {
810            // expected
811        }
812
813        formatter = new Formatter(Locale.US);
814        try {
815            formatter.format("%s%s", "hello");
816            fail("should throw MissingFormatArgumentException");
817        } catch (MissingFormatArgumentException e) {
818            // expected
819        }
820
821        formatter = new Formatter(Locale.US);
822        formatter.format("$100", 100);
823        assertEquals("$100", formatter.toString());
824
825        formatter = new Formatter(Locale.UK);
826        formatter.format("%01$s", "string");
827        assertEquals("string", formatter.toString());
828    }
829
830    /**
831     * java.util.Formatter#format(String, Object...) for width
832     */
833    public void test_formatLjava_lang_String$Ljava_lang_Object_Width() {
834        Formatter f = new Formatter(Locale.US);
835        f.format("%1$8s", "1");
836        assertEquals("       1", f.toString());
837
838        f = new Formatter(Locale.US);
839        f.format("%1$-1%", "string");
840        assertEquals("%", f.toString());
841
842        f = new Formatter(Locale.ITALY);
843        // 2147483648 is the value of Integer.MAX_VALUE + 1
844        f.format("%2147483648s", "string");
845        assertEquals("string", f.toString());
846
847        // the value of Integer.MAX_VALUE will allocate about 4G bytes of
848        // memory.
849        // It may cause OutOfMemoryError, so this value is not tested
850    }
851
852    /**
853     * java.util.Formatter#format(String, Object...) for precision
854     */
855    public void test_formatLjava_lang_String$Ljava_lang_Object_Precision() {
856        Formatter f = new Formatter(Locale.US);
857        f.format("%.5s", "123456");
858        assertEquals("12345", f.toString());
859
860        f = new Formatter(Locale.US);
861        // 2147483648 is the value of Integer.MAX_VALUE + 1
862        f.format("%.2147483648s", "...");
863        assertEquals("...", f.toString());
864
865        // the value of Integer.MAX_VALUE will allocate about 4G bytes of
866        // memory.
867        // It may cause OutOfMemoryError, so this value is not tested
868
869        f = new Formatter(Locale.US);
870        f.format("%10.0b", Boolean.TRUE);
871        assertEquals("          ", f.toString());
872
873        f = new Formatter(Locale.US);
874        f.format("%10.01s", "hello");
875        assertEquals("         h", f.toString());
876
877        try {
878            f = new Formatter(Locale.US);
879            f.format("%.s", "hello", "2");
880            fail("should throw Exception");
881        } catch (UnknownFormatConversionException
882                 | IllegalFormatPrecisionException expected) {
883            // expected
884        }
885
886        try {
887            f = new Formatter(Locale.US);
888            f.format("%.-5s", "123456");
889            fail("should throw Exception");
890        } catch (UnknownFormatConversionException
891                 | IllegalFormatPrecisionException expected) {
892            // expected
893        }
894
895        try {
896            f = new Formatter(Locale.US);
897            f.format("%1.s", "hello", "2");
898            fail("should throw Exception");
899        } catch (UnknownFormatConversionException
900                 | IllegalFormatPrecisionException expected) {
901            // expected
902        }
903
904        f = new Formatter(Locale.US);
905        f.format("%5.1s", "hello");
906        assertEquals("    h", f.toString());
907
908        f = new Formatter(Locale.FRANCE);
909        f.format("%.0s", "hello", "2");
910        assertEquals("", f.toString());
911    }
912
913    /**
914     * java.util.Formatter#format(String, Object...) for line sperator
915     */
916    public void test_formatLjava_lang_String$Ljava_lang_Object_LineSeparator() {
917        Formatter f = null;
918
919        String oldSeparator = System.getProperty("line.separator");
920        try {
921            System.setProperty("line.separator", "!\n");
922
923            f = new Formatter(Locale.US);
924            f.format("%1$n", 1);
925            assertEquals("!\n", f.toString());
926
927            f = new Formatter(Locale.KOREAN);
928            f.format("head%1$n%2$n", 1, new Date());
929            assertEquals("head!\n!\n", f.toString());
930
931            f = new Formatter(Locale.US);
932            f.format("%n%s", "hello");
933            assertEquals("!\nhello", f.toString());
934        } finally {
935            System.setProperty("line.separator", oldSeparator);
936        }
937
938        f = new Formatter(Locale.US);
939        try {
940            f.format("%-n");
941            fail("should throw IllegalFormatFlagsException: %-n");
942        } catch (IllegalFormatFlagsException e) {
943            // expected
944        }
945        try {
946            f.format("%+n");
947            fail("should throw IllegalFormatFlagsException: %+n");
948        } catch (IllegalFormatFlagsException e) {
949            // expected
950        }
951        try {
952            f.format("%#n");
953            fail("should throw IllegalFormatFlagsException: %#n");
954        } catch (IllegalFormatFlagsException e) {
955            // expected
956        }
957        try {
958            f.format("% n");
959            fail("should throw IllegalFormatFlagsException: % n");
960        } catch (IllegalFormatFlagsException e) {
961            // expected
962        }
963        try {
964            f.format("%0n");
965            fail("should throw IllegalFormatFlagsException: %0n");
966        } catch (IllegalFormatFlagsException e) {
967            // expected
968        }
969        try {
970            f.format("%,n");
971            fail("should throw IllegalFormatFlagsException: %,n");
972        } catch (IllegalFormatFlagsException e) {
973            // expected
974        }
975        try {
976            f.format("%(n");
977            fail("should throw IllegalFormatFlagsException: %(n");
978        } catch (IllegalFormatFlagsException e) {
979            // expected
980        }
981
982        f = new Formatter(Locale.US);
983        try {
984            f.format("%4n");
985            fail("should throw IllegalFormatWidthException");
986        } catch (IllegalFormatWidthException e) {
987            // expected
988        }
989
990        f = new Formatter(Locale.US);
991        try {
992            f.format("%-4n");
993            fail("should throw IllegalFormatWidthException");
994        } catch (IllegalFormatWidthException e) {
995            // expected
996        }
997
998        f = new Formatter(Locale.US);
999        try {
1000            f.format("%.9n");
1001            fail("should throw IllegalFormatPrecisionException");
1002        } catch (IllegalFormatPrecisionException e) {
1003            // expected
1004        }
1005
1006        f = new Formatter(Locale.US);
1007        try {
1008            f.format("%5.9n");
1009            fail("should throw IllegalFormatPrecisionException");
1010        } catch (IllegalFormatPrecisionException e) {
1011            // expected
1012        }
1013
1014        System.setProperty("line.separator", oldSeparator);
1015    }
1016
1017    /**
1018     * java.util.Formatter#format(String, Object...) for percent
1019     */
1020    public void test_formatLjava_lang_String$Ljava_lang_Object_Percent() {
1021        Formatter f = null;
1022
1023        f = new Formatter(Locale.ENGLISH);
1024        f.format("%1$%", 100);
1025        assertEquals("%", f.toString());
1026
1027        f = new Formatter(Locale.CHINA);
1028        f.format("%1$%%%", "hello", new Object());
1029        assertEquals("%%", f.toString());
1030
1031        f = new Formatter(Locale.CHINA);
1032        f.format("%%%s", "hello");
1033        assertEquals("%hello", f.toString());
1034
1035        f = new Formatter(Locale.US);
1036        try {
1037            f.format("%.9%");
1038            fail("should throw IllegalFormatPrecisionException");
1039        } catch (IllegalFormatPrecisionException e) {
1040            // expected
1041        }
1042
1043        f = new Formatter(Locale.US);
1044        try {
1045            f.format("%5.9%");
1046            fail("should throw IllegalFormatPrecisionException");
1047        } catch (IllegalFormatPrecisionException e) {
1048            // expected
1049        }
1050
1051        f = new Formatter(Locale.US);
1052        assertFormatFlagsConversionMismatchException(f, "%+%");
1053        assertFormatFlagsConversionMismatchException(f, "%#%");
1054        assertFormatFlagsConversionMismatchException(f, "% %");
1055        assertFormatFlagsConversionMismatchException(f, "%0%");
1056        assertFormatFlagsConversionMismatchException(f, "%,%");
1057        assertFormatFlagsConversionMismatchException(f, "%(%");
1058
1059
1060        f = new Formatter(Locale.KOREAN);
1061        f.format("%4%", 1);
1062        /*
1063         * fail on RI the output string should be right justified by appending
1064         * spaces till the whole string is 4 chars width.
1065         */
1066        assertEquals("   %", f.toString());
1067
1068        f = new Formatter(Locale.US);
1069        f.format("%-4%", 100);
1070        /*
1071         * fail on RI, throw UnknownFormatConversionException the output string
1072         * should be left justified by appending spaces till the whole string is
1073         * 4 chars width.
1074         */
1075        assertEquals("%   ", f.toString());
1076    }
1077
1078    private void assertFormatFlagsConversionMismatchException(Formatter f, String str) {
1079        try {
1080            f.format(str);
1081            fail("should throw FormatFlagsConversionMismatchException: "
1082                    + str);
1083            /*
1084            * error on RI, throw IllegalFormatFlagsException specification
1085            * says FormatFlagsConversionMismatchException should be thrown
1086            */
1087        } catch (FormatFlagsConversionMismatchException e) {
1088            // expected
1089        }
1090    }
1091
1092    /**
1093     * java.util.Formatter#format(String, Object...) for flag
1094     */
1095    public void test_formatLjava_lang_String$Ljava_lang_Object_Flag() {
1096        Formatter f = new Formatter(Locale.US);
1097        try {
1098            f.format("%1$-#-8s", "something");
1099            fail("should throw DuplicateFormatFlagsException");
1100        } catch (DuplicateFormatFlagsException e) {
1101            // expected
1102        }
1103
1104        final char[] chars = { '-', '#', '+', ' ', '0', ',', '(', '%', '<' };
1105        Arrays.sort(chars);
1106        f = new Formatter(Locale.US);
1107        for (char i = 0; i <= 256; i++) {
1108            // test 8 bit character
1109            if (Arrays.binarySearch(chars, i) >= 0 || Character.isDigit(i)
1110                    || Character.isLetter(i)) {
1111                // Do not test 0-9, a-z, A-Z and characters in the chars array.
1112                // They are characters used as flags, width or conversions
1113                continue;
1114            }
1115            try {
1116                f.format("%" + i + "s", 1);
1117                fail("should throw UnknownFormatConversionException");
1118            } catch (UnknownFormatConversionException e) {
1119                // expected
1120            } catch (IllegalFormatPrecisionException e) {
1121                // If i is '.', s can also be interpreted as an illegal precision.
1122                if (i != '.') {
1123                    throw e;
1124                }
1125            }
1126        }
1127    }
1128
1129    /**
1130     * java.util.Formatter#format(String, Object...) for general
1131     * conversion b/B
1132     */
1133    public void test_format_LString$LObject_GeneralConversionB() {
1134        final Object[][] triple = {
1135                { Boolean.FALSE, "%3.2b", " fa", },
1136                { Boolean.FALSE, "%-4.6b", "false", },
1137                { Boolean.FALSE, "%.2b", "fa", },
1138                { Boolean.TRUE, "%3.2b", " tr", },
1139                { Boolean.TRUE, "%-4.6b", "true", },
1140                { Boolean.TRUE, "%.2b", "tr", },
1141                { new Character('c'), "%3.2b", " tr", },
1142                { new Character('c'), "%-4.6b", "true", },
1143                { new Character('c'), "%.2b", "tr", },
1144                { new Byte((byte) 0x01), "%3.2b", " tr", },
1145                { new Byte((byte) 0x01), "%-4.6b", "true", },
1146                { new Byte((byte) 0x01), "%.2b", "tr", },
1147                { new Short((short) 0x0001), "%3.2b", " tr", },
1148                { new Short((short) 0x0001), "%-4.6b", "true", },
1149                { new Short((short) 0x0001), "%.2b", "tr", },
1150                { new Integer(1), "%3.2b", " tr", },
1151                { new Integer(1), "%-4.6b", "true", },
1152                { new Integer(1), "%.2b", "tr", },
1153                { new Float(1.1f), "%3.2b", " tr", },
1154                { new Float(1.1f), "%-4.6b", "true", },
1155                { new Float(1.1f), "%.2b", "tr", },
1156                { new Double(1.1d), "%3.2b", " tr", },
1157                { new Double(1.1d), "%-4.6b", "true", },
1158                { new Double(1.1d), "%.2b", "tr", },
1159                { "", "%3.2b", " tr", },
1160                { "", "%-4.6b", "true", },
1161                { "", "%.2b", "tr", },
1162                { "string content", "%3.2b", " tr", },
1163                { "string content", "%-4.6b", "true", },
1164                { "string content", "%.2b", "tr", },
1165                { new MockFormattable(), "%3.2b", " tr", },
1166                { new MockFormattable(), "%-4.6b", "true", },
1167                { new MockFormattable(), "%.2b", "tr", },
1168                { (Object) null, "%3.2b", " fa", },
1169                { (Object) null, "%-4.6b", "false", },
1170                { (Object) null, "%.2b", "fa", },
1171        };
1172
1173
1174        final int input = 0;
1175        final int pattern = 1;
1176        final int output = 2;
1177        Formatter f = null;
1178        for (int i = 0; i < triple.length; i++) {
1179            f = new Formatter(Locale.FRANCE);
1180            f.format((String) triple[i][pattern], triple[i][input]);
1181            assertEquals("triple[" + i + "]:" + triple[i][input]
1182                    + ",pattern[" + i + "]:" + triple[i][pattern], triple[i][output], f.toString());
1183
1184            f = new Formatter(Locale.GERMAN);
1185            f.format(((String) triple[i][pattern]).toUpperCase(Locale.US), triple[i][input]);
1186            assertEquals("triple[" + i + "]:" + triple[i][input]
1187                    + ",pattern[" + i + "]:" + triple[i][pattern], ((String) triple[i][output])
1188                    .toUpperCase(Locale.US), f.toString());
1189        }
1190    }
1191
1192    /**
1193     * java.util.Formatter#format(String, Object...) for general
1194     * conversion type 's' and 'S'
1195     */
1196    public void test_format_LString$LObject_GeneralConversionS() {
1197
1198        final Object[][] triple = {
1199                { Boolean.FALSE, "%2.3s", "fal", },
1200                { Boolean.FALSE, "%-6.4s", "fals  ", },
1201                { Boolean.FALSE, "%.5s", "false", },
1202                { Boolean.TRUE, "%2.3s", "tru", },
1203                { Boolean.TRUE, "%-6.4s", "true  ", },
1204                { Boolean.TRUE, "%.5s", "true", },
1205                { new Character('c'), "%2.3s", " c", },
1206                { new Character('c'), "%-6.4s", "c     ", },
1207                { new Character('c'), "%.5s", "c", },
1208                { new Byte((byte) 0x01), "%2.3s", " 1", },
1209                { new Byte((byte) 0x01), "%-6.4s", "1     ", },
1210                { new Byte((byte) 0x01), "%.5s", "1", },
1211                { new Short((short) 0x0001), "%2.3s", " 1", },
1212                { new Short((short) 0x0001), "%-6.4s", "1     ", },
1213                { new Short((short) 0x0001), "%.5s", "1", },
1214                { new Integer(1), "%2.3s", " 1", },
1215                { new Integer(1), "%-6.4s", "1     ", },
1216                { new Integer(1), "%.5s", "1", },
1217                { new Float(1.1f), "%2.3s", "1.1", },
1218                { new Float(1.1f), "%-6.4s", "1.1   ", },
1219                { new Float(1.1f), "%.5s", "1.1", },
1220                { new Double(1.1d), "%2.3s", "1.1", },
1221                { new Double(1.1d), "%-6.4s", "1.1   ", },
1222                { new Double(1.1d), "%.5s", "1.1", },
1223                { "", "%2.3s", "  ", },
1224                { "", "%-6.4s", "      ", },
1225                { "", "%.5s", "", },
1226                { "string content", "%2.3s", "str", },
1227                { "string content", "%-6.4s", "stri  ", },
1228                { "string content", "%.5s", "strin", },
1229                { new MockFormattable(), "%2.3s", "customized format function width: 2 precision: 3", },
1230                { new MockFormattable(), "%-6.4s", "customized format function width: 6 precision: 4", },
1231                { new MockFormattable(), "%.5s", "customized format function width: -1 precision: 5", },
1232                { (Object) null, "%2.3s", "nul", },
1233                { (Object) null, "%-6.4s", "null  ", },
1234                { (Object) null, "%.5s", "null", },
1235        };
1236
1237
1238        final int input = 0;
1239        final int pattern = 1;
1240        final int output = 2;
1241        Formatter f = null;
1242        for (int i = 0; i < triple.length; i++) {
1243            f = new Formatter(Locale.FRANCE);
1244            f.format((String) triple[i][pattern], triple[i][input]);
1245            assertEquals("triple[" + i + "]:" + triple[i][input]
1246                    + ",pattern[" + i + "]:" + triple[i][pattern], triple[i][output], f.toString());
1247
1248            f = new Formatter(Locale.GERMAN);
1249            f.format(((String) triple[i][pattern]).toUpperCase(Locale.US), triple[i][input]);
1250            assertEquals("triple[" + i + "]:" + triple[i][input]
1251                    + ",pattern[" + i + "]:" + triple[i][pattern], ((String) triple[i][output])
1252                    .toUpperCase(Locale.US), f.toString());
1253        }
1254    }
1255
1256    /**
1257     * java.util.Formatter#format(String, Object...) for general
1258     * conversion type 'h' and 'H'
1259     */
1260    public void test_format_LString$LObject_GeneralConversionH() {
1261
1262        final Object[] input = {
1263                Boolean.FALSE,
1264                Boolean.TRUE,
1265                new Character('c'),
1266                new Byte((byte) 0x01),
1267                new Short((short) 0x0001),
1268                new Integer(1),
1269                new Float(1.1f),
1270                new Double(1.1d),
1271                "",
1272                "string content",
1273                new MockFormattable(),
1274                (Object) null,
1275        };
1276
1277        Formatter f = null;
1278        for (int i = 0; i < input.length - 1; i++) {
1279            f = new Formatter(Locale.FRANCE);
1280            f.format("%h", input[i]);
1281            assertEquals("triple[" + i + "]:" + input[i],
1282                    Integer.toHexString(input[i].hashCode()), f.toString());
1283
1284            f = new Formatter(Locale.GERMAN);
1285            f.format("%H", input[i]);
1286            assertEquals("triple[" + i + "]:" + input[i],
1287                    Integer.toHexString(input[i].hashCode()).toUpperCase(Locale.US), f.toString());
1288        }
1289    }
1290
1291    /**
1292     * java.util.Formatter#format(String, Object...) for general
1293     * conversion other cases
1294     */
1295    public void test_formatLjava_lang_String$Ljava_lang_Object_GeneralConversionOther() {
1296        /*
1297         * In Turkish locale, the upper case of '\u0069' is '\u0130'. The
1298         * following test indicate that '\u0069' is coverted to upper case
1299         * without using the turkish locale.
1300         */
1301        Formatter f = new Formatter(new Locale("tr"));
1302        f.format("%S", "\u0069");
1303        assertEquals("\u0049", f.toString());
1304
1305        final Object[] input = {
1306                Boolean.FALSE,
1307                Boolean.TRUE,
1308                new Character('c'),
1309                new Byte((byte) 0x01),
1310                new Short((short) 0x0001),
1311                new Integer(1),
1312                new Float(1.1f),
1313                new Double(1.1d),
1314                "",
1315                "string content",
1316                new MockFormattable(),
1317                (Object) null,
1318        };
1319        f = new Formatter(Locale.GERMAN);
1320        for (int i = 0; i < input.length; i++) {
1321            if (!(input[i] instanceof Formattable)) {
1322                try {
1323                    f.format("%#s", input[i]);
1324                    /*
1325                     * fail on RI, spec says if the '#' flag is present and the
1326                     * argument is not a Formattable , then a
1327                     * FormatFlagsConversionMismatchException will be thrown.
1328                     */
1329                    fail("should throw FormatFlagsConversionMismatchException");
1330                } catch (FormatFlagsConversionMismatchException e) {
1331                    // expected
1332                }
1333            } else {
1334                f.format("%#s%<-#8s", input[i]);
1335                assertEquals(
1336                        "customized format function width: -1 precision: -1customized format function width: 8 precision: -1",
1337                        f.toString());
1338            }
1339        }
1340    }
1341
1342    /**
1343     * java.util.Formatter#format(String, Object...) for general
1344     * conversion exception
1345     */
1346    public void test_formatLjava_lang_String$Ljava_lang_Object_GeneralConversionException() {
1347        final String[] flagMismatch = { "%#b", "%+b", "% b", "%0b", "%,b",
1348                "%(b", "%#B", "%+B", "% B", "%0B", "%,B", "%(B", "%#h", "%+h",
1349                "% h", "%0h", "%,h", "%(h", "%#H", "%+H", "% H", "%0H", "%,H",
1350                "%(H", "%+s", "% s", "%0s", "%,s", "%(s", "%+S", "% S", "%0S",
1351                "%,S", "%(S" };
1352
1353        Formatter f = new Formatter(Locale.US);
1354
1355        for (int i = 0; i < flagMismatch.length; i++) {
1356            try {
1357                f.format(flagMismatch[i], "something");
1358                fail("should throw FormatFlagsConversionMismatchException");
1359            } catch (FormatFlagsConversionMismatchException e) {
1360                // expected
1361            }
1362        }
1363
1364        final String[] missingWidth = { "%-b", "%-B", "%-h", "%-H", "%-s",
1365                "%-S", };
1366        for (int i = 0; i < missingWidth.length; i++) {
1367            try {
1368                f.format(missingWidth[i], "something");
1369                fail("should throw MissingFormatWidthException");
1370            } catch (MissingFormatWidthException e) {
1371                // expected
1372            }
1373        }
1374
1375        // Regression test
1376        f = new Formatter();
1377        try {
1378            f.format("%c", (byte) -0x0001);
1379            fail("Should throw IllegalFormatCodePointException");
1380        } catch (IllegalFormatCodePointException e) {
1381            // expected
1382        }
1383
1384        f = new Formatter();
1385        try {
1386            f.format("%c", (short) -0x0001);
1387            fail("Should throw IllegalFormatCodePointException");
1388        } catch (IllegalFormatCodePointException e) {
1389            // expected
1390        }
1391
1392        f = new Formatter();
1393        try {
1394            f.format("%c", -0x0001);
1395            fail("Should throw IllegalFormatCodePointException");
1396        } catch (IllegalFormatCodePointException e) {
1397            // expected
1398        }
1399    }
1400
1401    /**
1402     * java.util.Formatter#format(String, Object...) for Character
1403     * conversion
1404     */
1405    public void test_formatLjava_lang_String$Ljava_lang_Object_CharacterConversion() {
1406        Formatter f = new Formatter(Locale.US);
1407        final Object[] illArgs = { Boolean.TRUE, new Float(1.1f),
1408                new Double(1.1d), "string content", new Float(1.1f), new Date() };
1409        for (int i = 0; i < illArgs.length; i++) {
1410            try {
1411                f.format("%c", illArgs[i]);
1412                fail("should throw IllegalFormatConversionException");
1413            } catch (IllegalFormatConversionException e) {
1414                // expected
1415            }
1416        }
1417
1418        try {
1419            f.format("%c", Integer.MAX_VALUE);
1420            fail("should throw IllegalFormatCodePointException");
1421        } catch (IllegalFormatCodePointException e) {
1422            // expected
1423        }
1424
1425        try {
1426            f.format("%#c", 'c');
1427            fail("should throw FormatFlagsConversionMismatchException");
1428        } catch (FormatFlagsConversionMismatchException e) {
1429            // expected
1430        }
1431
1432        final Object[][] triple = {
1433                { 'c', "%c", "c" },
1434                { 'c', "%-2c", "c " },
1435                { '\u0123', "%c", "\u0123" },
1436                { '\u0123', "%-2c", "\u0123 " },
1437                { (byte) 0x11, "%c", "\u0011" },
1438                { (byte) 0x11, "%-2c", "\u0011 " },
1439                { (short) 0x1111, "%c", "\u1111" },
1440                { (short) 0x1111, "%-2c", "\u1111 " },
1441                { 0x11, "%c", "\u0011" },
1442                { 0x11, "%-2c", "\u0011 " },
1443        };
1444
1445        final int input = 0;
1446        final int pattern = 1;
1447        final int output = 2;
1448        for (int i = 0; i < triple.length; i++) {
1449            f = new Formatter(Locale.US);
1450            f.format((String) triple[i][pattern], triple[i][input]);
1451            assertEquals(triple[i][output], f.toString());
1452        }
1453
1454        f = new Formatter(Locale.US);
1455        f.format("%c", 0x10000);
1456        assertEquals(0x10000, f.toString().codePointAt(0));
1457
1458        try {
1459            f.format("%2.2c", 'c');
1460            fail("should throw IllegalFormatPrecisionException");
1461        } catch (IllegalFormatPrecisionException e) {
1462            // expected
1463        }
1464
1465        f = new Formatter(Locale.US);
1466        f.format("%C", 'w');
1467        // error on RI, throw UnknownFormatConversionException
1468        // RI do not support converter 'C'
1469        assertEquals("W", f.toString());
1470
1471        f = new Formatter(Locale.JAPAN);
1472        f.format("%Ced", 0x1111);
1473        // error on RI, throw UnknownFormatConversionException
1474        // RI do not support converter 'C'
1475        assertEquals("\u1111ed", f.toString());
1476    }
1477
1478
1479    /**
1480     * java.util.Formatter#format(String, Object...) for legal
1481     * Byte/Short/Integer/Long conversion type 'd'
1482     */
1483    public void test_formatLjava_lang_String$Ljava_lang_Object_ByteShortIntegerLongConversionD() {
1484        final Object[][] triple = {
1485                { 0, "%d", "0" },
1486                { 0, "%10d", "         0" },
1487                { 0, "%-1d", "0" },
1488                { 0, "%+d", "+0" },
1489                { 0, "% d", " 0" },
1490                { 0, "%,d", "0" },
1491                { 0, "%(d", "0" },
1492                { 0, "%08d", "00000000" },
1493                { 0, "%-+,(11d", "+0         " },
1494                { 0, "%0 ,(11d", " 0000000000" },
1495
1496                { (byte) 0xff, "%d", "-1" },
1497                { (byte) 0xff, "%10d", "        -1" },
1498                { (byte) 0xff, "%-1d", "-1" },
1499                { (byte) 0xff, "%+d", "-1" },
1500                { (byte) 0xff, "% d", "-1" },
1501                { (byte) 0xff, "%,d", "-1" },
1502                { (byte) 0xff, "%(d", "(1)" },
1503                { (byte) 0xff, "%08d", "-0000001" },
1504                { (byte) 0xff, "%-+,(11d", "(1)        " },
1505                { (byte) 0xff, "%0 ,(11d", "(000000001)" },
1506
1507                { (short) 0xf123, "%d", "-3805" },
1508                { (short) 0xf123, "%10d", "     -3805" },
1509                { (short) 0xf123, "%-1d", "-3805" },
1510                { (short) 0xf123, "%+d", "-3805" },
1511                { (short) 0xf123, "% d", "-3805" },
1512                { (short) 0xf123, "%,d", "-3.805" },
1513                { (short) 0xf123, "%(d", "(3805)" },
1514                { (short) 0xf123, "%08d", "-0003805" },
1515                { (short) 0xf123, "%-+,(11d", "(3.805)    " },
1516                { (short) 0xf123, "%0 ,(11d", "(00003.805)" },
1517
1518                { 0x123456, "%d", "1193046" },
1519                { 0x123456, "%10d", "   1193046" },
1520                { 0x123456, "%-1d", "1193046" },
1521                { 0x123456, "%+d", "+1193046" },
1522                { 0x123456, "% d", " 1193046" },
1523                { 0x123456, "%,d", "1.193.046" },
1524                { 0x123456, "%(d", "1193046" },
1525                { 0x123456, "%08d", "01193046" },
1526                { 0x123456, "%-+,(11d", "+1.193.046 " },
1527                { 0x123456, "%0 ,(11d", " 01.193.046" },
1528
1529                { -3, "%d", "-3" },
1530                { -3, "%10d", "        -3" },
1531                { -3, "%-1d", "-3" },
1532                { -3, "%+d", "-3" },
1533                { -3, "% d", "-3" },
1534                { -3, "%,d", "-3" },
1535                { -3, "%(d", "(3)" },
1536                { -3, "%08d", "-0000003" },
1537                { -3, "%-+,(11d", "(3)        " },
1538                { -3, "%0 ,(11d", "(000000003)" },
1539
1540                { 0x7654321L, "%d", "124076833" },
1541                { 0x7654321L, "%10d", " 124076833" },
1542                { 0x7654321L, "%-1d", "124076833" },
1543                { 0x7654321L, "%+d", "+124076833" },
1544                { 0x7654321L, "% d", " 124076833" },
1545                { 0x7654321L, "%,d", "124.076.833" },
1546                { 0x7654321L, "%(d", "124076833" },
1547                { 0x7654321L, "%08d", "124076833" },
1548                { 0x7654321L, "%-+,(11d", "+124.076.833" },
1549                { 0x7654321L, "%0 ,(11d", " 124.076.833" },
1550
1551                { -1L, "%d", "-1" },
1552                { -1L, "%10d", "        -1" },
1553                { -1L, "%-1d", "-1" },
1554                { -1L, "%+d", "-1" },
1555                { -1L, "% d", "-1" },
1556                { -1L, "%,d", "-1" },
1557                { -1L, "%(d", "(1)" },
1558                { -1L, "%08d", "-0000001" },
1559                { -1L, "%-+,(11d", "(1)        " },
1560                { -1L, "%0 ,(11d", "(000000001)" },
1561        };
1562
1563        final int input = 0;
1564        final int pattern = 1;
1565        final int output = 2;
1566        Formatter f;
1567        for (int i = 0; i < triple.length; i++) {
1568            f = new Formatter(Locale.GERMAN);
1569            f.format((String) triple[i][pattern],
1570                    triple[i][input]);
1571            assertEquals("triple[" + i + "]:" + triple[i][input] + ",pattern["
1572                    + i + "]:" + triple[i][pattern], triple[i][output], f
1573                    .toString());
1574        }
1575    }
1576
1577    /**
1578     * java.util.Formatter#format(String, Object...) for legal
1579     * Byte/Short/Integer/Long conversion type 'o'
1580     */
1581    public void test_formatLjava_lang_String$Ljava_lang_Object_ByteShortIntegerLongConversionO() {
1582        final Object[][] triple = {
1583                { 0, "%o", "0" },
1584                { 0, "%-6o", "0     " },
1585                { 0, "%08o", "00000000" },
1586                { 0, "%#o", "00" },
1587                { 0, "%0#11o", "00000000000" },
1588                { 0, "%-#9o", "00       " },
1589
1590                { (byte) 0xff, "%o", "377" },
1591                { (byte) 0xff, "%-6o", "377   " },
1592                { (byte) 0xff, "%08o", "00000377" },
1593                { (byte) 0xff, "%#o", "0377" },
1594                { (byte) 0xff, "%0#11o", "00000000377" },
1595                { (byte) 0xff, "%-#9o", "0377     " },
1596
1597                { (short) 0xf123, "%o", "170443" },
1598                { (short) 0xf123, "%-6o", "170443" },
1599                { (short) 0xf123, "%08o", "00170443" },
1600                { (short) 0xf123, "%#o", "0170443" },
1601                { (short) 0xf123, "%0#11o", "00000170443" },
1602                { (short) 0xf123, "%-#9o", "0170443  " },
1603
1604                { 0x123456, "%o", "4432126" },
1605                { 0x123456, "%-6o", "4432126" },
1606                { 0x123456, "%08o", "04432126" },
1607                { 0x123456, "%#o", "04432126" },
1608                { 0x123456, "%0#11o", "00004432126" },
1609                { 0x123456, "%-#9o", "04432126 " },
1610
1611                { -3, "%o", "37777777775" },
1612                { -3, "%-6o", "37777777775" },
1613                { -3, "%08o", "37777777775" },
1614                { -3, "%#o", "037777777775" },
1615                { -3, "%0#11o", "037777777775" },
1616                { -3, "%-#9o", "037777777775" },
1617
1618                { 0x7654321L, "%o", "731241441" },
1619                { 0x7654321L, "%-6o", "731241441" },
1620                { 0x7654321L, "%08o", "731241441" },
1621                { 0x7654321L, "%#o", "0731241441" },
1622                { 0x7654321L, "%0#11o", "00731241441" },
1623                { 0x7654321L, "%-#9o", "0731241441" },
1624
1625                { -1L, "%o", "1777777777777777777777" },
1626                { -1L, "%-6o", "1777777777777777777777" },
1627                { -1L, "%08o", "1777777777777777777777" },
1628                { -1L, "%#o", "01777777777777777777777" },
1629                { -1L, "%0#11o", "01777777777777777777777" },
1630                { -1L, "%-#9o", "01777777777777777777777" },
1631        };
1632
1633        final int input = 0;
1634        final int pattern = 1;
1635        final int output = 2;
1636        Formatter f;
1637        for (int i = 0; i < triple.length; i++) {
1638            f = new Formatter(Locale.ITALY);
1639            f.format((String) triple[i][pattern],
1640                    triple[i][input]);
1641            assertEquals("triple[" + i + "]:" + triple[i][input] + ",pattern["
1642                    + i + "]:" + triple[i][pattern], triple[i][output], f
1643                    .toString());
1644        }
1645    }
1646
1647    /**
1648     * java.util.Formatter#format(String, Object...) for legal
1649     * Byte/Short/Integer/Long conversion type 'x' and 'X'
1650     */
1651    public void test_formatLjava_lang_String$Ljava_lang_Object_ByteShortIntegerLongConversionX() {
1652        final Object[][] triple = {
1653                { 0, "%x", "0" },
1654                { 0, "%-8x", "0       " },
1655                { 0, "%06x", "000000" },
1656                { 0, "%#x", "0x0" },
1657                { 0, "%0#12x", "0x0000000000" },
1658                { 0, "%-#9x", "0x0      " },
1659
1660                { (byte) 0xff, "%x", "ff" },
1661                { (byte) 0xff, "%-8x", "ff      " },
1662                { (byte) 0xff, "%06x", "0000ff" },
1663                { (byte) 0xff, "%#x", "0xff" },
1664                { (byte) 0xff, "%0#12x", "0x00000000ff" },
1665                { (byte) 0xff, "%-#9x", "0xff     " },
1666
1667                { (short) 0xf123, "%x", "f123" },
1668                { (short) 0xf123, "%-8x", "f123    " },
1669                { (short) 0xf123, "%06x", "00f123" },
1670                { (short) 0xf123, "%#x", "0xf123" },
1671                { (short) 0xf123, "%0#12x", "0x000000f123" },
1672                { (short) 0xf123, "%-#9x", "0xf123   " },
1673
1674                { 0x123456, "%x", "123456" },
1675                { 0x123456, "%-8x", "123456  " },
1676                { 0x123456, "%06x", "123456" },
1677                { 0x123456, "%#x", "0x123456" },
1678                { 0x123456, "%0#12x", "0x0000123456" },
1679                { 0x123456, "%-#9x", "0x123456 " },
1680
1681                { -3, "%x", "fffffffd" },
1682                { -3, "%-8x", "fffffffd" },
1683                { -3, "%06x", "fffffffd" },
1684                { -3, "%#x", "0xfffffffd" },
1685                { -3, "%0#12x", "0x00fffffffd" },
1686                { -3, "%-#9x", "0xfffffffd" },
1687
1688                { 0x7654321L, "%x", "7654321" },
1689                { 0x7654321L, "%-8x", "7654321 " },
1690                { 0x7654321L, "%06x", "7654321" },
1691                { 0x7654321L, "%#x", "0x7654321" },
1692                { 0x7654321L, "%0#12x", "0x0007654321" },
1693                { 0x7654321L, "%-#9x", "0x7654321" },
1694
1695                { -1L, "%x", "ffffffffffffffff" },
1696                { -1L, "%-8x", "ffffffffffffffff" },
1697                { -1L, "%06x", "ffffffffffffffff" },
1698                { -1L, "%#x", "0xffffffffffffffff" },
1699                { -1L, "%0#12x", "0xffffffffffffffff" },
1700                { -1L, "%-#9x", "0xffffffffffffffff" },
1701        };
1702
1703        final int input = 0;
1704        final int pattern = 1;
1705        final int output = 2;
1706        Formatter f;
1707        for (int i = 0; i < triple.length; i++) {
1708            f = new Formatter(Locale.FRANCE);
1709            f.format((String) triple[i][pattern],
1710                    triple[i][input]);
1711            assertEquals("triple[" + i + "]:" + triple[i][input] + ",pattern["
1712                    + i + "]:" + triple[i][pattern], triple[i][output], f
1713                    .toString());
1714
1715            f = new Formatter(Locale.FRANCE);
1716            f.format((String) triple[i][pattern],
1717                    triple[i][input]);
1718            assertEquals("triple[" + i + "]:" + triple[i][input] + ",pattern["
1719                    + i + "]:" + triple[i][pattern], triple[i][output], f
1720                    .toString());
1721        }
1722    }
1723
1724    /**
1725     * java.util.Formatter#format(String, Object...) for Date/Time
1726     * conversion
1727     */
1728    public void test_formatLjava_lang_String$Ljava_lang_Object_DateTimeConversion() {
1729        Formatter f = null;
1730        Date now = new Date(1147327147578L);
1731
1732        Calendar paris = Calendar.getInstance(TimeZone
1733                .getTimeZone("Europe/Paris"), Locale.FRANCE);
1734        paris.set(2006, 4, 8, 12, 0, 0);
1735        paris.set(Calendar.MILLISECOND, 453);
1736        Calendar china = Calendar.getInstance(
1737                TimeZone.getTimeZone("GMT-08:00"), Locale.CHINA);
1738        china.set(2006, 4, 8, 12, 0, 0);
1739        china.set(Calendar.MILLISECOND, 609);
1740
1741        final Object[][] lowerCaseGermanTriple = {
1742                { 0L, 'a', "Do." },  //$NON-NLS-2$
1743                { Long.MAX_VALUE, 'a', "So." },  //$NON-NLS-2$
1744                { -1000L, 'a', "Do." },  //$NON-NLS-2$
1745                { new Date(1147327147578L), 'a', "Do." },  //$NON-NLS-2$
1746                { paris, 'a', "Mo." },  //$NON-NLS-2$
1747                { china, 'a', "Mo." },  //$NON-NLS-2$
1748                { 0L, 'b', "Jan" },  //$NON-NLS-2$
1749                { Long.MAX_VALUE, 'b', "Aug" },  //$NON-NLS-2$
1750                { -1000L, 'b', "Jan" },  //$NON-NLS-2$
1751                { new Date(1147327147578L), 'b', "Mai" },  //$NON-NLS-2$
1752                { paris, 'b', "Mai" },  //$NON-NLS-2$
1753                { china, 'b', "Mai" },  //$NON-NLS-2$
1754                { 0L, 'c', "Do. Jan 01 08:00:00 GMT+08:00 1970" },  //$NON-NLS-2$
1755                { Long.MAX_VALUE, 'c', "So. Aug 17 15:18:47 GMT+08:00 292278994" },  //$NON-NLS-2$
1756                { -1000L, 'c', "Do. Jan 01 07:59:59 GMT+08:00 1970" },  //$NON-NLS-2$
1757                { new Date(1147327147578L), 'c', "Do. Mai 11 13:59:07 GMT+08:00 2006" },  //$NON-NLS-2$
1758                { paris, 'c', "Mo. Mai 08 12:00:00 MESZ 2006" },  //$NON-NLS-2$
1759                { china, 'c', "Mo. Mai 08 12:00:00 GMT-08:00 2006" },  //$NON-NLS-2$
1760                { 0L, 'd', "01" },  //$NON-NLS-2$
1761                { Long.MAX_VALUE, 'd', "17" },  //$NON-NLS-2$
1762                { -1000L, 'd', "01" },  //$NON-NLS-2$
1763                { new Date(1147327147578L), 'd', "11" },  //$NON-NLS-2$
1764                { paris, 'd', "08" },  //$NON-NLS-2$
1765                { china, 'd', "08" },  //$NON-NLS-2$
1766                { 0L, 'e', "1" },  //$NON-NLS-2$
1767                { Long.MAX_VALUE, 'e', "17" },  //$NON-NLS-2$
1768                { -1000L, 'e', "1" },  //$NON-NLS-2$
1769                { new Date(1147327147578L), 'e', "11" },  //$NON-NLS-2$
1770                { paris, 'e', "8" },  //$NON-NLS-2$
1771                { china, 'e', "8" },  //$NON-NLS-2$
1772                { 0L, 'h', "Jan" },  //$NON-NLS-2$
1773                { Long.MAX_VALUE, 'h', "Aug" },  //$NON-NLS-2$
1774                { -1000L, 'h', "Jan" },  //$NON-NLS-2$
1775                { new Date(1147327147578L), 'h', "Mai" },  //$NON-NLS-2$
1776                { paris, 'h', "Mai" },  //$NON-NLS-2$
1777                { china, 'h', "Mai" },  //$NON-NLS-2$
1778                { 0L, 'j', "001" },  //$NON-NLS-2$
1779                { Long.MAX_VALUE, 'j', "229" },  //$NON-NLS-2$
1780                { -1000L, 'j', "001" },  //$NON-NLS-2$
1781                { new Date(1147327147578L), 'j', "131" },  //$NON-NLS-2$
1782                { paris, 'j', "128" },  //$NON-NLS-2$
1783                { china, 'j', "128" },  //$NON-NLS-2$
1784                { 0L, 'k', "8" },  //$NON-NLS-2$
1785                { Long.MAX_VALUE, 'k', "15" },  //$NON-NLS-2$
1786                { -1000L, 'k', "7" },  //$NON-NLS-2$
1787                { new Date(1147327147578L), 'k', "13" },  //$NON-NLS-2$
1788                { paris, 'k', "12" },  //$NON-NLS-2$
1789                { china, 'k', "12" },  //$NON-NLS-2$
1790                { 0L, 'l', "8" }, //$NON-NLS-2$
1791                { Long.MAX_VALUE, 'l', "3" }, //$NON-NLS-2$
1792                { -1000L, 'l', "7" }, //$NON-NLS-2$
1793                { new Date(1147327147578L), 'l', "1" }, //$NON-NLS-2$
1794                { paris, 'l', "12" }, //$NON-NLS-2$
1795                { china, 'l', "12" }, //$NON-NLS-2$
1796                { 0L, 'm', "01" }, //$NON-NLS-2$
1797                { Long.MAX_VALUE, 'm', "08" }, //$NON-NLS-2$
1798                { -1000L, 'm', "01" }, //$NON-NLS-2$
1799                { new Date(1147327147578L), 'm', "05" }, //$NON-NLS-2$
1800                { paris, 'm', "05" }, //$NON-NLS-2$
1801                { china, 'm', "05" }, //$NON-NLS-2$
1802                { 0L, 'p', "vorm." }, //$NON-NLS-2$
1803                { Long.MAX_VALUE, 'p', "nachm." }, //$NON-NLS-2$
1804                { -1000L, 'p', "vorm." }, //$NON-NLS-2$
1805                { new Date(1147327147578L), 'p', "nachm." }, //$NON-NLS-2$
1806                { paris, 'p', "nachm." }, //$NON-NLS-2$
1807                { china, 'p', "nachm." }, //$NON-NLS-2$
1808                { 0L, 'r', "08:00:00 vorm." }, //$NON-NLS-2$
1809                { Long.MAX_VALUE, 'r', "03:18:47 nachm." }, //$NON-NLS-2$
1810                { -1000L, 'r', "07:59:59 vorm." }, //$NON-NLS-2$
1811                { new Date(1147327147578L), 'r', "01:59:07 nachm." }, //$NON-NLS-2$
1812                { paris, 'r', "12:00:00 nachm." }, //$NON-NLS-2$
1813                { china, 'r', "12:00:00 nachm." }, //$NON-NLS-2$
1814                { 0L, 's', "0" }, //$NON-NLS-2$
1815                { Long.MAX_VALUE, 's', "9223372036854775" }, //$NON-NLS-2$
1816                { -1000L, 's', "-1" }, //$NON-NLS-2$
1817                { new Date(1147327147578L), 's', "1147327147" }, //$NON-NLS-2$
1818                { paris, 's', "1147082400" }, //$NON-NLS-2$
1819                { china, 's', "1147118400" }, //$NON-NLS-2$
1820                { 0L, 'y', "70" }, //$NON-NLS-2$
1821                { Long.MAX_VALUE, 'y', "94" }, //$NON-NLS-2$
1822                { -1000L, 'y', "70" }, //$NON-NLS-2$
1823                { new Date(1147327147578L), 'y', "06" }, //$NON-NLS-2$
1824                { paris, 'y', "06" }, //$NON-NLS-2$
1825                { china, 'y', "06" }, //$NON-NLS-2$
1826                { 0L, 'z', "+0800" }, //$NON-NLS-2$
1827                { Long.MAX_VALUE, 'z', "+0800" }, //$NON-NLS-2$
1828                { -1000L, 'z', "+0800" }, //$NON-NLS-2$
1829                { new Date(1147327147578L), 'z', "+0800" }, //$NON-NLS-2$
1830                { paris, 'z', "+0100" }, //$NON-NLS-2$
1831                { china, 'z', "-0800" }, //$NON-NLS-2$
1832
1833        };
1834
1835        final Object[][] lowerCaseFranceTriple = {
1836                { 0L, 'a', "jeu." }, //$NON-NLS-2$
1837                { Long.MAX_VALUE, 'a', "dim." }, //$NON-NLS-2$
1838                { -1000L, 'a', "jeu." }, //$NON-NLS-2$
1839                { new Date(1147327147578L), 'a', "jeu." }, //$NON-NLS-2$
1840                { paris, 'a', "lun." }, //$NON-NLS-2$
1841                { china, 'a', "lun." }, //$NON-NLS-2$
1842                { 0L, 'b', "janv." }, //$NON-NLS-2$
1843                { Long.MAX_VALUE, 'b', "ao\u00fbt" }, //$NON-NLS-2$
1844                { -1000L, 'b', "janv." }, //$NON-NLS-2$
1845                { new Date(1147327147578L), 'b', "mai" }, //$NON-NLS-2$
1846                { paris, 'b', "mai" }, //$NON-NLS-2$
1847                { china, 'b', "mai" }, //$NON-NLS-2$
1848                { 0L, 'c', "jeu. janv. 01 08:00:00 UTC+08:00 1970" }, //$NON-NLS-2$
1849                { Long.MAX_VALUE, 'c', "dim. ao\u00fbt 17 15:18:47 UTC+08:00 292278994" }, //$NON-NLS-2$
1850                { -1000L, 'c', "jeu. janv. 01 07:59:59 UTC+08:00 1970" }, //$NON-NLS-2$
1851                { new Date(1147327147578L), 'c', "jeu. mai 11 13:59:07 UTC+08:00 2006" }, //$NON-NLS-2$
1852                { paris, 'c', "lun. mai 08 12:00:00 HAEC 2006" }, //$NON-NLS-2$
1853                { china, 'c', "lun. mai 08 12:00:00 UTC-08:00 2006" }, //$NON-NLS-2$
1854                { 0L, 'd', "01" }, //$NON-NLS-2$
1855                { Long.MAX_VALUE, 'd', "17" }, //$NON-NLS-2$
1856                { -1000L, 'd', "01" }, //$NON-NLS-2$
1857                { new Date(1147327147578L), 'd', "11" }, //$NON-NLS-2$
1858                { paris, 'd', "08" }, //$NON-NLS-2$
1859                { china, 'd', "08" }, //$NON-NLS-2$
1860                { 0L, 'e', "1" }, //$NON-NLS-2$
1861                { Long.MAX_VALUE, 'e', "17" }, //$NON-NLS-2$
1862                { -1000L, 'e', "1" }, //$NON-NLS-2$
1863                { new Date(1147327147578L), 'e', "11" }, //$NON-NLS-2$
1864                { paris, 'e', "8" }, //$NON-NLS-2$
1865                { china, 'e', "8" }, //$NON-NLS-2$
1866                { 0L, 'h', "janv." }, //$NON-NLS-2$
1867                { Long.MAX_VALUE, 'h', "ao\u00fbt" }, //$NON-NLS-2$
1868                { -1000L, 'h', "janv." }, //$NON-NLS-2$
1869                { new Date(1147327147578L), 'h', "mai" }, //$NON-NLS-2$
1870                { paris, 'h', "mai" }, //$NON-NLS-2$
1871                { china, 'h', "mai" }, //$NON-NLS-2$
1872                { 0L, 'j', "001" }, //$NON-NLS-2$
1873                { Long.MAX_VALUE, 'j', "229" }, //$NON-NLS-2$
1874                { -1000L, 'j', "001" }, //$NON-NLS-2$
1875                { new Date(1147327147578L), 'j', "131" }, //$NON-NLS-2$
1876                { paris, 'j', "128" }, //$NON-NLS-2$
1877                { china, 'j', "128" }, //$NON-NLS-2$
1878                { 0L, 'k', "8" }, //$NON-NLS-2$
1879                { Long.MAX_VALUE, 'k', "15" }, //$NON-NLS-2$
1880                { -1000L, 'k', "7" }, //$NON-NLS-2$
1881                { new Date(1147327147578L), 'k', "13" }, //$NON-NLS-2$
1882                { paris, 'k', "12" }, //$NON-NLS-2$
1883                { china, 'k', "12" }, //$NON-NLS-2$
1884                { 0L, 'l', "8" }, //$NON-NLS-2$
1885                { Long.MAX_VALUE, 'l', "3" }, //$NON-NLS-2$
1886                { -1000L, 'l', "7" }, //$NON-NLS-2$
1887                { new Date(1147327147578L), 'l', "1" }, //$NON-NLS-2$
1888                { paris, 'l', "12" }, //$NON-NLS-2$
1889                { china, 'l', "12" }, //$NON-NLS-2$
1890                { 0L, 'm', "01" }, //$NON-NLS-2$
1891                { Long.MAX_VALUE, 'm', "08" }, //$NON-NLS-2$
1892                { -1000L, 'm', "01" }, //$NON-NLS-2$
1893                { new Date(1147327147578L), 'm', "05" }, //$NON-NLS-2$
1894                { paris, 'm', "05" }, //$NON-NLS-2$
1895                { china, 'm', "05" }, //$NON-NLS-2$
1896                { 0L, 'p', "am" }, //$NON-NLS-2$
1897                { Long.MAX_VALUE, 'p', "pm" }, //$NON-NLS-2$
1898                { -1000L, 'p', "am" }, //$NON-NLS-2$
1899                { new Date(1147327147578L), 'p', "pm" }, //$NON-NLS-2$
1900                { paris, 'p', "pm" }, //$NON-NLS-2$
1901                { china, 'p', "pm" }, //$NON-NLS-2$
1902                { 0L, 'r', "08:00:00 AM" }, //$NON-NLS-2$
1903                { Long.MAX_VALUE, 'r', "03:18:47 PM" }, //$NON-NLS-2$
1904                { -1000L, 'r', "07:59:59 AM" }, //$NON-NLS-2$
1905                { new Date(1147327147578L), 'r', "01:59:07 PM" }, //$NON-NLS-2$
1906                { paris, 'r', "12:00:00 PM" }, //$NON-NLS-2$
1907                { china, 'r', "12:00:00 PM" }, //$NON-NLS-2$
1908                { 0L, 's', "0" }, //$NON-NLS-2$
1909                { Long.MAX_VALUE, 's', "9223372036854775" }, //$NON-NLS-2$
1910                { -1000L, 's', "-1" }, //$NON-NLS-2$
1911                { new Date(1147327147578L), 's', "1147327147" }, //$NON-NLS-2$
1912                { paris, 's', "1147082400" }, //$NON-NLS-2$
1913                { china, 's', "1147118400" }, //$NON-NLS-2$
1914                { 0L, 'y', "70" }, //$NON-NLS-2$
1915                { Long.MAX_VALUE, 'y', "94" }, //$NON-NLS-2$
1916                { -1000L, 'y', "70" }, //$NON-NLS-2$
1917                { new Date(1147327147578L), 'y', "06" }, //$NON-NLS-2$
1918                { paris, 'y', "06" }, //$NON-NLS-2$
1919                { china, 'y', "06" }, //$NON-NLS-2$
1920                { 0L, 'z', "+0800" }, //$NON-NLS-2$
1921                { Long.MAX_VALUE, 'z', "+0800" }, //$NON-NLS-2$
1922                { -1000L, 'z', "+0800" }, //$NON-NLS-2$
1923                { new Date(1147327147578L), 'z', "+0800" }, //$NON-NLS-2$
1924                { paris, 'z', "+0100" }, //$NON-NLS-2$
1925                { china, 'z', "-0800" }, //$NON-NLS-2$
1926
1927        };
1928
1929        final Object[][] lowerCaseJapanTriple = {
1930                { 0L, 'a', "\u6728" }, //$NON-NLS-2$
1931                { Long.MAX_VALUE, 'a', "\u65e5" }, //$NON-NLS-2$
1932                { -1000L, 'a', "\u6728" }, //$NON-NLS-2$
1933                { new Date(1147327147578L), 'a', "\u6728" }, //$NON-NLS-2$
1934                { paris, 'a', "\u6708" }, //$NON-NLS-2$
1935                { china, 'a', "\u6708" }, //$NON-NLS-2$
1936                { 0L, 'b', "1\u6708" }, //$NON-NLS-2$
1937                { Long.MAX_VALUE, 'b', "8\u6708" }, //$NON-NLS-2$
1938                { -1000L, 'b', "1\u6708" }, //$NON-NLS-2$
1939                { new Date(1147327147578L), 'b', "5\u6708" }, //$NON-NLS-2$
1940                { paris, 'b', "5\u6708" }, //$NON-NLS-2$
1941                { china, 'b', "5\u6708" }, //$NON-NLS-2$
1942                { 0L, 'c', "\u6728 1\u6708 01 08:00:00 GMT+08:00 1970" }, //$NON-NLS-2$
1943                { Long.MAX_VALUE, 'c', "\u65e5 8\u6708 17 15:18:47 GMT+08:00 292278994" }, //$NON-NLS-2$
1944                { -1000L, 'c', "\u6728 1\u6708 01 07:59:59 GMT+08:00 1970" }, //$NON-NLS-2$
1945                { new Date(1147327147578L), 'c', "\u6728 5\u6708 11 13:59:07 GMT+08:00 2006" }, //$NON-NLS-2$
1946                { paris, 'c', "\u6708 5\u6708 08 12:00:00 GMT+02:00 2006" }, //$NON-NLS-2$
1947                { china, 'c', "\u6708 5\u6708 08 12:00:00 GMT-08:00 2006" }, //$NON-NLS-2$
1948                { 0L, 'd', "01" }, //$NON-NLS-2$
1949                { Long.MAX_VALUE, 'd', "17" }, //$NON-NLS-2$
1950                { -1000L, 'd', "01" }, //$NON-NLS-2$
1951                { new Date(1147327147578L), 'd', "11" }, //$NON-NLS-2$
1952                { paris, 'd', "08" }, //$NON-NLS-2$
1953                { china, 'd', "08" }, //$NON-NLS-2$
1954                { 0L, 'e', "1" }, //$NON-NLS-2$
1955                { Long.MAX_VALUE, 'e', "17" }, //$NON-NLS-2$
1956                { -1000L, 'e', "1" }, //$NON-NLS-2$
1957                { new Date(1147327147578L), 'e', "11" }, //$NON-NLS-2$
1958                { paris, 'e', "8" }, //$NON-NLS-2$
1959                { china, 'e', "8" }, //$NON-NLS-2$
1960                { 0L, 'h', "1\u6708" }, //$NON-NLS-2$
1961                { Long.MAX_VALUE, 'h', "8\u6708" }, //$NON-NLS-2$
1962                { -1000L, 'h', "1\u6708" }, //$NON-NLS-2$
1963                { new Date(1147327147578L), 'h', "5\u6708" }, //$NON-NLS-2$
1964                { paris, 'h', "5\u6708" }, //$NON-NLS-2$
1965                { china, 'h', "5\u6708" }, //$NON-NLS-2$
1966                { 0L, 'j', "001" }, //$NON-NLS-2$
1967                { Long.MAX_VALUE, 'j', "229" }, //$NON-NLS-2$
1968                { -1000L, 'j', "001" }, //$NON-NLS-2$
1969                { new Date(1147327147578L), 'j', "131" }, //$NON-NLS-2$
1970                { paris, 'j', "128" }, //$NON-NLS-2$
1971                { china, 'j', "128" }, //$NON-NLS-2$
1972                { 0L, 'k', "8" }, //$NON-NLS-2$
1973                { Long.MAX_VALUE, 'k', "15" }, //$NON-NLS-2$
1974                { -1000L, 'k', "7" }, //$NON-NLS-2$
1975                { new Date(1147327147578L), 'k', "13" }, //$NON-NLS-2$
1976                { paris, 'k', "12" }, //$NON-NLS-2$
1977                { china, 'k', "12" }, //$NON-NLS-2$
1978                { 0L, 'l', "8" }, //$NON-NLS-2$
1979                { Long.MAX_VALUE, 'l', "3" }, //$NON-NLS-2$
1980                { -1000L, 'l', "7" }, //$NON-NLS-2$
1981                { new Date(1147327147578L), 'l', "1" }, //$NON-NLS-2$
1982                { paris, 'l', "12" }, //$NON-NLS-2$
1983                { china, 'l', "12" }, //$NON-NLS-2$
1984                { 0L, 'm', "01" }, //$NON-NLS-2$
1985                { Long.MAX_VALUE, 'm', "08" }, //$NON-NLS-2$
1986                { -1000L, 'm', "01" }, //$NON-NLS-2$
1987                { new Date(1147327147578L), 'm', "05" }, //$NON-NLS-2$
1988                { paris, 'm', "05" }, //$NON-NLS-2$
1989                { china, 'm', "05" }, //$NON-NLS-2$
1990                { 0L, 'p', "\u5348\u524d" }, //$NON-NLS-2$
1991                { Long.MAX_VALUE, 'p', "\u5348\u5f8c" }, //$NON-NLS-2$
1992                { -1000L, 'p', "\u5348\u524d" }, //$NON-NLS-2$
1993                { new Date(1147327147578L), 'p', "\u5348\u5f8c" }, //$NON-NLS-2$
1994                { paris, 'p', "\u5348\u5f8c" }, //$NON-NLS-2$
1995                { china, 'p', "\u5348\u5f8c" }, //$NON-NLS-2$
1996                { 0L, 'r', "08:00:00 \u5348\u524d" }, //$NON-NLS-2$
1997                { Long.MAX_VALUE, 'r', "03:18:47 \u5348\u5f8c" }, //$NON-NLS-2$
1998                { -1000L, 'r', "07:59:59 \u5348\u524d" }, //$NON-NLS-2$
1999                { new Date(1147327147578L), 'r', "01:59:07 \u5348\u5f8c" }, //$NON-NLS-2$
2000                { paris, 'r', "12:00:00 \u5348\u5f8c" }, //$NON-NLS-2$
2001                { china, 'r', "12:00:00 \u5348\u5f8c" }, //$NON-NLS-2$
2002                { 0L, 's', "0" }, //$NON-NLS-2$
2003                { Long.MAX_VALUE, 's', "9223372036854775" }, //$NON-NLS-2$
2004                { -1000L, 's', "-1" }, //$NON-NLS-2$
2005                { new Date(1147327147578L), 's', "1147327147" }, //$NON-NLS-2$
2006                { paris, 's', "1147082400" }, //$NON-NLS-2$
2007                { china, 's', "1147118400" }, //$NON-NLS-2$
2008                { 0L, 'y', "70" }, //$NON-NLS-2$
2009                { Long.MAX_VALUE, 'y', "94" }, //$NON-NLS-2$
2010                { -1000L, 'y', "70" }, //$NON-NLS-2$
2011                { new Date(1147327147578L), 'y', "06" }, //$NON-NLS-2$
2012                { paris, 'y', "06" }, //$NON-NLS-2$
2013                { china, 'y', "06" }, //$NON-NLS-2$
2014                { 0L, 'z', "+0800" }, //$NON-NLS-2$
2015                { Long.MAX_VALUE, 'z', "+0800" }, //$NON-NLS-2$
2016                { -1000L, 'z', "+0800" }, //$NON-NLS-2$
2017                { new Date(1147327147578L), 'z', "+0800" }, //$NON-NLS-2$
2018                { paris, 'z', "+0100" }, //$NON-NLS-2$
2019                { china, 'z', "-0800" }, //$NON-NLS-2$
2020        };
2021
2022        final int input = 0;
2023        final int pattern = 1;
2024        final int output = 2;
2025        for (int i = 0; i < 90; i++) {
2026            // go through legal conversion
2027            String formatSpecifier = "%t" + lowerCaseGermanTriple[i][pattern]; //$NON-NLS-2$
2028            String formatSpecifierUpper = "%T" + lowerCaseGermanTriple[i][pattern]; //$NON-NLS-2$
2029            // test '%t'
2030            f = new Formatter(Locale.GERMAN);
2031            f.format(formatSpecifier, lowerCaseGermanTriple[i][input]);
2032            assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
2033                    + " Argument: " + lowerCaseGermanTriple[i][input], //$NON-NLS-2$
2034                    lowerCaseGermanTriple[i][output], f.toString());
2035
2036            f = new Formatter(Locale.GERMAN);
2037            f.format(Locale.FRANCE, formatSpecifier, lowerCaseFranceTriple[i][input]);
2038            assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
2039                    + " Argument: " + lowerCaseFranceTriple[i][input], //$NON-NLS-2$
2040                    lowerCaseFranceTriple[i][output], f.toString());
2041
2042            f = new Formatter(Locale.GERMAN);
2043            f.format(Locale.JAPAN, formatSpecifier, lowerCaseJapanTriple[i][input]);
2044            assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
2045                    + " Argument: " + lowerCaseJapanTriple[i][input], //$NON-NLS-2$
2046                    lowerCaseJapanTriple[i][output], f.toString());
2047
2048            // test '%T'
2049            f = new Formatter(Locale.GERMAN);
2050            f.format(formatSpecifierUpper, lowerCaseGermanTriple[i][input]);
2051            assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
2052                    + " Argument: " + lowerCaseGermanTriple[i][input], //$NON-NLS-2$
2053                    ((String) lowerCaseGermanTriple[i][output])
2054                            .toUpperCase(Locale.US), f.toString());
2055
2056            f = new Formatter(Locale.GERMAN);
2057            f.format(Locale.FRANCE, formatSpecifierUpper, lowerCaseFranceTriple[i][input]);
2058            assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
2059                    + " Argument: " + lowerCaseFranceTriple[i][input], //$NON-NLS-2$
2060                    ((String) lowerCaseFranceTriple[i][output])
2061                            .toUpperCase(Locale.US), f.toString());
2062
2063            f = new Formatter(Locale.GERMAN);
2064            f.format(Locale.JAPAN, formatSpecifierUpper, lowerCaseJapanTriple[i][input]);
2065            assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
2066                    + " Argument: " + lowerCaseJapanTriple[i][input], //$NON-NLS-2$
2067                    ((String) lowerCaseJapanTriple[i][output])
2068                            .toUpperCase(Locale.US), f.toString());
2069        }
2070
2071        final Object[][] upperCaseGermanTriple = {
2072                { 0L, 'A', "Donnerstag" }, //$NON-NLS-2$
2073                { Long.MAX_VALUE, 'A', "Sonntag" }, //$NON-NLS-2$
2074                { -1000L, 'A', "Donnerstag" }, //$NON-NLS-2$
2075                { new Date(1147327147578L), 'A', "Donnerstag" }, //$NON-NLS-2$
2076                { paris, 'A', "Montag" }, //$NON-NLS-2$
2077                { china, 'A', "Montag" }, //$NON-NLS-2$
2078                { 0L, 'B', "Januar" }, //$NON-NLS-2$
2079                { Long.MAX_VALUE, 'B', "August" }, //$NON-NLS-2$
2080                { -1000L, 'B', "Januar" }, //$NON-NLS-2$
2081                { new Date(1147327147578L), 'B', "Mai" }, //$NON-NLS-2$
2082                { paris, 'B', "Mai" }, //$NON-NLS-2$
2083                { china, 'B', "Mai" }, //$NON-NLS-2$
2084                { 0L, 'C', "19" }, //$NON-NLS-2$
2085                { Long.MAX_VALUE, 'C', "2922789" }, //$NON-NLS-2$
2086                { -1000L, 'C', "19" }, //$NON-NLS-2$
2087                { new Date(1147327147578L), 'C', "20" }, //$NON-NLS-2$
2088                { paris, 'C', "20" }, //$NON-NLS-2$
2089                { china, 'C', "20" }, //$NON-NLS-2$
2090                { 0L, 'D', "01/01/70" }, //$NON-NLS-2$
2091                { Long.MAX_VALUE, 'D', "08/17/94" }, //$NON-NLS-2$
2092                { -1000L, 'D', "01/01/70" }, //$NON-NLS-2$
2093                { new Date(1147327147578L), 'D', "05/11/06" }, //$NON-NLS-2$
2094                { paris, 'D', "05/08/06" }, //$NON-NLS-2$
2095                { china, 'D', "05/08/06" }, //$NON-NLS-2$
2096                { 0L, 'F', "1970-01-01" }, //$NON-NLS-2$
2097                { Long.MAX_VALUE, 'F', "292278994-08-17" }, //$NON-NLS-2$
2098                { -1000L, 'F', "1970-01-01" }, //$NON-NLS-2$
2099                { new Date(1147327147578L), 'F', "2006-05-11" }, //$NON-NLS-2$
2100                { paris, 'F', "2006-05-08" }, //$NON-NLS-2$
2101                { china, 'F', "2006-05-08" }, //$NON-NLS-2$
2102                { 0L, 'H', "08" }, //$NON-NLS-2$
2103                { Long.MAX_VALUE, 'H', "15" }, //$NON-NLS-2$
2104                { -1000L, 'H', "07" }, //$NON-NLS-2$
2105                { new Date(1147327147578L), 'H', "13" }, //$NON-NLS-2$
2106                { paris, 'H', "12" }, //$NON-NLS-2$
2107                { china, 'H', "12" }, //$NON-NLS-2$
2108                { 0L, 'I', "08" }, //$NON-NLS-2$
2109                { Long.MAX_VALUE, 'I', "03" }, //$NON-NLS-2$
2110                { -1000L, 'I', "07" }, //$NON-NLS-2$
2111                { new Date(1147327147578L), 'I', "01" }, //$NON-NLS-2$
2112                { paris, 'I', "12" }, //$NON-NLS-2$
2113                { china, 'I', "12" }, //$NON-NLS-2$
2114                { 0L, 'L', "000" }, //$NON-NLS-2$
2115                { Long.MAX_VALUE, 'L', "807" }, //$NON-NLS-2$
2116                { -1000L, 'L', "000" }, //$NON-NLS-2$
2117                { new Date(1147327147578L), 'L', "578" }, //$NON-NLS-2$
2118                { paris, 'L', "453" }, //$NON-NLS-2$
2119                { china, 'L', "609" }, //$NON-NLS-2$
2120                { 0L, 'M', "00" }, //$NON-NLS-2$
2121                { Long.MAX_VALUE, 'M', "18" }, //$NON-NLS-2$
2122                { -1000L, 'M', "59" }, //$NON-NLS-2$
2123                { new Date(1147327147578L), 'M', "59" }, //$NON-NLS-2$
2124                { paris, 'M', "00" }, //$NON-NLS-2$
2125                { china, 'M', "00" }, //$NON-NLS-2$
2126                { 0L, 'N', "000000000" }, //$NON-NLS-2$
2127                { Long.MAX_VALUE, 'N', "807000000" }, //$NON-NLS-2$
2128                { -1000L, 'N', "000000000" }, //$NON-NLS-2$
2129                { new Date(1147327147578L), 'N', "578000000" }, //$NON-NLS-2$
2130                { paris, 'N', "609000000" }, //$NON-NLS-2$
2131                { china, 'N', "609000000" }, //$NON-NLS-2$
2132                { 0L, 'Q', "0" }, //$NON-NLS-2$
2133                { Long.MAX_VALUE, 'Q', "9223372036854775807" }, //$NON-NLS-2$
2134                { -1000L, 'Q', "-1000" }, //$NON-NLS-2$
2135                { new Date(1147327147578L), 'Q', "1147327147578" }, //$NON-NLS-2$
2136                { paris, 'Q', "1147082400453" }, //$NON-NLS-2$
2137                { china, 'Q', "1147118400609" }, //$NON-NLS-2$
2138                { 0L, 'R', "08:00" }, //$NON-NLS-2$
2139                { Long.MAX_VALUE, 'R', "15:18" }, //$NON-NLS-2$
2140                { -1000L, 'R', "07:59" }, //$NON-NLS-2$
2141                { new Date(1147327147578L), 'R', "13:59" }, //$NON-NLS-2$
2142                { paris, 'R', "12:00" }, //$NON-NLS-2$
2143                { china, 'R', "12:00" }, //$NON-NLS-2$
2144                { 0L, 'S', "00" }, //$NON-NLS-2$
2145                { Long.MAX_VALUE, 'S', "47" }, //$NON-NLS-2$
2146                { -1000L, 'S', "59" }, //$NON-NLS-2$
2147                { new Date(1147327147578L), 'S', "07" }, //$NON-NLS-2$
2148                { paris, 'S', "00" }, //$NON-NLS-2$
2149                { china, 'S', "00" }, //$NON-NLS-2$
2150                { 0L, 'T', "08:00:00" }, //$NON-NLS-2$
2151                { Long.MAX_VALUE, 'T', "15:18:47" }, //$NON-NLS-2$
2152                { -1000L, 'T', "07:59:59" }, //$NON-NLS-2$
2153                { new Date(1147327147578L), 'T', "13:59:07" }, //$NON-NLS-2$
2154                { paris, 'T', "12:00:00" }, //$NON-NLS-2$
2155                { china, 'T', "12:00:00" }, //$NON-NLS-2$
2156                { 0L, 'Y', "1970" }, //$NON-NLS-2$
2157                { Long.MAX_VALUE, 'Y', "292278994" }, //$NON-NLS-2$
2158                { -1000L, 'Y', "1970" }, //$NON-NLS-2$
2159                { new Date(1147327147578L), 'Y', "2006" }, //$NON-NLS-2$
2160                { paris, 'Y', "2006" }, //$NON-NLS-2$
2161                { china, 'Y', "2006" }, //$NON-NLS-2$
2162                { 0L, 'Z', "CST" }, //$NON-NLS-2$
2163                { Long.MAX_VALUE, 'Z', "CST" }, //$NON-NLS-2$
2164                { -1000L, 'Z', "CST" }, //$NON-NLS-2$
2165                { new Date(1147327147578L), 'Z', "CST" }, //$NON-NLS-2$
2166                { paris, 'Z', "CEST" }, //$NON-NLS-2$
2167                { china, 'Z', "GMT-08:00" }, //$NON-NLS-2$
2168
2169        };
2170
2171        final Object[][] upperCaseFranceTriple = {
2172                { 0L, 'A', "jeudi" }, //$NON-NLS-2$
2173                { Long.MAX_VALUE, 'A', "dimanche" }, //$NON-NLS-2$
2174                { -1000L, 'A', "jeudi" }, //$NON-NLS-2$
2175                { new Date(1147327147578L), 'A', "jeudi" }, //$NON-NLS-2$
2176                { paris, 'A', "lundi" }, //$NON-NLS-2$
2177                { china, 'A', "lundi" }, //$NON-NLS-2$
2178                { 0L, 'B', "janvier" }, //$NON-NLS-2$
2179                { Long.MAX_VALUE, 'B', "ao\u00fbt" }, //$NON-NLS-2$
2180                { -1000L, 'B', "janvier" }, //$NON-NLS-2$
2181                { new Date(1147327147578L), 'B', "mai" }, //$NON-NLS-2$
2182                { paris, 'B', "mai" }, //$NON-NLS-2$
2183                { china, 'B', "mai" }, //$NON-NLS-2$
2184                { 0L, 'C', "19" }, //$NON-NLS-2$
2185                { Long.MAX_VALUE, 'C', "2922789" }, //$NON-NLS-2$
2186                { -1000L, 'C', "19" }, //$NON-NLS-2$
2187                { new Date(1147327147578L), 'C', "20" }, //$NON-NLS-2$
2188                { paris, 'C', "20" }, //$NON-NLS-2$
2189                { china, 'C', "20" }, //$NON-NLS-2$
2190                { 0L, 'D', "01/01/70" }, //$NON-NLS-2$
2191                { Long.MAX_VALUE, 'D', "08/17/94" }, //$NON-NLS-2$
2192                { -1000L, 'D', "01/01/70" }, //$NON-NLS-2$
2193                { new Date(1147327147578L), 'D', "05/11/06" }, //$NON-NLS-2$
2194                { paris, 'D', "05/08/06" }, //$NON-NLS-2$
2195                { china, 'D', "05/08/06" }, //$NON-NLS-2$
2196                { 0L, 'F', "1970-01-01" }, //$NON-NLS-2$
2197                { Long.MAX_VALUE, 'F', "292278994-08-17" }, //$NON-NLS-2$
2198                { -1000L, 'F', "1970-01-01" }, //$NON-NLS-2$
2199                { new Date(1147327147578L), 'F', "2006-05-11" }, //$NON-NLS-2$
2200                { paris, 'F', "2006-05-08" }, //$NON-NLS-2$
2201                { china, 'F', "2006-05-08" }, //$NON-NLS-2$
2202                { 0L, 'H', "08" }, //$NON-NLS-2$
2203                { Long.MAX_VALUE, 'H', "15" }, //$NON-NLS-2$
2204                { -1000L, 'H', "07" }, //$NON-NLS-2$
2205                { new Date(1147327147578L), 'H', "13" }, //$NON-NLS-2$
2206                { paris, 'H', "12" }, //$NON-NLS-2$
2207                { china, 'H', "12" }, //$NON-NLS-2$
2208                { 0L, 'I', "08" }, //$NON-NLS-2$
2209                { Long.MAX_VALUE, 'I', "03" }, //$NON-NLS-2$
2210                { -1000L, 'I', "07" }, //$NON-NLS-2$
2211                { new Date(1147327147578L), 'I', "01" }, //$NON-NLS-2$
2212                { paris, 'I', "12" }, //$NON-NLS-2$
2213                { china, 'I', "12" }, //$NON-NLS-2$
2214                { 0L, 'L', "000" }, //$NON-NLS-2$
2215                { Long.MAX_VALUE, 'L', "807" }, //$NON-NLS-2$
2216                { -1000L, 'L', "000" }, //$NON-NLS-2$
2217                { new Date(1147327147578L), 'L', "578" }, //$NON-NLS-2$
2218                { paris, 'L', "453" }, //$NON-NLS-2$
2219                { china, 'L', "609" }, //$NON-NLS-2$
2220                { 0L, 'M', "00" }, //$NON-NLS-2$
2221                { Long.MAX_VALUE, 'M', "18" }, //$NON-NLS-2$
2222                { -1000L, 'M', "59" }, //$NON-NLS-2$
2223                { new Date(1147327147578L), 'M', "59" }, //$NON-NLS-2$
2224                { paris, 'M', "00" }, //$NON-NLS-2$
2225                { china, 'M', "00" }, //$NON-NLS-2$
2226                { 0L, 'N', "000000000" }, //$NON-NLS-2$
2227                { Long.MAX_VALUE, 'N', "807000000" }, //$NON-NLS-2$
2228                { -1000L, 'N', "000000000" }, //$NON-NLS-2$
2229                { new Date(1147327147578L), 'N', "578000000" }, //$NON-NLS-2$
2230                { paris, 'N', "453000000" }, //$NON-NLS-2$
2231                { china, 'N', "468000000" }, //$NON-NLS-2$
2232                { 0L, 'Q', "0" }, //$NON-NLS-2$
2233                { Long.MAX_VALUE, 'Q', "9223372036854775807" }, //$NON-NLS-2$
2234                { -1000L, 'Q', "-1000" }, //$NON-NLS-2$
2235                { new Date(1147327147578L), 'Q', "1147327147578" }, //$NON-NLS-2$
2236                { paris, 'Q', "1147082400453" }, //$NON-NLS-2$
2237                { china, 'Q', "1147118400609" }, //$NON-NLS-2$
2238                { 0L, 'R', "08:00" }, //$NON-NLS-2$
2239                { Long.MAX_VALUE, 'R', "15:18" }, //$NON-NLS-2$
2240                { -1000L, 'R', "07:59" }, //$NON-NLS-2$
2241                { new Date(1147327147578L), 'R', "13:59" }, //$NON-NLS-2$
2242                { paris, 'R', "12:00" }, //$NON-NLS-2$
2243                { china, 'R', "12:00" }, //$NON-NLS-2$
2244                { 0L, 'S', "00" }, //$NON-NLS-2$
2245                { Long.MAX_VALUE, 'S', "47" }, //$NON-NLS-2$
2246                { -1000L, 'S', "59" }, //$NON-NLS-2$
2247                { new Date(1147327147578L), 'S', "07" }, //$NON-NLS-2$
2248                { paris, 'S', "00" }, //$NON-NLS-2$
2249                { china, 'S', "00" }, //$NON-NLS-2$
2250                { 0L, 'T', "08:00:00" }, //$NON-NLS-2$
2251                { Long.MAX_VALUE, 'T', "15:18:47" }, //$NON-NLS-2$
2252                { -1000L, 'T', "07:59:59" }, //$NON-NLS-2$
2253                { new Date(1147327147578L), 'T', "13:59:07" }, //$NON-NLS-2$
2254                { paris, 'T', "12:00:00" }, //$NON-NLS-2$
2255                { china, 'T', "12:00:00" }, //$NON-NLS-2$
2256                { 0L, 'Y', "1970" }, //$NON-NLS-2$
2257                { Long.MAX_VALUE, 'Y', "292278994" }, //$NON-NLS-2$
2258                { -1000L, 'Y', "1970" }, //$NON-NLS-2$
2259                { new Date(1147327147578L), 'Y', "2006" }, //$NON-NLS-2$
2260                { paris, 'Y', "2006" }, //$NON-NLS-2$
2261                { china, 'Y', "2006" }, //$NON-NLS-2$
2262                { 0L, 'Z', "CST" }, //$NON-NLS-2$
2263                { Long.MAX_VALUE, 'Z', "CST" }, //$NON-NLS-2$
2264                { -1000L, 'Z', "CST" }, //$NON-NLS-2$
2265                { new Date(1147327147578L), 'Z', "CST" }, //$NON-NLS-2$
2266                { paris, 'Z', "CEST" }, //$NON-NLS-2$
2267                { china, 'Z', "GMT-08:00" }, //$NON-NLS-2$
2268
2269        };
2270
2271        final Object[][] upperCaseJapanTriple = {
2272                { 0L, 'A', "\u6728\u66dc\u65e5" }, //$NON-NLS-2$
2273                { Long.MAX_VALUE, 'A', "\u65e5\u66dc\u65e5" }, //$NON-NLS-2$
2274                { -1000L, 'A', "\u6728\u66dc\u65e5" }, //$NON-NLS-2$
2275                { new Date(1147327147578L), 'A', "\u6728\u66dc\u65e5" }, //$NON-NLS-2$
2276                { paris, 'A', "\u6708\u66dc\u65e5" }, //$NON-NLS-2$
2277                { china, 'A', "\u6708\u66dc\u65e5" }, //$NON-NLS-2$
2278                { 0L, 'B', "1\u6708" }, //$NON-NLS-2$
2279                { Long.MAX_VALUE, 'B', "8\u6708" }, //$NON-NLS-2$
2280                { -1000L, 'B', "1\u6708" }, //$NON-NLS-2$
2281                { new Date(1147327147578L), 'B', "5\u6708" }, //$NON-NLS-2$
2282                { paris, 'B', "5\u6708" }, //$NON-NLS-2$
2283                { china, 'B', "5\u6708" }, //$NON-NLS-2$
2284                { 0L, 'C', "19" }, //$NON-NLS-2$
2285                { Long.MAX_VALUE, 'C', "2922789" }, //$NON-NLS-2$
2286                { -1000L, 'C', "19" }, //$NON-NLS-2$
2287                { new Date(1147327147578L), 'C', "20" }, //$NON-NLS-2$
2288                { paris, 'C', "20" }, //$NON-NLS-2$
2289                { china, 'C', "20" }, //$NON-NLS-2$
2290                { 0L, 'D', "01/01/70" }, //$NON-NLS-2$
2291                { Long.MAX_VALUE, 'D', "08/17/94" }, //$NON-NLS-2$
2292                { -1000L, 'D', "01/01/70" }, //$NON-NLS-2$
2293                { new Date(1147327147578L), 'D', "05/11/06" }, //$NON-NLS-2$
2294                { paris, 'D', "05/08/06" }, //$NON-NLS-2$
2295                { china, 'D', "05/08/06" }, //$NON-NLS-2$
2296                { 0L, 'F', "1970-01-01" }, //$NON-NLS-2$
2297                { Long.MAX_VALUE, 'F', "292278994-08-17" }, //$NON-NLS-2$
2298                { -1000L, 'F', "1970-01-01" }, //$NON-NLS-2$
2299                { new Date(1147327147578L), 'F', "2006-05-11" }, //$NON-NLS-2$
2300                { paris, 'F', "2006-05-08" }, //$NON-NLS-2$
2301                { china, 'F', "2006-05-08" }, //$NON-NLS-2$
2302                { 0L, 'H', "08" }, //$NON-NLS-2$
2303                { Long.MAX_VALUE, 'H', "15" }, //$NON-NLS-2$
2304                { -1000L, 'H', "07" }, //$NON-NLS-2$
2305                { new Date(1147327147578L), 'H', "13" }, //$NON-NLS-2$
2306                { paris, 'H', "12" }, //$NON-NLS-2$
2307                { china, 'H', "12" }, //$NON-NLS-2$
2308                { 0L, 'I', "08" }, //$NON-NLS-2$
2309                { Long.MAX_VALUE, 'I', "03" }, //$NON-NLS-2$
2310                { -1000L, 'I', "07" }, //$NON-NLS-2$
2311                { new Date(1147327147578L), 'I', "01" }, //$NON-NLS-2$
2312                { paris, 'I', "12" }, //$NON-NLS-2$
2313                { china, 'I', "12" }, //$NON-NLS-2$
2314                { 0L, 'L', "000" }, //$NON-NLS-2$
2315                { Long.MAX_VALUE, 'L', "807" }, //$NON-NLS-2$
2316                { -1000L, 'L', "000" }, //$NON-NLS-2$
2317                { new Date(1147327147578L), 'L', "578" }, //$NON-NLS-2$
2318                { paris, 'L', "453" }, //$NON-NLS-2$
2319                { china, 'L', "609" }, //$NON-NLS-2$
2320                { 0L, 'M', "00" }, //$NON-NLS-2$
2321                { Long.MAX_VALUE, 'M', "18" }, //$NON-NLS-2$
2322                { -1000L, 'M', "59" }, //$NON-NLS-2$
2323                { new Date(1147327147578L), 'M', "59" }, //$NON-NLS-2$
2324                { paris, 'M', "00" }, //$NON-NLS-2$
2325                { china, 'M', "00" }, //$NON-NLS-2$
2326                { 0L, 'N', "000000000" }, //$NON-NLS-2$
2327                { Long.MAX_VALUE, 'N', "807000000" }, //$NON-NLS-2$
2328                { -1000L, 'N', "000000000" }, //$NON-NLS-2$
2329                { new Date(1147327147578L), 'N', "578000000" }, //$NON-NLS-2$
2330                { paris, 'N', "453000000" }, //$NON-NLS-2$
2331                { china, 'N', "468000000" }, //$NON-NLS-2$
2332                { 0L, 'Q', "0" }, //$NON-NLS-2$
2333                { Long.MAX_VALUE, 'Q', "9223372036854775807" }, //$NON-NLS-2$
2334                { -1000L, 'Q', "-1000" }, //$NON-NLS-2$
2335                { new Date(1147327147578L), 'Q', "1147327147578" }, //$NON-NLS-2$
2336                { paris, 'Q', "1147082400453" }, //$NON-NLS-2$
2337                { china, 'Q', "1147118400609" }, //$NON-NLS-2$
2338                { 0L, 'R', "08:00" }, //$NON-NLS-2$
2339                { Long.MAX_VALUE, 'R', "15:18" }, //$NON-NLS-2$
2340                { -1000L, 'R', "07:59" }, //$NON-NLS-2$
2341                { new Date(1147327147578L), 'R', "13:59" }, //$NON-NLS-2$
2342                { paris, 'R', "12:00" }, //$NON-NLS-2$
2343                { china, 'R', "12:00" }, //$NON-NLS-2$
2344                { 0L, 'S', "00" }, //$NON-NLS-2$
2345                { Long.MAX_VALUE, 'S', "47" }, //$NON-NLS-2$
2346                { -1000L, 'S', "59" }, //$NON-NLS-2$
2347                { new Date(1147327147578L), 'S', "07" }, //$NON-NLS-2$
2348                { paris, 'S', "00" }, //$NON-NLS-2$
2349                { china, 'S', "00" }, //$NON-NLS-2$
2350                { 0L, 'T', "08:00:00" }, //$NON-NLS-2$
2351                { Long.MAX_VALUE, 'T', "15:18:47" }, //$NON-NLS-2$
2352                { -1000L, 'T', "07:59:59" }, //$NON-NLS-2$
2353                { new Date(1147327147578L), 'T', "13:59:07" }, //$NON-NLS-2$
2354                { paris, 'T', "12:00:00" }, //$NON-NLS-2$
2355                { china, 'T', "12:00:00" }, //$NON-NLS-2$
2356                { 0L, 'Y', "1970" }, //$NON-NLS-2$
2357                { Long.MAX_VALUE, 'Y', "292278994" }, //$NON-NLS-2$
2358                { -1000L, 'Y', "1970" }, //$NON-NLS-2$
2359                { new Date(1147327147578L), 'Y', "2006" }, //$NON-NLS-2$
2360                { paris, 'Y', "2006" }, //$NON-NLS-2$
2361                { china, 'Y', "2006" }, //$NON-NLS-2$
2362                { 0L, 'Z', "CST" }, //$NON-NLS-2$
2363                { Long.MAX_VALUE, 'Z', "CST" }, //$NON-NLS-2$
2364                { -1000L, 'Z', "CST" }, //$NON-NLS-2$
2365                { new Date(1147327147578L), 'Z', "CST" }, //$NON-NLS-2$
2366                { paris, 'Z', "CEST" }, //$NON-NLS-2$
2367                { china, 'Z', "GMT-08:00" }, //$NON-NLS-2$
2368        };
2369
2370
2371        for (int i = 0; i < 90; i++) {
2372            String formatSpecifier = "%t" + upperCaseGermanTriple[i][pattern]; //$NON-NLS-2$
2373            String formatSpecifierUpper = "%T" + upperCaseGermanTriple[i][pattern]; //$NON-NLS-2$
2374            if ((Character) upperCaseGermanTriple[i][pattern] == 'N') {
2375                // result can't be predicted on RI, so skip this test
2376                continue;
2377            }
2378            // test '%t'
2379            f = new Formatter(Locale.JAPAN);
2380            f.format(formatSpecifier, upperCaseJapanTriple[i][input]);
2381            assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
2382                    + " Argument: " + upperCaseJapanTriple[i][input], //$NON-NLS-2$
2383                    upperCaseJapanTriple[i][output], f.toString());
2384
2385            f = new Formatter(Locale.JAPAN);
2386            f.format(Locale.GERMAN, formatSpecifier, upperCaseGermanTriple[i][input]);
2387            assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
2388                    + " Argument: " + upperCaseGermanTriple[i][input], //$NON-NLS-2$
2389                    upperCaseGermanTriple[i][output], f.toString());
2390
2391            f = new Formatter(Locale.JAPAN);
2392            f.format(Locale.FRANCE, formatSpecifier, upperCaseFranceTriple[i][input]);
2393            assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
2394                    + " Argument: " + upperCaseFranceTriple[i][input], //$NON-NLS-2$
2395                    upperCaseFranceTriple[i][output], f.toString());
2396
2397            // test '%T'
2398            f = new Formatter(Locale.GERMAN);
2399            f.format(formatSpecifierUpper, upperCaseGermanTriple[i][input]);
2400            assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
2401                    + " Argument: " + upperCaseGermanTriple[i][input], //$NON-NLS-2$
2402                    ((String) upperCaseGermanTriple[i][output])
2403                            .toUpperCase(Locale.US), f.toString());
2404
2405            f = new Formatter(Locale.GERMAN);
2406            f.format(Locale.JAPAN, formatSpecifierUpper, upperCaseJapanTriple[i][input]);
2407            assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
2408                    + " Argument: " + upperCaseJapanTriple[i][input], //$NON-NLS-2$
2409                    ((String) upperCaseJapanTriple[i][output])
2410                            .toUpperCase(Locale.US), f.toString());
2411
2412            f = new Formatter(Locale.GERMAN);
2413            f.format(Locale.FRANCE, formatSpecifierUpper, upperCaseFranceTriple[i][input]);
2414            assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
2415                    + " Argument: " + upperCaseFranceTriple[i][input], //$NON-NLS-2$
2416                    ((String) upperCaseFranceTriple[i][output])
2417                            .toUpperCase(Locale.US), f.toString());
2418        }
2419
2420        f = new Formatter(Locale.US);
2421        f.format("%-10ta", now); //$NON-NLS-2$
2422        assertEquals("Thu       ", f.toString()); //$NON-NLS-2$
2423
2424        f = new Formatter(Locale.US);
2425        f.format("%10000000000000000000000000000000001ta", now); //$NON-NLS-2$
2426        assertEquals("Thu", f.toString().trim()); //$NON-NLS-2$
2427    }
2428
2429    /**
2430     * java.util.Formatter#format(String, Object...) for null argment for
2431     * Byte/Short/Integer/Long/BigInteger conversion
2432     */
2433    public void test_formatLjava_lang_String$Ljava_lang_Object_ByteShortIntegerLongNullConversion() {
2434
2435        Formatter f = new Formatter(Locale.FRANCE);
2436        f.format("%d%<o%<x%<5X", (Integer) null);
2437        assertEquals("nullnullnull NULL", f.toString());
2438
2439        f = new Formatter(Locale.GERMAN);
2440        f.format("%d%<#03o %<0#4x%<6X", (Long) null);
2441        assertEquals("nullnull null  NULL", f.toString());
2442
2443        f = new Formatter(Locale.GERMAN);
2444        f.format("%(+,07d%<o %<x%<6X", (Byte) null);
2445        assertEquals("   nullnull null  NULL", f.toString());
2446
2447        f = new Formatter(Locale.ITALY);
2448        f.format("%(+,07d%<o %<x%<0#6X", (Short) null);
2449        assertEquals("   nullnull null  NULL", f.toString());
2450
2451        f = new Formatter(Locale.GERMAN);
2452        f.format("%(+,-7d%<( o%<+(x %<( 06X", (BigInteger) null);
2453        assertEquals("null   nullnull   NULL", f.toString());
2454    }
2455
2456    /**
2457     * java.util.Formatter#format(String, Object...) for legal
2458     * BigInteger conversion type 'd'
2459     */
2460    public void test_formatLjava_lang_String$LBigInteger() {
2461        final Object[][] tripleD = {
2462                { new BigInteger("123456789012345678901234567890"), "%d", "123456789012345678901234567890" }, //$NON-NLS-2$
2463                { new BigInteger("123456789012345678901234567890"), "%10d", "123456789012345678901234567890" }, //$NON-NLS-2$
2464                { new BigInteger("123456789012345678901234567890"), "%-1d", "123456789012345678901234567890" }, //$NON-NLS-2$
2465                { new BigInteger("123456789012345678901234567890"), "%+d", "+123456789012345678901234567890" }, //$NON-NLS-2$
2466                { new BigInteger("123456789012345678901234567890"), "% d", " 123456789012345678901234567890" }, //$NON-NLS-2$
2467                { new BigInteger("123456789012345678901234567890"), "%,d", "123.456.789.012.345.678.901.234.567.890" }, //$NON-NLS-2$
2468                { new BigInteger("123456789012345678901234567890"), "%(d", "123456789012345678901234567890" }, //$NON-NLS-2$
2469                { new BigInteger("123456789012345678901234567890"), "%08d", "123456789012345678901234567890" }, //$NON-NLS-2$
2470                { new BigInteger("123456789012345678901234567890"), "%-+,(11d", "+123.456.789.012.345.678.901.234.567.890" }, //$NON-NLS-2$
2471                { new BigInteger("123456789012345678901234567890"), "%0 ,(11d", " 123.456.789.012.345.678.901.234.567.890" }, //$NON-NLS-2$
2472                { new BigInteger("-9876543210987654321098765432100000"), "%d", "-9876543210987654321098765432100000" }, //$NON-NLS-2$
2473                { new BigInteger("-9876543210987654321098765432100000"), "%10d", "-9876543210987654321098765432100000" }, //$NON-NLS-2$
2474                { new BigInteger("-9876543210987654321098765432100000"), "%-1d", "-9876543210987654321098765432100000" }, //$NON-NLS-2$
2475                { new BigInteger("-9876543210987654321098765432100000"), "%+d", "-9876543210987654321098765432100000" }, //$NON-NLS-2$
2476                { new BigInteger("-9876543210987654321098765432100000"), "% d", "-9876543210987654321098765432100000" }, //$NON-NLS-2$
2477                { new BigInteger("-9876543210987654321098765432100000"), "%,d", "-9.876.543.210.987.654.321.098.765.432.100.000" }, //$NON-NLS-2$
2478                { new BigInteger("-9876543210987654321098765432100000"), "%(d", "(9876543210987654321098765432100000)" }, //$NON-NLS-2$
2479                { new BigInteger("-9876543210987654321098765432100000"), "%08d", "-9876543210987654321098765432100000" }, //$NON-NLS-2$
2480                { new BigInteger("-9876543210987654321098765432100000"), "%-+,(11d", "(9.876.543.210.987.654.321.098.765.432.100.000)" }, //$NON-NLS-2$
2481                { new BigInteger("-9876543210987654321098765432100000"), "%0 ,(11d", "(9.876.543.210.987.654.321.098.765.432.100.000)" }, //$NON-NLS-2$
2482        };
2483
2484        final int input = 0;
2485        final int pattern = 1;
2486        final int output = 2;
2487        Formatter f;
2488        for (int i = 0; i < tripleD.length; i++) {
2489            f = new Formatter(Locale.GERMAN);
2490            f.format((String) tripleD[i][pattern],
2491                    tripleD[i][input]);
2492            assertEquals("triple[" + i + "]:" + tripleD[i][input] + ",pattern["
2493                    + i + "]:" + tripleD[i][pattern], tripleD[i][output], f
2494                    .toString());
2495
2496        }
2497
2498        final Object[][] tripleO = {
2499                { new BigInteger("123456789012345678901234567890"), "%o", "143564417755415637016711617605322" }, //$NON-NLS-2$
2500                { new BigInteger("123456789012345678901234567890"), "%-6o", "143564417755415637016711617605322" }, //$NON-NLS-2$
2501                { new BigInteger("123456789012345678901234567890"), "%08o", "143564417755415637016711617605322" }, //$NON-NLS-2$
2502                { new BigInteger("123456789012345678901234567890"), "%#o", "0143564417755415637016711617605322" }, //$NON-NLS-2$
2503                { new BigInteger("123456789012345678901234567890"), "%0#11o", "0143564417755415637016711617605322" }, //$NON-NLS-2$
2504                { new BigInteger("123456789012345678901234567890"), "%-#9o", "0143564417755415637016711617605322" }, //$NON-NLS-2$
2505                { new BigInteger("-9876543210987654321098765432100000"), "%o", "-36336340043453651353467270113157312240" }, //$NON-NLS-2$
2506                { new BigInteger("-9876543210987654321098765432100000"), "%-6o", "-36336340043453651353467270113157312240" }, //$NON-NLS-2$
2507                { new BigInteger("-9876543210987654321098765432100000"), "%08o", "-36336340043453651353467270113157312240" }, //$NON-NLS-2$
2508                { new BigInteger("-9876543210987654321098765432100000"), "%#o", "-036336340043453651353467270113157312240" }, //$NON-NLS-2$
2509                { new BigInteger("-9876543210987654321098765432100000"), "%0#11o", "-036336340043453651353467270113157312240" }, //$NON-NLS-2$
2510                { new BigInteger("-9876543210987654321098765432100000"), "%-#9o", "-036336340043453651353467270113157312240" }, //$NON-NLS-2$
2511        };
2512        for (int i = 0; i < tripleO.length; i++) {
2513            f = new Formatter(Locale.ITALY);
2514            f.format((String) tripleO[i][pattern],
2515                    tripleO[i][input]);
2516            assertEquals("triple[" + i + "]:" + tripleO[i][input] + ",pattern["
2517                    + i + "]:" + tripleO[i][pattern], tripleO[i][output], f
2518                    .toString());
2519
2520        }
2521
2522        final Object[][] tripleX = {
2523                { new BigInteger("123456789012345678901234567890"), "%x", "18ee90ff6c373e0ee4e3f0ad2" }, //$NON-NLS-2$
2524                { new BigInteger("123456789012345678901234567890"), "%-8x", "18ee90ff6c373e0ee4e3f0ad2" }, //$NON-NLS-2$
2525                { new BigInteger("123456789012345678901234567890"), "%06x", "18ee90ff6c373e0ee4e3f0ad2" }, //$NON-NLS-2$
2526                { new BigInteger("123456789012345678901234567890"), "%#x", "0x18ee90ff6c373e0ee4e3f0ad2" }, //$NON-NLS-2$
2527                { new BigInteger("123456789012345678901234567890"), "%0#12x", "0x18ee90ff6c373e0ee4e3f0ad2" }, //$NON-NLS-2$
2528                { new BigInteger("123456789012345678901234567890"), "%-#9x", "0x18ee90ff6c373e0ee4e3f0ad2" }, //$NON-NLS-2$
2529                { new BigInteger("-9876543210987654321098765432100000"), "%x", "-1e6f380472bd4bae6eb8259bd94a0" }, //$NON-NLS-2$
2530                { new BigInteger("-9876543210987654321098765432100000"), "%-8x", "-1e6f380472bd4bae6eb8259bd94a0" }, //$NON-NLS-2$
2531                { new BigInteger("-9876543210987654321098765432100000"), "%06x", "-1e6f380472bd4bae6eb8259bd94a0" }, //$NON-NLS-2$
2532                { new BigInteger("-9876543210987654321098765432100000"), "%#x", "-0x1e6f380472bd4bae6eb8259bd94a0" }, //$NON-NLS-2$
2533                { new BigInteger("-9876543210987654321098765432100000"), "%0#12x", "-0x1e6f380472bd4bae6eb8259bd94a0" }, //$NON-NLS-2$
2534                { new BigInteger("-9876543210987654321098765432100000"), "%-#9x", "-0x1e6f380472bd4bae6eb8259bd94a0" }, //$NON-NLS-2$
2535        };
2536
2537        for (int i = 0; i < tripleX.length; i++) {
2538            f = new Formatter(Locale.FRANCE);
2539            f.format((String) tripleX[i][pattern],
2540                    tripleX[i][input]);
2541            assertEquals("triple[" + i + "]:" + tripleX[i][input] + ",pattern["
2542                    + i + "]:" + tripleX[i][pattern], tripleX[i][output], f
2543                    .toString());
2544
2545        }
2546
2547        f = new Formatter(Locale.GERMAN);
2548        f.format("%(+,-7d%<( o%<+(x %<( 06X", (BigInteger) null);
2549        assertEquals("null   nullnull   NULL", f.toString());
2550    }
2551
2552    /**
2553     * java.util.Formatter#format(String, Object...) for padding of
2554     * BigInteger conversion
2555     */
2556    public void test_formatLjava_lang_String$Ljava_lang_Object_BigIntegerPaddingConversion() {
2557        Formatter f = null;
2558
2559        BigInteger bigInt = new BigInteger("123456789012345678901234567890");
2560        f = new Formatter(Locale.GERMAN);
2561        f.format("%32d", bigInt);
2562        assertEquals("  123456789012345678901234567890", f.toString());
2563
2564        f = new Formatter(Locale.GERMAN);
2565        f.format("%+32x", bigInt);
2566        assertEquals("      +18ee90ff6c373e0ee4e3f0ad2", f.toString());
2567
2568        f = new Formatter(Locale.GERMAN);
2569        f.format("% 32o", bigInt);
2570        assertEquals(" 143564417755415637016711617605322", f.toString());
2571
2572        BigInteger negBigInt = new BigInteger(
2573                "-1234567890123456789012345678901234567890");
2574        f = new Formatter(Locale.GERMAN);
2575        f.format("%( 040X", negBigInt);
2576        assertEquals("(000003A0C92075C0DBF3B8ACBC5F96CE3F0AD2)", f.toString());
2577
2578        f = new Formatter(Locale.GERMAN);
2579        f.format("%+(045d", negBigInt);
2580        assertEquals("(0001234567890123456789012345678901234567890)", f
2581                .toString());
2582
2583        f = new Formatter(Locale.GERMAN);
2584        f.format("%+,-(60d", negBigInt);
2585        assertEquals(
2586                "(1.234.567.890.123.456.789.012.345.678.901.234.567.890)     ",
2587                f.toString());
2588    }
2589
2590    /**
2591     * java.util.Formatter#format(String, Object...) for BigInteger
2592     * conversion exception
2593     */
2594    public void test_formatLjava_lang_String$Ljava_lang_Object_BigIntegerConversionException() {
2595        Formatter f = null;
2596
2597        final String[] flagsConversionMismatches = { "%#d", "%,o", "%,x", "%,X" };
2598        for (int i = 0; i < flagsConversionMismatches.length; i++) {
2599            try {
2600                f = new Formatter(Locale.CHINA);
2601                f.format(flagsConversionMismatches[i], new BigInteger("1"));
2602                fail("should throw FormatFlagsConversionMismatchException");
2603            } catch (FormatFlagsConversionMismatchException e) {
2604                // expected
2605            }
2606        }
2607
2608        final String[] missingFormatWidths = { "%-0d", "%0d", "%-d", "%-0o",
2609                "%0o", "%-o", "%-0x", "%0x", "%-x", "%-0X", "%0X", "%-X" };
2610        for (int i = 0; i < missingFormatWidths.length; i++) {
2611            try {
2612                f = new Formatter(Locale.KOREA);
2613                f.format(missingFormatWidths[i], new BigInteger("1"));
2614                fail("should throw MissingFormatWidthException");
2615            } catch (MissingFormatWidthException e) {
2616                // expected
2617            }
2618        }
2619
2620        final String[] illFlags = { "%+ d", "%-08d", "%+ o", "%-08o", "%+ x",
2621                "%-08x", "%+ X", "%-08X" };
2622        for (int i = 0; i < illFlags.length; i++) {
2623            try {
2624                f = new Formatter(Locale.CANADA);
2625                f.format(illFlags[i], new BigInteger("1"));
2626                fail("should throw IllegalFormatFlagsException");
2627            } catch (IllegalFormatFlagsException e) {
2628                // expected
2629            }
2630        }
2631
2632        final String[] precisionExceptions = { "%.4d", "%2.5o", "%8.6x",
2633                "%11.17X" };
2634        for (int i = 0; i < precisionExceptions.length; i++) {
2635            try {
2636                f = new Formatter(Locale.US);
2637                f.format(precisionExceptions[i], new BigInteger("1"));
2638                fail("should throw IllegalFormatPrecisionException");
2639            } catch (IllegalFormatPrecisionException e) {
2640                // expected
2641            }
2642        }
2643
2644        f = new Formatter(Locale.US);
2645        try {
2646            f.format("%D", new BigInteger("1"));
2647            fail("should throw UnknownFormatConversionException");
2648        } catch (UnknownFormatConversionException e) {
2649            // expected
2650        }
2651
2652        f = new Formatter(Locale.US);
2653        try {
2654            f.format("%O", new BigInteger("1"));
2655            fail("should throw UnknownFormatConversionException");
2656        } catch (UnknownFormatConversionException e) {
2657            // expected
2658        }
2659
2660        try {
2661            f = new Formatter();
2662            f.format("%010000000000000000000000000000000001d", new BigInteger(
2663                    "1"));
2664            fail("should throw MissingFormatWidthException");
2665        } catch (MissingFormatWidthException e) {
2666            // expected
2667        }
2668    }
2669
2670    /**
2671     * java.util.Formatter#format(String, Object...) for BigInteger
2672     * exception throwing order
2673     */
2674    public void test_formatLjava_lang_String$Ljava_lang_Object_BigIntegerExceptionOrder() {
2675        Formatter f = null;
2676        BigInteger big = new BigInteger("100");
2677
2678        /*
2679         * Order summary: UnknownFormatConversionException >
2680         * MissingFormatWidthException > IllegalFormatFlagsException >
2681         * IllegalFormatPrecisionException > IllegalFormatConversionException >
2682         * FormatFlagsConversionMismatchException
2683         *
2684         */
2685        f = new Formatter(Locale.US);
2686        try {
2687            f.format("%(o", false);
2688            fail();
2689        } catch (FormatFlagsConversionMismatchException expected) {
2690        } catch (IllegalFormatConversionException expected) {
2691        }
2692
2693        try {
2694            f.format("%.4o", false);
2695            fail();
2696        } catch (IllegalFormatPrecisionException expected) {
2697        } catch (IllegalFormatConversionException expected) {
2698        }
2699
2700        try {
2701            f.format("%+ .4o", big);
2702            fail();
2703        } catch (IllegalFormatPrecisionException expected) {
2704        } catch (IllegalFormatFlagsException expected) {
2705        }
2706
2707        try {
2708            f.format("%+ -o", big);
2709            fail();
2710        } catch (MissingFormatWidthException expected) {
2711        } catch (IllegalFormatFlagsException expected) {
2712        }
2713
2714        try {
2715            f.format("%-O", big);
2716            fail();
2717        } catch (MissingFormatWidthException expected) {
2718        } catch (UnknownFormatConversionException expected) {
2719        }
2720    }
2721
2722    /**
2723     * java.util.Formatter#format(String, Object...) for Float/Double
2724     * conversion type 'e' and 'E'
2725     */
2726    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionE() {
2727        Formatter f = null;
2728        final Object[][] tripleE = {
2729                { 0f, "%e", "0.000000e+00" },
2730                { 0f, "%#.0e", "0.e+00" },
2731                { 0f, "%#- (9.8e", " 0.00000000e+00" },
2732                { 0f, "%#+0(8.4e", "+0.0000e+00" },
2733                { 0f, "%-+(1.6e", "+0.000000e+00" },
2734                { 0f, "% 0(12e", " 0.000000e+00" },
2735
2736                { 101f, "%e", "1.010000e+02" },
2737                { 101f, "%#.0e", "1.e+02" },
2738                { 101f, "%#- (9.8e", " 1.01000000e+02" },
2739                { 101f, "%#+0(8.4e", "+1.0100e+02" },
2740                { 101f, "%-+(1.6e", "+1.010000e+02" },
2741                { 101f, "% 0(12e", " 1.010000e+02" },
2742
2743                { 1.f, "%e", "1.000000e+00" },
2744                { 1.f, "%#.0e", "1.e+00" },
2745                { 1.f, "%#- (9.8e", " 1.00000000e+00" },
2746                { 1.f, "%#+0(8.4e", "+1.0000e+00" },
2747                { 1.f, "%-+(1.6e", "+1.000000e+00" },
2748                { 1.f, "% 0(12e", " 1.000000e+00" },
2749
2750                { -98f, "%e", "-9.800000e+01" },
2751                { -98f, "%#.0e", "-1.e+02" },
2752                { -98f, "%#- (9.8e", "(9.80000000e+01)" },
2753                { -98f, "%#+0(8.4e", "(9.8000e+01)" },
2754                { -98f, "%-+(1.6e", "(9.800000e+01)" },
2755                { -98f, "% 0(12e", "(9.800000e+01)" },
2756
2757                { 1.23f, "%e", "1.230000e+00" },
2758                { 1.23f, "%#.0e", "1.e+00" },
2759                { 1.23f, "%#- (9.8e", " 1.23000002e+00" },
2760                { 1.23f, "%#+0(8.4e", "+1.2300e+00" },
2761                { 1.23f, "%-+(1.6e", "+1.230000e+00" },
2762                { 1.23f, "% 0(12e", " 1.230000e+00" },
2763
2764                { 34.1234567f, "%e", "3.412346e+01" },
2765                { 34.1234567f, "%#.0e", "3.e+01" },
2766                { 34.1234567f, "%#- (9.8e", " 3.41234550e+01" },
2767                { 34.1234567f, "%#+0(8.4e", "+3.4123e+01" },
2768                { 34.1234567f, "%-+(1.6e", "+3.412346e+01" },
2769                { 34.1234567f, "% 0(12e", " 3.412346e+01" },
2770
2771                { -.12345f, "%e", "-1.234500e-01" },
2772                { -.12345f, "%#.0e", "-1.e-01" },
2773                { -.12345f, "%#- (9.8e", "(1.23450004e-01)" },
2774                { -.12345f, "%#+0(8.4e", "(1.2345e-01)" },
2775                { -.12345f, "%-+(1.6e", "(1.234500e-01)" },
2776                { -.12345f, "% 0(12e", "(1.234500e-01)" },
2777
2778                { -9876.1234567f, "%e", "-9.876123e+03" },
2779                { -9876.1234567f, "%#.0e", "-1.e+04" },
2780                { -9876.1234567f, "%#- (9.8e", "(9.87612305e+03)" },
2781                { -9876.1234567f, "%#+0(8.4e", "(9.8761e+03)" },
2782                { -9876.1234567f, "%-+(1.6e", "(9.876123e+03)" },
2783                { -9876.1234567f, "% 0(12e", "(9.876123e+03)" },
2784
2785                { Float.MAX_VALUE, "%e", "3.402823e+38" },
2786                { Float.MAX_VALUE, "%#.0e", "3.e+38" },
2787                { Float.MAX_VALUE, "%#- (9.8e", " 3.40282347e+38" },
2788                { Float.MAX_VALUE, "%#+0(8.4e", "+3.4028e+38" },
2789                { Float.MAX_VALUE, "%-+(1.6e", "+3.402823e+38" },
2790                { Float.MAX_VALUE, "% 0(12e", " 3.402823e+38" },
2791
2792                { Float.MIN_VALUE, "%e", "1.401298e-45" },
2793                { Float.MIN_VALUE, "%#.0e", "1.e-45" },
2794                { Float.MIN_VALUE, "%#- (9.8e", " 1.40129846e-45" },
2795                { Float.MIN_VALUE, "%#+0(8.4e", "+1.4013e-45" },
2796                { Float.MIN_VALUE, "%-+(1.6e", "+1.401298e-45" },
2797                { Float.MIN_VALUE, "% 0(12e", " 1.401298e-45" },
2798
2799                { Float.NaN, "%e", "NaN" },
2800                { Float.NaN, "%#.0e", "NaN" },
2801                { Float.NaN, "%#- (9.8e", "NaN      " },
2802                { Float.NaN, "%#+0(8.4e", "     NaN" },
2803                { Float.NaN, "%-+(1.6e", "NaN" },
2804                { Float.NaN, "% 0(12e", "         NaN" },
2805
2806
2807                { Float.NEGATIVE_INFINITY, "%e", "-Infinity" },
2808                { Float.NEGATIVE_INFINITY, "%#.0e", "-Infinity" },
2809                { Float.NEGATIVE_INFINITY, "%#- (9.8e", "(Infinity)" },
2810                { Float.NEGATIVE_INFINITY, "%#+0(8.4e", "(Infinity)" },
2811                { Float.NEGATIVE_INFINITY, "%-+(1.6e", "(Infinity)" },
2812                { Float.NEGATIVE_INFINITY, "% 0(12e", "  (Infinity)" },
2813
2814                { Float.NEGATIVE_INFINITY, "%e", "-Infinity" },
2815                { Float.NEGATIVE_INFINITY, "%#.0e", "-Infinity" },
2816                { Float.NEGATIVE_INFINITY, "%#- (9.8e", "(Infinity)" },
2817                { Float.NEGATIVE_INFINITY, "%#+0(8.4e", "(Infinity)" },
2818                { Float.NEGATIVE_INFINITY, "%-+(1.6e", "(Infinity)" },
2819                { Float.NEGATIVE_INFINITY, "% 0(12e", "  (Infinity)" },
2820
2821                { 0d, "%e", "0.000000e+00" },
2822                { 0d, "%#.0e", "0.e+00" },
2823                { 0d, "%#- (9.8e", " 0.00000000e+00" },
2824                { 0d, "%#+0(8.4e", "+0.0000e+00" },
2825                { 0d, "%-+(1.6e", "+0.000000e+00" },
2826                { 0d, "% 0(12e", " 0.000000e+00" },
2827
2828                { 1d, "%e", "1.000000e+00" },
2829                { 1d, "%#.0e", "1.e+00" },
2830                { 1d, "%#- (9.8e", " 1.00000000e+00" },
2831                { 1d, "%#+0(8.4e", "+1.0000e+00" },
2832                { 1d, "%-+(1.6e", "+1.000000e+00" },
2833                { 1d, "% 0(12e", " 1.000000e+00" },
2834
2835                { -1d, "%e", "-1.000000e+00" },
2836                { -1d, "%#.0e", "-1.e+00" },
2837                { -1d, "%#- (9.8e", "(1.00000000e+00)" },
2838                { -1d, "%#+0(8.4e", "(1.0000e+00)" },
2839                { -1d, "%-+(1.6e", "(1.000000e+00)" },
2840                { -1d, "% 0(12e", "(1.000000e+00)" },
2841
2842
2843                { .00000001d, "%e", "1.000000e-08" },
2844                { .00000001d, "%#.0e", "1.e-08" },
2845                { .00000001d, "%#- (9.8e", " 1.00000000e-08" },
2846                { .00000001d, "%#+0(8.4e", "+1.0000e-08" },
2847                { .00000001d, "%-+(1.6e", "+1.000000e-08" },
2848                { .00000001d, "% 0(12e", " 1.000000e-08" },
2849
2850                { 9122.10d, "%e", "9.122100e+03" },
2851                { 9122.10d, "%#.0e", "9.e+03" },
2852                { 9122.10d, "%#- (9.8e", " 9.12210000e+03" },
2853                { 9122.10d, "%#+0(8.4e", "+9.1221e+03" },
2854                { 9122.10d, "%-+(1.6e", "+9.122100e+03" },
2855                { 9122.10d, "% 0(12e", " 9.122100e+03" },
2856
2857                { 0.1d, "%e", "1.000000e-01" },
2858                { 0.1d, "%#.0e", "1.e-01" },
2859                { 0.1d, "%#- (9.8e", " 1.00000000e-01" },
2860                { 0.1d, "%#+0(8.4e", "+1.0000e-01" },
2861                { 0.1d, "%-+(1.6e", "+1.000000e-01" },
2862                { 0.1d, "% 0(12e", " 1.000000e-01" },
2863
2864                { -2.d, "%e", "-2.000000e+00" },
2865                { -2.d, "%#.0e", "-2.e+00" },
2866                { -2.d, "%#- (9.8e", "(2.00000000e+00)" },
2867                { -2.d, "%#+0(8.4e", "(2.0000e+00)" },
2868                { -2.d, "%-+(1.6e", "(2.000000e+00)" },
2869                { -2.d, "% 0(12e", "(2.000000e+00)" },
2870
2871                { -.39d, "%e", "-3.900000e-01" },
2872                { -.39d, "%#.0e", "-4.e-01" },
2873                { -.39d, "%#- (9.8e", "(3.90000000e-01)" },
2874                { -.39d, "%#+0(8.4e", "(3.9000e-01)" },
2875                { -.39d, "%-+(1.6e", "(3.900000e-01)" },
2876                { -.39d, "% 0(12e", "(3.900000e-01)" },
2877
2878                { -1234567890.012345678d, "%e", "-1.234568e+09" },
2879                { -1234567890.012345678d, "%#.0e", "-1.e+09" },
2880                { -1234567890.012345678d, "%#- (9.8e", "(1.23456789e+09)" },
2881                { -1234567890.012345678d, "%#+0(8.4e", "(1.2346e+09)" },
2882                { -1234567890.012345678d, "%-+(1.6e", "(1.234568e+09)" },
2883                { -1234567890.012345678d, "% 0(12e", "(1.234568e+09)" },
2884
2885                { Double.MAX_VALUE, "%e", "1.797693e+308" },
2886                { Double.MAX_VALUE, "%#.0e", "2.e+308" },
2887                { Double.MAX_VALUE, "%#- (9.8e", " 1.79769313e+308" },
2888                { Double.MAX_VALUE, "%#+0(8.4e", "+1.7977e+308" },
2889                { Double.MAX_VALUE, "%-+(1.6e", "+1.797693e+308" },
2890                { Double.MAX_VALUE, "% 0(12e", " 1.797693e+308" },
2891
2892                { Double.MIN_VALUE, "%e", "4.900000e-324" },
2893                { Double.MIN_VALUE, "%#.0e", "5.e-324" },
2894                { Double.MIN_VALUE, "%#- (9.8e", " 4.90000000e-324" },
2895                { Double.MIN_VALUE, "%#+0(8.4e", "+4.9000e-324" },
2896                { Double.MIN_VALUE, "%-+(1.6e", "+4.900000e-324" },
2897                { Double.MIN_VALUE, "% 0(12e", " 4.900000e-324" },
2898
2899                { Double.NaN, "%e", "NaN" },
2900                { Double.NaN, "%#.0e", "NaN" },
2901                { Double.NaN, "%#- (9.8e", "NaN      " },
2902                { Double.NaN, "%#+0(8.4e", "     NaN" },
2903                { Double.NaN, "%-+(1.6e", "NaN" },
2904                { Double.NaN, "% 0(12e", "         NaN" },
2905
2906                { Double.NEGATIVE_INFINITY, "%e", "-Infinity" },
2907                { Double.NEGATIVE_INFINITY, "%#.0e", "-Infinity" },
2908                { Double.NEGATIVE_INFINITY, "%#- (9.8e", "(Infinity)" },
2909                { Double.NEGATIVE_INFINITY, "%#+0(8.4e", "(Infinity)" },
2910                { Double.NEGATIVE_INFINITY, "%-+(1.6e", "(Infinity)" },
2911                { Double.NEGATIVE_INFINITY, "% 0(12e", "  (Infinity)" },
2912
2913                { Double.POSITIVE_INFINITY, "%e", "Infinity" },
2914                { Double.POSITIVE_INFINITY, "%#.0e", "Infinity" },
2915                { Double.POSITIVE_INFINITY, "%#- (9.8e", " Infinity" },
2916                { Double.POSITIVE_INFINITY, "%#+0(8.4e", "+Infinity" },
2917                { Double.POSITIVE_INFINITY, "%-+(1.6e", "+Infinity" },
2918                { Double.POSITIVE_INFINITY, "% 0(12e", "    Infinity" },
2919        };
2920        final int input = 0;
2921        final int pattern = 1;
2922        final int output = 2;
2923        for (int i = 0; i < tripleE.length; i++) {
2924            f = new Formatter(Locale.US);
2925            f.format((String) tripleE[i][pattern], tripleE[i][input]);
2926            assertEquals("triple[" + i + "]:" + tripleE[i][input] + ",pattern["
2927                    + i + "]:" + tripleE[i][pattern],
2928                    tripleE[i][output], f.toString());
2929
2930            // test for conversion type 'E'
2931            f = new Formatter(Locale.US);
2932            f.format(((String) tripleE[i][pattern]).toUpperCase(), tripleE[i][input]);
2933            assertEquals("triple[" + i + "]:" + tripleE[i][input] + ",pattern["
2934                    + i + "]:" + tripleE[i][pattern], ((String) tripleE[i][output])
2935                    .toUpperCase(Locale.UK), f.toString());
2936        }
2937
2938        f = new Formatter(Locale.GERMAN);
2939        f.format("%e", 1001f);
2940        /*
2941         * fail on RI, spec says 'e' requires the output to be formatted in
2942         * general scientific notation and the localization algorithm is
2943         * applied. But RI format this case to 1.001000e+03, which does not
2944         * conform to the German Locale
2945         */
2946        assertEquals("1,001000e+03", f.toString());
2947    }
2948
2949    /**
2950     * java.util.Formatter#format(String, Object...) for Float/Double
2951     * conversion type 'g' and 'G'
2952     */
2953    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionG() {
2954        Formatter f = null;
2955        final Object[][] tripleG = {
2956                { 1001f, "%g", "1001.00" },
2957                { 1001f, "%- (,9.8g", " 1,001.0000" },
2958                { 1001f, "%+0(,8.4g", "+001,001" },
2959                { 1001f, "%-+(,1.6g", "+1,001.00" },
2960                { 1001f, "% 0(,12.0g", " 0000001e+03" },
2961
2962                { 1.f, "%g", "1.00000" },
2963                { 1.f, "%- (,9.8g", " 1.0000000" },
2964                { 1.f, "%+0(,8.4g", "+001.000" },
2965                { 1.f, "%-+(,1.6g", "+1.00000" },
2966                { 1.f, "% 0(,12.0g", " 00000000001" },
2967
2968                { -98f, "%g", "-98.0000" },
2969                { -98f, "%- (,9.8g", "(98.000000)" },
2970                { -98f, "%+0(,8.4g", "(098.00)" },
2971                { -98f, "%-+(,1.6g", "(98.0000)" },
2972                { -98f, "% 0(,12.0g", "(000001e+02)" },
2973
2974                { 0.000001f, "%g", "1.00000e-06" },
2975                { 0.000001f, "%- (,9.8g", " 1.0000000e-06" },
2976                { 0.000001f, "%+0(,8.4g", "+1.000e-06" },
2977                { 0.000001f, "%-+(,1.6g", "+1.00000e-06" },
2978                { 0.000001f, "% 0(,12.0g", " 0000001e-06" },
2979
2980                { 345.1234567f, "%g", "345.123" },
2981                { 345.1234567f, "%- (,9.8g", " 345.12344" },
2982                { 345.1234567f, "%+0(,8.4g", "+00345.1" },
2983                { 345.1234567f, "%-+(,1.6g", "+345.123" },
2984                { 345.1234567f, "% 0(,12.0g", " 0000003e+02" },
2985
2986                { -.00000012345f, "%g", "-1.23450e-07" },
2987                { -.00000012345f, "%- (,9.8g", "(1.2344999e-07)" },
2988                { -.00000012345f, "%+0(,8.4g", "(1.234e-07)" },
2989                { -.00000012345f, "%-+(,1.6g", "(1.23450e-07)" },
2990                { -.00000012345f, "% 0(,12.0g", "(000001e-07)" },
2991
2992                { -987.1234567f, "%g", "-987.123" },
2993                { -987.1234567f, "%- (,9.8g", "(987.12347)" },
2994                { -987.1234567f, "%+0(,8.4g", "(0987.1)" },
2995                { -987.1234567f, "%-+(,1.6g", "(987.123)" },
2996                { -987.1234567f, "% 0(,12.0g", "(000001e+03)" },
2997
2998                { Float.MAX_VALUE, "%g", "3.40282e+38" },
2999                { Float.MAX_VALUE, "%- (,9.8g", " 3.4028235e+38" },
3000                { Float.MAX_VALUE, "%+0(,8.4g", "+3.403e+38" },
3001                { Float.MAX_VALUE, "%-+(,1.6g", "+3.40282e+38" },
3002                { Float.MAX_VALUE, "% 0(,12.0g", " 0000003e+38" },
3003
3004                { Float.MIN_VALUE, "%g", "1.40130e-45" },
3005                { Float.MIN_VALUE, "%- (,9.8g", " 1.4012985e-45" },
3006                { Float.MIN_VALUE, "%+0(,8.4g", "+1.401e-45" },
3007                { Float.MIN_VALUE, "%-+(,1.6g", "+1.40130e-45" },
3008                { Float.MIN_VALUE, "% 0(,12.0g", " 0000001e-45" },
3009
3010                { Float.NaN, "%g", "NaN" },
3011                { Float.NaN, "%- (,9.8g", "NaN      " },
3012                { Float.NaN, "%+0(,8.4g", "     NaN" },
3013                { Float.NaN, "%-+(,1.6g", "NaN" },
3014                { Float.NaN, "% 0(,12.0g", "         NaN" },
3015
3016                { Float.NEGATIVE_INFINITY, "%g", "-Infinity" },
3017                { Float.NEGATIVE_INFINITY, "%- (,9.8g", "(Infinity)" },
3018                { Float.NEGATIVE_INFINITY, "%+0(,8.4g", "(Infinity)" },
3019                { Float.NEGATIVE_INFINITY, "%-+(,1.6g", "(Infinity)" },
3020                { Float.NEGATIVE_INFINITY, "% 0(,12.0g", "  (Infinity)" },
3021
3022                { Float.POSITIVE_INFINITY, "%g", "Infinity" },
3023                { Float.POSITIVE_INFINITY, "%- (,9.8g", " Infinity" },
3024                { Float.POSITIVE_INFINITY, "%+0(,8.4g", "+Infinity" },
3025                { Float.POSITIVE_INFINITY, "%-+(,1.6g", "+Infinity" },
3026                { Float.POSITIVE_INFINITY, "% 0(,12.0g", "    Infinity" },
3027
3028                { 1d, "%g", "1.00000" },
3029                { 1d, "%- (,9.8g", " 1.0000000" },
3030                { 1d, "%+0(,8.4g", "+001.000" },
3031                { 1d, "%-+(,1.6g", "+1.00000" },
3032                { 1d, "% 0(,12.0g", " 00000000001" },
3033
3034                { -1d, "%g", "-1.00000" },
3035                { -1d, "%- (,9.8g", "(1.0000000)" },
3036                { -1d, "%+0(,8.4g", "(01.000)" },
3037                { -1d, "%-+(,1.6g", "(1.00000)" },
3038                { -1d, "% 0(,12.0g", "(0000000001)" },
3039
3040                { .00000001d, "%g", "1.00000e-08" },
3041                { .00000001d, "%- (,9.8g", " 1.0000000e-08" },
3042                { .00000001d, "%+0(,8.4g", "+1.000e-08" },
3043                { .00000001d, "%-+(,1.6g", "+1.00000e-08" },
3044                { .00000001d, "% 0(,12.0g", " 0000001e-08" },
3045
3046                { 1912.10d, "%g", "1912.10" },
3047                { 1912.10d, "%- (,9.8g", " 1,912.1000" },
3048                { 1912.10d, "%+0(,8.4g", "+001,912" },
3049                { 1912.10d, "%-+(,1.6g", "+1,912.10" },
3050                { 1912.10d, "% 0(,12.0g", " 0000002e+03" },
3051
3052                { 0.1d, "%g", "0.100000" },
3053                { 0.1d, "%- (,9.8g", " 0.10000000" },
3054                { 0.1d, "%+0(,8.4g", "+00.1000" },
3055                { 0.1d, "%-+(,1.6g", "+0.100000" },
3056                { 0.1d, "% 0(,12.0g", " 000000000.1" },
3057
3058                { -2.d, "%g", "-2.00000" },
3059                { -2.d, "%- (,9.8g", "(2.0000000)" },
3060                { -2.d, "%+0(,8.4g", "(02.000)" },
3061                { -2.d, "%-+(,1.6g", "(2.00000)" },
3062                { -2.d, "% 0(,12.0g", "(0000000002)" },
3063
3064                { -.00039d, "%g", "-0.000390000" },
3065                { -.00039d, "%- (,9.8g", "(0.00039000000)" },
3066                { -.00039d, "%+0(,8.4g", "(0.0003900)" },
3067                { -.00039d, "%-+(,1.6g", "(0.000390000)" },
3068                { -.00039d, "% 0(,12.0g", "(00000.0004)" },
3069
3070                { -1234567890.012345678d, "%g", "-1.23457e+09" },
3071                { -1234567890.012345678d, "%- (,9.8g", "(1.2345679e+09)" },
3072                { -1234567890.012345678d, "%+0(,8.4g", "(1.235e+09)" },
3073                { -1234567890.012345678d, "%-+(,1.6g", "(1.23457e+09)" },
3074                { -1234567890.012345678d, "% 0(,12.0g", "(000001e+09)" },
3075
3076                { Double.MAX_VALUE, "%g", "1.79769e+308" },
3077                { Double.MAX_VALUE, "%- (,9.8g", " 1.7976931e+308" },
3078                { Double.MAX_VALUE, "%+0(,8.4g", "+1.798e+308" },
3079                { Double.MAX_VALUE, "%-+(,1.6g", "+1.79769e+308" },
3080                { Double.MAX_VALUE, "% 0(,12.0g", " 000002e+308" },
3081
3082                { Double.MIN_VALUE, "%g", "4.90000e-324" },
3083                { Double.MIN_VALUE, "%- (,9.8g", " 4.9000000e-324" },
3084                { Double.MIN_VALUE, "%+0(,8.4g", "+4.900e-324" },
3085                { Double.MIN_VALUE, "%-+(,1.6g", "+4.90000e-324" },
3086                { Double.MIN_VALUE, "% 0(,12.0g", " 000005e-324" },
3087
3088                { Double.NaN, "%g", "NaN" },
3089                { Double.NaN, "%- (,9.8g", "NaN      " },
3090                { Double.NaN, "%+0(,8.4g", "     NaN" },
3091                { Double.NaN, "%-+(,1.6g", "NaN" },
3092                { Double.NaN, "% 0(,12.0g", "         NaN" },
3093
3094                { Double.NEGATIVE_INFINITY, "%g", "-Infinity" },
3095                { Double.NEGATIVE_INFINITY, "%- (,9.8g", "(Infinity)" },
3096                { Double.NEGATIVE_INFINITY, "%+0(,8.4g", "(Infinity)" },
3097                { Double.NEGATIVE_INFINITY, "%-+(,1.6g", "(Infinity)" },
3098                { Double.NEGATIVE_INFINITY, "% 0(,12.0g", "  (Infinity)" },
3099
3100                { Double.POSITIVE_INFINITY, "%g", "Infinity" },
3101                { Double.POSITIVE_INFINITY, "%- (,9.8g", " Infinity" },
3102                { Double.POSITIVE_INFINITY, "%+0(,8.4g", "+Infinity" },
3103                { Double.POSITIVE_INFINITY, "%-+(,1.6g", "+Infinity" },
3104                { Double.POSITIVE_INFINITY, "% 0(,12.0g", "    Infinity" },
3105
3106        };
3107        final int input = 0;
3108        final int pattern = 1;
3109        final int output = 2;
3110        for (int i = 0; i < tripleG.length; i++) {
3111
3112            f = new Formatter(Locale.US);
3113            f.format((String) tripleG[i][pattern], tripleG[i][input]);
3114            assertEquals("triple[" + i + "]:" + tripleG[i][input] + ",pattern["
3115                    + i + "]:" + tripleG[i][pattern],
3116                    tripleG[i][output], f.toString());
3117
3118            // test for conversion type 'G'
3119            f = new Formatter(Locale.US);
3120            f.format(((String) tripleG[i][pattern]).toUpperCase(), tripleG[i][input]);
3121            assertEquals("triple[" + i + "]:" + tripleG[i][input] + ",pattern["
3122                    + i + "]:" + tripleG[i][pattern], ((String) tripleG[i][output])
3123                    .toUpperCase(Locale.UK), f.toString());
3124        }
3125
3126        f = new Formatter(Locale.US);
3127        f.format("%.5g", 0f);
3128        assertEquals("0.0000", f.toString());
3129
3130        f = new Formatter(Locale.US);
3131        f.format("%.0g", 0f);
3132        /*
3133         * fail on RI, spec says if the precision is 0, then it is taken to be
3134         * 1. but RI throws ArrayIndexOutOfBoundsException.
3135         */
3136        assertEquals("0", f.toString());
3137
3138        f = new Formatter(Locale.GERMAN);
3139        f.format("%g", 1001f);
3140        /*
3141         * fail on RI, spec says 'g' requires the output to be formatted in
3142         * general scientific notation and the localization algorithm is
3143         * applied. But RI format this case to 1001.00, which does not conform
3144         * to the German Locale
3145         */
3146        assertEquals("1001,00", f.toString());
3147    }
3148
3149    /**
3150     * java.util.Formatter#format(String, Object...) for Float/Double
3151     * conversion type 'g' and 'G' overflow
3152     */
3153    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionG_Overflow() {
3154        Formatter f = new Formatter();
3155        f.format("%g", 999999.5);
3156        assertEquals("1.00000e+06", f.toString());
3157
3158        f = new Formatter();
3159        f.format("%g", 99999.5);
3160        assertEquals("99999.5", f.toString());
3161
3162        f = new Formatter();
3163        f.format("%.4g", 99.95);
3164        assertEquals("99.95", f.toString());
3165
3166        f = new Formatter();
3167        f.format("%g", 99.95);
3168        assertEquals("99.9500", f.toString());
3169
3170        f = new Formatter();
3171        f.format("%g", 0.9);
3172        assertEquals("0.900000", f.toString());
3173
3174        f = new Formatter();
3175        f.format("%.0g", 0.000095);
3176        assertEquals("0.0001", f.toString());
3177
3178        f = new Formatter();
3179        f.format("%g", 0.0999999);
3180        assertEquals("0.0999999", f.toString());
3181
3182        f = new Formatter();
3183        f.format("%g", 0.00009);
3184        assertEquals("9.00000e-05", f.toString());
3185    }
3186
3187    /**
3188     * java.util.Formatter#format(String, Object...) for Float/Double
3189     * conversion type 'f'
3190     */
3191    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionF() {
3192        Formatter f = null;
3193
3194        final Object[][] tripleF = {
3195                { 0f, "%f", "0,000000" },
3196                { 0f, "%#.3f", "0,000" },
3197                { 0f, "%,5f", "0,000000" },
3198                { 0f, "%- (12.0f", " 0          " },
3199                { 0f, "%#+0(1.6f", "+0,000000" },
3200                { 0f, "%-+(8.4f", "+0,0000 " },
3201                { 0f, "% 0#(9.8f", " 0,00000000" },
3202
3203                { 1234f, "%f", "1234,000000" },
3204                { 1234f, "%#.3f", "1234,000" },
3205                { 1234f, "%,5f", "1.234,000000" },
3206                { 1234f, "%- (12.0f", " 1234       " },
3207                { 1234f, "%#+0(1.6f", "+1234,000000" },
3208                { 1234f, "%-+(8.4f", "+1234,0000" },
3209                { 1234f, "% 0#(9.8f", " 1234,00000000" },
3210
3211                { 1.f, "%f", "1,000000" },
3212                { 1.f, "%#.3f", "1,000" },
3213                { 1.f, "%,5f", "1,000000" },
3214                { 1.f, "%- (12.0f", " 1          " },
3215                { 1.f, "%#+0(1.6f", "+1,000000" },
3216                { 1.f, "%-+(8.4f", "+1,0000 " },
3217                { 1.f, "% 0#(9.8f", " 1,00000000" },
3218
3219                { -98f, "%f", "-98,000000" },
3220                { -98f, "%#.3f", "-98,000" },
3221                { -98f, "%,5f", "-98,000000" },
3222                { -98f, "%- (12.0f", "(98)        " },
3223                { -98f, "%#+0(1.6f", "(98,000000)" },
3224                { -98f, "%-+(8.4f", "(98,0000)" },
3225                { -98f, "% 0#(9.8f", "(98,00000000)" },
3226
3227                { 0.000001f, "%f", "0,000001" },
3228                { 0.000001f, "%#.3f", "0,000" },
3229                { 0.000001f, "%,5f", "0,000001" },
3230                { 0.000001f, "%- (12.0f", " 0          " },
3231                { 0.000001f, "%#+0(1.6f", "+0,000001" },
3232                { 0.000001f, "%-+(8.4f", "+0,0000 " },
3233                { 0.000001f, "% 0#(9.8f", " 0,00000100" },
3234
3235                { 345.1234567f, "%f", "345,123444" },
3236                { 345.1234567f, "%#.3f", "345,123" },
3237                { 345.1234567f, "%,5f", "345,123444" },
3238                { 345.1234567f, "%- (12.0f", " 345        " },
3239                { 345.1234567f, "%#+0(1.6f", "+345,123444" },
3240                { 345.1234567f, "%-+(8.4f", "+345,1234" },
3241                { 345.1234567f, "% 0#(9.8f", " 345,12344360" },
3242
3243                { -.00000012345f, "%f", "-0,000000" },
3244                { -.00000012345f, "%#.3f", "-0,000" },
3245                { -.00000012345f, "%,5f", "-0,000000" },
3246                { -.00000012345f, "%- (12.0f", "(0)         " },
3247                { -.00000012345f, "%#+0(1.6f", "(0,000000)" },
3248                { -.00000012345f, "%-+(8.4f", "(0,0000)" },
3249                { -.00000012345f, "% 0#(9.8f", "(0,00000012)" },
3250
3251                { -987654321.1234567f, "%f", "-987654336,000000" },
3252                { -987654321.1234567f, "%#.3f", "-987654336,000" },
3253                { -987654321.1234567f, "%,5f", "-987.654.336,000000" },
3254                { -987654321.1234567f, "%- (12.0f", "(987654336) " },
3255                { -987654321.1234567f, "%#+0(1.6f", "(987654336,000000)" },
3256                { -987654321.1234567f, "%-+(8.4f", "(987654336,0000)" },
3257                { -987654321.1234567f, "% 0#(9.8f", "(987654336,00000000)" },
3258
3259                { Float.MAX_VALUE, "%f", "340282346638528860000000000000000000000,000000" },
3260                { Float.MAX_VALUE, "%#.3f", "340282346638528860000000000000000000000,000" },
3261                { Float.MAX_VALUE, "%,5f", "340.282.346.638.528.860.000.000.000.000.000.000.000,000000" },
3262                { Float.MAX_VALUE, "%- (12.0f", " 340282346638528860000000000000000000000" },
3263                { Float.MAX_VALUE, "%#+0(1.6f", "+340282346638528860000000000000000000000,000000" },
3264                { Float.MAX_VALUE, "%-+(8.4f", "+340282346638528860000000000000000000000,0000" },
3265                { Float.MAX_VALUE, "% 0#(9.8f", " 340282346638528860000000000000000000000,00000000" },
3266
3267                { Float.MIN_VALUE, "%f", "0,000000" },
3268                { Float.MIN_VALUE, "%#.3f", "0,000" },
3269                { Float.MIN_VALUE, "%,5f", "0,000000" },
3270                { Float.MIN_VALUE, "%- (12.0f", " 0          " },
3271                { Float.MIN_VALUE, "%#+0(1.6f", "+0,000000" },
3272                { Float.MIN_VALUE, "%-+(8.4f", "+0,0000 " },
3273                { Float.MIN_VALUE, "% 0#(9.8f", " 0,00000000" },
3274
3275                { Float.NaN, "%f", "NaN" },
3276                { Float.NaN, "%#.3f", "NaN" },
3277                { Float.NaN, "%,5f", "  NaN" },
3278                { Float.NaN, "%- (12.0f", "NaN         " },
3279                { Float.NaN, "%#+0(1.6f", "NaN" },
3280                { Float.NaN, "%-+(8.4f", "NaN     " },
3281                { Float.NaN, "% 0#(9.8f", "      NaN" },
3282
3283                { Float.NEGATIVE_INFINITY, "%f", "-Infinity" },
3284                { Float.NEGATIVE_INFINITY, "%#.3f", "-Infinity" },
3285                { Float.NEGATIVE_INFINITY, "%,5f", "-Infinity" },
3286                { Float.NEGATIVE_INFINITY, "%- (12.0f", "(Infinity)  " },
3287                { Float.NEGATIVE_INFINITY, "%#+0(1.6f", "(Infinity)" },
3288                { Float.NEGATIVE_INFINITY, "%-+(8.4f", "(Infinity)" },
3289                { Float.NEGATIVE_INFINITY, "% 0#(9.8f", "(Infinity)" },
3290
3291                { Float.POSITIVE_INFINITY, "%f", "Infinity" },
3292                { Float.POSITIVE_INFINITY, "%#.3f", "Infinity" },
3293                { Float.POSITIVE_INFINITY, "%,5f", "Infinity" },
3294                { Float.POSITIVE_INFINITY, "%- (12.0f", " Infinity   " },
3295                { Float.POSITIVE_INFINITY, "%#+0(1.6f", "+Infinity" },
3296                { Float.POSITIVE_INFINITY, "%-+(8.4f", "+Infinity" },
3297                { Float.POSITIVE_INFINITY, "% 0#(9.8f", " Infinity" },
3298
3299
3300                { 0d, "%f", "0,000000" },
3301                { 0d, "%#.3f", "0,000" },
3302                { 0d, "%,5f", "0,000000" },
3303                { 0d, "%- (12.0f", " 0          " },
3304                { 0d, "%#+0(1.6f", "+0,000000" },
3305                { 0d, "%-+(8.4f", "+0,0000 " },
3306                { 0d, "% 0#(9.8f", " 0,00000000" },
3307
3308                { 1d, "%f", "1,000000" },
3309                { 1d, "%#.3f", "1,000" },
3310                { 1d, "%,5f", "1,000000" },
3311                { 1d, "%- (12.0f", " 1          " },
3312                { 1d, "%#+0(1.6f", "+1,000000" },
3313                { 1d, "%-+(8.4f", "+1,0000 " },
3314                { 1d, "% 0#(9.8f", " 1,00000000" },
3315
3316                { -1d, "%f", "-1,000000" },
3317                { -1d, "%#.3f", "-1,000" },
3318                { -1d, "%,5f", "-1,000000" },
3319                { -1d, "%- (12.0f", "(1)         " },
3320                { -1d, "%#+0(1.6f", "(1,000000)" },
3321                { -1d, "%-+(8.4f", "(1,0000)" },
3322                { -1d, "% 0#(9.8f", "(1,00000000)" },
3323
3324                { .00000001d, "%f", "0,000000" },
3325                { .00000001d, "%#.3f", "0,000" },
3326                { .00000001d, "%,5f", "0,000000" },
3327                { .00000001d, "%- (12.0f", " 0          " },
3328                { .00000001d, "%#+0(1.6f", "+0,000000" },
3329                { .00000001d, "%-+(8.4f", "+0,0000 " },
3330                { .00000001d, "% 0#(9.8f", " 0,00000001" },
3331
3332                { 1000.10d, "%f", "1000,100000" },
3333                { 1000.10d, "%#.3f", "1000,100" },
3334                { 1000.10d, "%,5f", "1.000,100000" },
3335                { 1000.10d, "%- (12.0f", " 1000       " },
3336                { 1000.10d, "%#+0(1.6f", "+1000,100000" },
3337                { 1000.10d, "%-+(8.4f", "+1000,1000" },
3338                { 1000.10d, "% 0#(9.8f", " 1000,10000000" },
3339
3340                { 0.1d, "%f", "0,100000" },
3341                { 0.1d, "%#.3f", "0,100" },
3342                { 0.1d, "%,5f", "0,100000" },
3343                { 0.1d, "%- (12.0f", " 0          " },
3344                { 0.1d, "%#+0(1.6f", "+0,100000" },
3345                { 0.1d, "%-+(8.4f", "+0,1000 " },
3346                { 0.1d, "% 0#(9.8f", " 0,10000000" },
3347
3348                { -2.d, "%f", "-2,000000" },
3349                { -2.d, "%#.3f", "-2,000" },
3350                { -2.d, "%,5f", "-2,000000" },
3351                { -2.d, "%- (12.0f", "(2)         " },
3352                { -2.d, "%#+0(1.6f", "(2,000000)" },
3353                { -2.d, "%-+(8.4f", "(2,0000)" },
3354                { -2.d, "% 0#(9.8f", "(2,00000000)" },
3355
3356                { -.00009d, "%f", "-0,000090" },
3357                { -.00009d, "%#.3f", "-0,000" },
3358                { -.00009d, "%,5f", "-0,000090" },
3359                { -.00009d, "%- (12.0f", "(0)         " },
3360                { -.00009d, "%#+0(1.6f", "(0,000090)" },
3361                { -.00009d, "%-+(8.4f", "(0,0001)" },
3362                { -.00009d, "% 0#(9.8f", "(0,00009000)" },
3363
3364                { -1234567890.012345678d, "%f", "-1234567890,012346" },
3365                { -1234567890.012345678d, "%#.3f", "-1234567890,012" },
3366                { -1234567890.012345678d, "%,5f", "-1.234.567.890,012346" },
3367                { -1234567890.012345678d, "%- (12.0f", "(1234567890)" },
3368                { -1234567890.012345678d, "%#+0(1.6f", "(1234567890,012346)" },
3369                { -1234567890.012345678d, "%-+(8.4f", "(1234567890,0123)" },
3370                { -1234567890.012345678d, "% 0#(9.8f", "(1234567890,01234580)" },
3371
3372                { Double.MAX_VALUE, "%f", "179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,000000" },
3373                { Double.MAX_VALUE, "%#.3f", "179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,000" },
3374                { Double.MAX_VALUE, "%,5f", "179.769.313.486.231.570.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000,000000" },
3375                { Double.MAX_VALUE, "%- (12.0f", " 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" },
3376                { Double.MAX_VALUE, "%#+0(1.6f", "+179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,000000" },
3377                { Double.MAX_VALUE, "%-+(8.4f", "+179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0000" },
3378                { Double.MAX_VALUE, "% 0#(9.8f", " 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,00000000" },
3379
3380                { Double.MIN_VALUE, "%f", "0,000000" },
3381                { Double.MIN_VALUE, "%#.3f", "0,000" },
3382                { Double.MIN_VALUE, "%,5f", "0,000000" },
3383                { Double.MIN_VALUE, "%- (12.0f", " 0          " },
3384                { Double.MIN_VALUE, "%#+0(1.6f", "+0,000000" },
3385                { Double.MIN_VALUE, "%-+(8.4f", "+0,0000 " },
3386                { Double.MIN_VALUE, "% 0#(9.8f", " 0,00000000" },
3387
3388                { Double.NaN, "%f", "NaN" },
3389                { Double.NaN, "%#.3f", "NaN" },
3390                { Double.NaN, "%,5f", "  NaN" },
3391                { Double.NaN, "%- (12.0f", "NaN         " },
3392                { Double.NaN, "%#+0(1.6f", "NaN" },
3393                { Double.NaN, "%-+(8.4f", "NaN     " },
3394                { Double.NaN, "% 0#(9.8f", "      NaN" },
3395
3396                { Double.POSITIVE_INFINITY, "%f", "Infinity" },
3397                { Double.POSITIVE_INFINITY, "%#.3f", "Infinity" },
3398                { Double.POSITIVE_INFINITY, "%,5f", "Infinity" },
3399                { Double.POSITIVE_INFINITY, "%- (12.0f", " Infinity   " },
3400                { Double.POSITIVE_INFINITY, "%#+0(1.6f", "+Infinity" },
3401                { Double.POSITIVE_INFINITY, "%-+(8.4f", "+Infinity" },
3402                { Double.POSITIVE_INFINITY, "% 0#(9.8f", " Infinity" },
3403
3404                { Double.NEGATIVE_INFINITY, "%f", "-Infinity" },
3405                { Double.NEGATIVE_INFINITY, "%#.3f", "-Infinity" },
3406                { Double.NEGATIVE_INFINITY, "%,5f", "-Infinity" },
3407                { Double.NEGATIVE_INFINITY, "%- (12.0f", "(Infinity)  " },
3408                { Double.NEGATIVE_INFINITY, "%#+0(1.6f", "(Infinity)" },
3409                { Double.NEGATIVE_INFINITY, "%-+(8.4f", "(Infinity)" },
3410                { Double.NEGATIVE_INFINITY, "% 0#(9.8f", "(Infinity)" },
3411        };
3412        final int input = 0;
3413        final int pattern = 1;
3414        final int output = 2;
3415        for (int i = 0; i < tripleF.length; i++) {
3416            f = new Formatter(Locale.GERMAN);
3417            f.format((String) tripleF[i][pattern], tripleF[i][input]);
3418            assertEquals("triple[" + i + "]:" + tripleF[i][input] + ",pattern["
3419                    + i + "]:" + tripleF[i][pattern],
3420                    tripleF[i][output], f.toString());
3421        }
3422    }
3423
3424    /**
3425     * java.util.Formatter#format(String, Object...) for Float/Double
3426     * conversion type 'a' and 'A'
3427     */
3428    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionA() {
3429        Formatter f = null;
3430        final Object[][] tripleA = {
3431                { -0f, "%a", "-0x0.0p0" },
3432                { -0f, "%#.3a", "-0x0.000p0" },
3433                { -0f, "%5a", "-0x0.0p0" },
3434                { -0f, "%- 12.0a", "-0x0.0p0    " },
3435                { -0f, "%#+01.6a", "-0x0.000000p0" },
3436                { -0f, "%-+8.4a", "-0x0.0000p0" },
3437
3438                { 0f, "%a", "0x0.0p0" },
3439                { 0f, "%#.3a", "0x0.000p0" },
3440                { 0f, "%5a", "0x0.0p0" },
3441                { 0f, "%- 12.0a", " 0x0.0p0    " },
3442                { 0f, "%#+01.6a", "+0x0.000000p0" },
3443                { 0f, "%-+8.4a", "+0x0.0000p0" },
3444
3445                { 1234f, "%a", "0x1.348p10" },
3446                { 1234f, "%#.3a", "0x1.348p10" },
3447                { 1234f, "%5a", "0x1.348p10" },
3448                { 1234f, "%- 12.0a", " 0x1.3p10   " },
3449                { 1234f, "%#+01.6a", "+0x1.348000p10" },
3450                { 1234f, "%-+8.4a", "+0x1.3480p10" },
3451
3452                { 1.f, "%a", "0x1.0p0" },
3453                { 1.f, "%#.3a", "0x1.000p0" },
3454                { 1.f, "%5a", "0x1.0p0" },
3455                { 1.f, "%- 12.0a", " 0x1.0p0    " },
3456                { 1.f, "%#+01.6a", "+0x1.000000p0" },
3457                { 1.f, "%-+8.4a", "+0x1.0000p0" },
3458
3459                { -98f, "%a", "-0x1.88p6" },
3460                { -98f, "%#.3a", "-0x1.880p6" },
3461                { -98f, "%5a", "-0x1.88p6" },
3462                { -98f, "%- 12.0a", "-0x1.8p6    " },
3463                { -98f, "%#+01.6a", "-0x1.880000p6" },
3464                { -98f, "%-+8.4a", "-0x1.8800p6" },
3465
3466                { 345.1234567f, "%a", "0x1.591f9ap8" },
3467                { 345.1234567f, "%5a", "0x1.591f9ap8" },
3468                { 345.1234567f, "%#+01.6a", "+0x1.591f9ap8" },
3469
3470                { -987654321.1234567f, "%a", "-0x1.d6f346p29" },
3471                { -987654321.1234567f, "%#.3a", "-0x1.d6fp29" },
3472                { -987654321.1234567f, "%5a", "-0x1.d6f346p29" },
3473                { -987654321.1234567f, "%- 12.0a", "-0x1.dp29   " },
3474                { -987654321.1234567f, "%#+01.6a", "-0x1.d6f346p29" },
3475                { -987654321.1234567f, "%-+8.4a", "-0x1.d6f3p29" },
3476
3477                { Float.MAX_VALUE, "%a", "0x1.fffffep127" },
3478                { Float.MAX_VALUE, "%5a", "0x1.fffffep127" },
3479                { Float.MAX_VALUE, "%#+01.6a", "+0x1.fffffep127" },
3480
3481                { Float.NaN, "%a", "NaN" },
3482                { Float.NaN, "%#.3a", "NaN" },
3483                { Float.NaN, "%5a", "  NaN" },
3484                { Float.NaN, "%- 12.0a", "NaN         " },
3485                { Float.NaN, "%#+01.6a", "NaN" },
3486                { Float.NaN, "%-+8.4a", "NaN     " },
3487
3488                { Float.NEGATIVE_INFINITY, "%a", "-Infinity" },
3489                { Float.NEGATIVE_INFINITY, "%#.3a", "-Infinity" },
3490                { Float.NEGATIVE_INFINITY, "%5a", "-Infinity" },
3491                { Float.NEGATIVE_INFINITY, "%- 12.0a", "-Infinity   " },
3492                { Float.NEGATIVE_INFINITY, "%#+01.6a", "-Infinity" },
3493                { Float.NEGATIVE_INFINITY, "%-+8.4a", "-Infinity" },
3494
3495                { Float.POSITIVE_INFINITY, "%a", "Infinity" },
3496                { Float.POSITIVE_INFINITY, "%#.3a", "Infinity" },
3497                { Float.POSITIVE_INFINITY, "%5a", "Infinity" },
3498                { Float.POSITIVE_INFINITY, "%- 12.0a", " Infinity   " },
3499                { Float.POSITIVE_INFINITY, "%#+01.6a", "+Infinity" },
3500                { Float.POSITIVE_INFINITY, "%-+8.4a", "+Infinity" },
3501
3502                { -0d, "%a", "-0x0.0p0" },
3503                { -0d, "%#.3a", "-0x0.000p0" },
3504                { -0d, "%5a", "-0x0.0p0" },
3505                { -0d, "%- 12.0a", "-0x0.0p0    " },
3506                { -0d, "%#+01.6a", "-0x0.000000p0" },
3507                { -0d, "%-+8.4a", "-0x0.0000p0" },
3508
3509                { 0d, "%a", "0x0.0p0" },
3510                { 0d, "%#.3a", "0x0.000p0" },
3511                { 0d, "%5a", "0x0.0p0" },
3512                { 0d, "%- 12.0a", " 0x0.0p0    " },
3513                { 0d, "%#+01.6a", "+0x0.000000p0" },
3514                { 0d, "%-+8.4a", "+0x0.0000p0" },
3515
3516                { 1d, "%a", "0x1.0p0" },
3517                { 1d, "%#.3a", "0x1.000p0" },
3518                { 1d, "%5a", "0x1.0p0" },
3519                { 1d, "%- 12.0a", " 0x1.0p0    " },
3520                { 1d, "%#+01.6a", "+0x1.000000p0" },
3521                { 1d, "%-+8.4a", "+0x1.0000p0" },
3522
3523                { -1d, "%a", "-0x1.0p0" },
3524                { -1d, "%#.3a", "-0x1.000p0" },
3525                { -1d, "%5a", "-0x1.0p0" },
3526                { -1d, "%- 12.0a", "-0x1.0p0    " },
3527                { -1d, "%#+01.6a", "-0x1.000000p0" },
3528                { -1d, "%-+8.4a", "-0x1.0000p0" },
3529
3530                { .00000001d, "%a", "0x1.5798ee2308c3ap-27" },
3531                { .00000001d, "%5a", "0x1.5798ee2308c3ap-27" },
3532                { .00000001d, "%- 12.0a", " 0x1.5p-27  " },
3533                { .00000001d, "%#+01.6a", "+0x1.5798eep-27" },
3534
3535                { 1000.10d, "%a", "0x1.f40cccccccccdp9" },
3536                { 1000.10d, "%5a", "0x1.f40cccccccccdp9" },
3537                { 1000.10d, "%- 12.0a", " 0x1.fp9    " },
3538
3539                { 0.1d, "%a", "0x1.999999999999ap-4" },
3540                { 0.1d, "%5a", "0x1.999999999999ap-4" },
3541
3542                { -2.d, "%a", "-0x1.0p1" },
3543                { -2.d, "%#.3a", "-0x1.000p1" },
3544                { -2.d, "%5a", "-0x1.0p1" },
3545                { -2.d, "%- 12.0a", "-0x1.0p1    " },
3546                { -2.d, "%#+01.6a", "-0x1.000000p1" },
3547                { -2.d, "%-+8.4a", "-0x1.0000p1" },
3548
3549                { -.00009d, "%a", "-0x1.797cc39ffd60fp-14" },
3550                { -.00009d, "%5a", "-0x1.797cc39ffd60fp-14" },
3551
3552                { -1234567890.012345678d, "%a", "-0x1.26580b480ca46p30" },
3553                { -1234567890.012345678d, "%5a", "-0x1.26580b480ca46p30" },
3554                { -1234567890.012345678d, "%- 12.0a", "-0x1.2p30   " },
3555                { -1234567890.012345678d, "%#+01.6a", "-0x1.26580bp30" },
3556                { -1234567890.012345678d, "%-+8.4a", "-0x1.2658p30" },
3557
3558                { Double.MAX_VALUE, "%a", "0x1.fffffffffffffp1023" },
3559                { Double.MAX_VALUE, "%5a", "0x1.fffffffffffffp1023" },
3560
3561                { Double.MIN_VALUE, "%a", "0x0.0000000000001p-1022" },
3562                { Double.MIN_VALUE, "%5a", "0x0.0000000000001p-1022" },
3563
3564                { Double.NaN, "%a", "NaN" },
3565                { Double.NaN, "%#.3a", "NaN" },
3566                { Double.NaN, "%5a", "  NaN" },
3567                { Double.NaN, "%- 12.0a", "NaN         " },
3568                { Double.NaN, "%#+01.6a", "NaN" },
3569                { Double.NaN, "%-+8.4a", "NaN     " },
3570
3571                { Double.NEGATIVE_INFINITY, "%a", "-Infinity" },
3572                { Double.NEGATIVE_INFINITY, "%#.3a", "-Infinity" },
3573                { Double.NEGATIVE_INFINITY, "%5a", "-Infinity" },
3574                { Double.NEGATIVE_INFINITY, "%- 12.0a", "-Infinity   " },
3575                { Double.NEGATIVE_INFINITY, "%#+01.6a", "-Infinity" },
3576                { Double.NEGATIVE_INFINITY, "%-+8.4a", "-Infinity" },
3577
3578                { Double.POSITIVE_INFINITY, "%a", "Infinity" },
3579                { Double.POSITIVE_INFINITY, "%#.3a", "Infinity" },
3580                { Double.POSITIVE_INFINITY, "%5a", "Infinity" },
3581                { Double.POSITIVE_INFINITY, "%- 12.0a", " Infinity   " },
3582                { Double.POSITIVE_INFINITY, "%#+01.6a", "+Infinity" },
3583                { Double.POSITIVE_INFINITY, "%-+8.4a", "+Infinity" },
3584
3585        };
3586        final int input = 0;
3587        final int pattern = 1;
3588        final int output = 2;
3589        for (int i = 0; i < tripleA.length; i++) {
3590            f = new Formatter(Locale.UK);
3591            f.format((String) tripleA[i][pattern], tripleA[i][input]);
3592            assertEquals("triple[" + i + "]:" + tripleA[i][input] + ",pattern["
3593                    + i + "]:" + tripleA[i][pattern],
3594                    tripleA[i][output], f.toString());
3595
3596            // test for conversion type 'A'
3597            f = new Formatter(Locale.UK);
3598            f.format(((String) tripleA[i][pattern]).toUpperCase(), tripleA[i][input]);
3599            assertEquals("triple[" + i + "]:" + tripleA[i][input] + ",pattern["
3600                    + i + "]:" + tripleA[i][pattern], ((String) tripleA[i][output])
3601                    .toUpperCase(Locale.UK), f.toString());
3602        }
3603    }
3604
3605    /**
3606     * java.util.Formatter#format(String, Object...) for BigDecimal
3607     * conversion type 'e' and 'E'
3608     */
3609    public void test_formatLjava_lang_String$Ljava_lang_Object_BigDecimalConversionE() {
3610        Formatter f = null;
3611        final Object[][] tripleE = {
3612                { BigDecimal.ZERO, "%e", "0.000000e+00" },
3613                { BigDecimal.ZERO, "%#.0e", "0.e+00" },
3614                { BigDecimal.ZERO, "%# 9.8e", " 0.00000000e+00" },
3615                { BigDecimal.ZERO, "%#+0(8.4e", "+0.0000e+00" },
3616                { BigDecimal.ZERO, "%-+17.6e", "+0.000000e+00    " },
3617                { BigDecimal.ZERO, "% 0(20e", " 00000000.000000e+00" },
3618
3619                { BigDecimal.ONE, "%e", "1.000000e+00" },
3620                { BigDecimal.ONE, "%#.0e", "1.e+00" },
3621                { BigDecimal.ONE, "%# 9.8e", " 1.00000000e+00" },
3622                { BigDecimal.ONE, "%#+0(8.4e", "+1.0000e+00" },
3623                { BigDecimal.ONE, "%-+17.6e", "+1.000000e+00    " },
3624                { BigDecimal.ONE, "% 0(20e", " 00000001.000000e+00" },
3625
3626                { BigDecimal.TEN, "%e", "1.000000e+01" },
3627                { BigDecimal.TEN, "%#.0e", "1.e+01" },
3628                { BigDecimal.TEN, "%# 9.8e", " 1.00000000e+01" },
3629                { BigDecimal.TEN, "%#+0(8.4e", "+1.0000e+01" },
3630                { BigDecimal.TEN, "%-+17.6e", "+1.000000e+01    " },
3631                { BigDecimal.TEN, "% 0(20e", " 00000001.000000e+01" },
3632
3633                { new BigDecimal(-1), "%e", "-1.000000e+00" },
3634                { new BigDecimal(-1), "%#.0e", "-1.e+00" },
3635                { new BigDecimal(-1), "%# 9.8e", "-1.00000000e+00" },
3636                { new BigDecimal(-1), "%#+0(8.4e", "(1.0000e+00)" },
3637                { new BigDecimal(-1), "%-+17.6e", "-1.000000e+00    " },
3638                { new BigDecimal(-1), "% 0(20e", "(0000001.000000e+00)" },
3639
3640                { new BigDecimal("5.000E999"), "%e", "5.000000e+999" },
3641                { new BigDecimal("5.000E999"), "%#.0e", "5.e+999" },
3642                { new BigDecimal("5.000E999"), "%# 9.8e", " 5.00000000e+999" },
3643                { new BigDecimal("5.000E999"), "%#+0(8.4e", "+5.0000e+999" },
3644                { new BigDecimal("5.000E999"), "%-+17.6e", "+5.000000e+999   " },
3645                { new BigDecimal("5.000E999"), "% 0(20e", " 0000005.000000e+999" },
3646
3647                { new BigDecimal("-5.000E999"), "%e", "-5.000000e+999" },
3648                { new BigDecimal("-5.000E999"), "%#.0e", "-5.e+999" },
3649                { new BigDecimal("-5.000E999"), "%# 9.8e", "-5.00000000e+999" },
3650                { new BigDecimal("-5.000E999"), "%#+0(8.4e", "(5.0000e+999)" },
3651                { new BigDecimal("-5.000E999"), "%-+17.6e", "-5.000000e+999   " },
3652                { new BigDecimal("-5.000E999"), "% 0(20e", "(000005.000000e+999)" },
3653        };
3654        final int input = 0;
3655        final int pattern = 1;
3656        final int output = 2;
3657        for (int i = 0; i < tripleE.length; i++) {
3658            f = new Formatter(Locale.US);
3659            f.format((String) tripleE[i][pattern], tripleE[i][input]);
3660            assertEquals("triple[" + i + "]:" + tripleE[i][input] + ",pattern["
3661                    + i + "]:" + tripleE[i][pattern],
3662                    tripleE[i][output], f.toString());
3663
3664            // test for conversion type 'E'
3665            f = new Formatter(Locale.US);
3666            f.format(((String) tripleE[i][pattern]).toUpperCase(), tripleE[i][input]);
3667            assertEquals("triple[" + i + "]:" + tripleE[i][input] + ",pattern["
3668                    + i + "]:" + tripleE[i][pattern], ((String) tripleE[i][output])
3669                    .toUpperCase(Locale.US), f.toString());
3670        }
3671    }
3672
3673    /**
3674     * java.util.Formatter#format(String, Object...) for BigDecimal
3675     * conversion type 'g' and 'G'
3676     */
3677    public void test_formatLjava_lang_String$Ljava_lang_Object_BigDecimalConversionG() {
3678        Formatter f = null;
3679        final Object[][] tripleG = {
3680                { BigDecimal.ZERO, "%g", "0.00000" },
3681                { BigDecimal.ZERO, "%.5g", "0.0000" },
3682                { BigDecimal.ZERO, "%- (,9.8g", " 0.0000000" },
3683                { BigDecimal.ZERO, "%+0(,8.4g", "+000.000" },
3684                { BigDecimal.ZERO, "%-+10.6g", "+0.00000  " },
3685                { BigDecimal.ZERO, "% 0(,12.0g", " 00000000000" },
3686                { BigDecimal.ONE, "%g", "1.00000" },
3687                { BigDecimal.ONE, "%.5g", "1.0000" },
3688                { BigDecimal.ONE, "%- (,9.8g", " 1.0000000" },
3689                { BigDecimal.ONE, "%+0(,8.4g", "+001.000" },
3690                { BigDecimal.ONE, "%-+10.6g", "+1.00000  " },
3691                { BigDecimal.ONE, "% 0(,12.0g", " 00000000001" },
3692
3693                { new BigDecimal(-1), "%g", "-1.00000" },
3694                { new BigDecimal(-1), "%.5g", "-1.0000" },
3695                { new BigDecimal(-1), "%- (,9.8g", "(1.0000000)" },
3696                { new BigDecimal(-1), "%+0(,8.4g", "(01.000)" },
3697                { new BigDecimal(-1), "%-+10.6g", "-1.00000  " },
3698                { new BigDecimal(-1), "% 0(,12.0g", "(0000000001)" },
3699
3700                { new BigDecimal(-0.000001), "%g", "-1.00000e-06" },
3701                { new BigDecimal(-0.000001), "%.5g", "-1.0000e-06" },
3702                { new BigDecimal(-0.000001), "%- (,9.8g", "(1.0000000e-06)" },
3703                { new BigDecimal(-0.000001), "%+0(,8.4g", "(1.000e-06)" },
3704                { new BigDecimal(-0.000001), "%-+10.6g", "-1.00000e-06" },
3705                { new BigDecimal(-0.000001), "% 0(,12.0g", "(000001e-06)" },
3706
3707                { new BigDecimal(0.0002), "%g", "0.000200000" },
3708                { new BigDecimal(0.0002), "%.5g", "0.00020000" },
3709                { new BigDecimal(0.0002), "%- (,9.8g", " 0.00020000000" },
3710                { new BigDecimal(0.0002), "%+0(,8.4g", "+0.0002000" },
3711                { new BigDecimal(0.0002), "%-+10.6g", "+0.000200000" },
3712                { new BigDecimal(0.0002), "% 0(,12.0g", " 000000.0002" },
3713
3714                { new BigDecimal(-0.003), "%g", "-0.00300000" },
3715                { new BigDecimal(-0.003), "%.5g", "-0.0030000" },
3716                { new BigDecimal(-0.003), "%- (,9.8g", "(0.0030000000)" },
3717                { new BigDecimal(-0.003), "%+0(,8.4g", "(0.003000)" },
3718                { new BigDecimal(-0.003), "%-+10.6g", "-0.00300000" },
3719                { new BigDecimal(-0.003), "% 0(,12.0g", "(000000.003)" },
3720
3721                { new BigDecimal("5.000E999"), "%g", "5.00000e+999" },
3722                { new BigDecimal("5.000E999"), "%.5g", "5.0000e+999" },
3723                { new BigDecimal("5.000E999"), "%- (,9.8g", " 5.0000000e+999" },
3724                { new BigDecimal("5.000E999"), "%+0(,8.4g", "+5.000e+999" },
3725                { new BigDecimal("5.000E999"), "%-+10.6g", "+5.00000e+999" },
3726                { new BigDecimal("5.000E999"), "% 0(,12.0g", " 000005e+999" },
3727
3728                { new BigDecimal("-5.000E999"), "%g", "-5.00000e+999" },
3729                { new BigDecimal("-5.000E999"), "%.5g", "-5.0000e+999" },
3730                { new BigDecimal("-5.000E999"), "%- (,9.8g", "(5.0000000e+999)" },
3731                { new BigDecimal("-5.000E999"), "%+0(,8.4g", "(5.000e+999)" },
3732                { new BigDecimal("-5.000E999"), "%-+10.6g", "-5.00000e+999" },
3733                { new BigDecimal("-5.000E999"), "% 0(,12.0g", "(00005e+999)" },
3734        };
3735        final int input = 0;
3736        final int pattern = 1;
3737        final int output = 2;
3738        for (int i = 0; i < tripleG.length; i++) {
3739            f = new Formatter(Locale.US);
3740            f.format((String) tripleG[i][pattern], tripleG[i][input]);
3741            assertEquals("triple[" + i + "]:" + tripleG[i][input] + ",pattern["
3742                    + i + "]:" + tripleG[i][pattern],
3743                    tripleG[i][output], f.toString());
3744
3745            // test for conversion type 'G'
3746            f = new Formatter(Locale.US);
3747            f.format(((String) tripleG[i][pattern]).toUpperCase(), tripleG[i][input]);
3748            assertEquals("triple[" + i + "]:" + tripleG[i][input] + ",pattern["
3749                    + i + "]:" + tripleG[i][pattern], ((String) tripleG[i][output])
3750                    .toUpperCase(Locale.US), f.toString());
3751        }
3752
3753        f = new Formatter(Locale.GERMAN);
3754        f.format("%- (,9.6g", new BigDecimal("4E6"));
3755        /*
3756         * fail on RI, spec says 'g' requires the output to be formatted in
3757         * general scientific notation and the localization algorithm is
3758         * applied. But RI format this case to 4.00000e+06, which does not
3759         * conform to the German Locale
3760         */
3761        assertEquals(" 4,00000e+06", f.toString());
3762    }
3763
3764    /**
3765     * java.util.Formatter#format(String, Object...) for BigDecimal
3766     * conversion type 'f'
3767     */
3768    public void test_formatLjava_lang_String$Ljava_lang_Object_BigDecimalConversionF() {
3769
3770        Formatter f = null;
3771        final int input = 0;
3772        final int pattern = 1;
3773        final int output = 2;
3774        final Object[][] tripleF = {
3775                { BigDecimal.ZERO, "%f", "0.000000" },
3776                { BigDecimal.ZERO, "%#.3f", "0.000" },
3777                { BigDecimal.ZERO, "%#,5f", "0.000000" },
3778                { BigDecimal.ZERO, "%- #(12.0f", " 0.         " },
3779                { BigDecimal.ZERO, "%#+0(1.6f", "+0.000000" },
3780                { BigDecimal.ZERO, "%-+(8.4f", "+0.0000 " },
3781                { BigDecimal.ZERO, "% 0#(9.8f", " 0.00000000" },
3782                { BigDecimal.ONE, "%f", "1.000000" },
3783                { BigDecimal.ONE, "%#.3f", "1.000" },
3784                { BigDecimal.ONE, "%#,5f", "1.000000" },
3785                { BigDecimal.ONE, "%- #(12.0f", " 1.         " },
3786                { BigDecimal.ONE, "%#+0(1.6f", "+1.000000" },
3787                { BigDecimal.ONE, "%-+(8.4f", "+1.0000 " },
3788                { BigDecimal.ONE, "% 0#(9.8f", " 1.00000000" },
3789                { BigDecimal.TEN, "%f", "10.000000" },
3790                { BigDecimal.TEN, "%#.3f", "10.000" },
3791                { BigDecimal.TEN, "%#,5f", "10.000000" },
3792                { BigDecimal.TEN, "%- #(12.0f", " 10.        " },
3793                { BigDecimal.TEN, "%#+0(1.6f", "+10.000000" },
3794                { BigDecimal.TEN, "%-+(8.4f", "+10.0000" },
3795                { BigDecimal.TEN, "% 0#(9.8f", " 10.00000000" },
3796                { new BigDecimal(-1), "%f", "-1.000000" },
3797                { new BigDecimal(-1), "%#.3f", "-1.000" },
3798                { new BigDecimal(-1), "%#,5f", "-1.000000" },
3799                { new BigDecimal(-1), "%- #(12.0f", "(1.)        " },
3800                { new BigDecimal(-1), "%#+0(1.6f", "(1.000000)" },
3801                { new BigDecimal(-1), "%-+(8.4f", "(1.0000)" },
3802                { new BigDecimal(-1), "% 0#(9.8f", "(1.00000000)" },
3803                { new BigDecimal("9999999999999999999999999999999999999999999"), "%f", "9999999999999999999999999999999999999999999.000000" },
3804                { new BigDecimal("9999999999999999999999999999999999999999999"), "%#.3f", "9999999999999999999999999999999999999999999.000" },
3805                { new BigDecimal("9999999999999999999999999999999999999999999"), "%#,5f", "9,999,999,999,999,999,999,999,999,999,999,999,999,999,999.000000" },
3806                { new BigDecimal("9999999999999999999999999999999999999999999"), "%- #(12.0f", " 9999999999999999999999999999999999999999999." },
3807                { new BigDecimal("9999999999999999999999999999999999999999999"), "%#+0(1.6f", "+9999999999999999999999999999999999999999999.000000" },
3808                { new BigDecimal("9999999999999999999999999999999999999999999"), "%-+(8.4f", "+9999999999999999999999999999999999999999999.0000" },
3809                { new BigDecimal("9999999999999999999999999999999999999999999"), "% 0#(9.8f", " 9999999999999999999999999999999999999999999.00000000" },
3810                { new BigDecimal("-9999999999999999999999999999999999999999999"), "%f", "-9999999999999999999999999999999999999999999.000000" },
3811                { new BigDecimal("-9999999999999999999999999999999999999999999"), "%#.3f", "-9999999999999999999999999999999999999999999.000" },
3812                { new BigDecimal("-9999999999999999999999999999999999999999999"), "%#,5f", "-9,999,999,999,999,999,999,999,999,999,999,999,999,999,999.000000" },
3813                { new BigDecimal("-9999999999999999999999999999999999999999999"), "%- #(12.0f", "(9999999999999999999999999999999999999999999.)" },
3814                { new BigDecimal("-9999999999999999999999999999999999999999999"), "%#+0(1.6f", "(9999999999999999999999999999999999999999999.000000)" },
3815                { new BigDecimal("-9999999999999999999999999999999999999999999"), "%-+(8.4f", "(9999999999999999999999999999999999999999999.0000)" },
3816                { new BigDecimal("-9999999999999999999999999999999999999999999"), "% 0#(9.8f", "(9999999999999999999999999999999999999999999.00000000)" },
3817        };
3818        for (int i = 0; i < tripleF.length; i++) {
3819            f = new Formatter(Locale.US);
3820            f.format((String) tripleF[i][pattern], tripleF[i][input]);
3821            assertEquals("triple[" + i + "]:" + tripleF[i][input] + ",pattern["
3822                    + i + "]:" + tripleF[i][pattern], tripleF[i][output], f.toString());
3823        }
3824
3825        f = new Formatter(Locale.US);
3826        f.format("%f", new BigDecimal("5.0E9"));
3827        // error on RI
3828        // RI throw ArrayIndexOutOfBoundsException
3829        assertEquals("5000000000.000000", f.toString());
3830    }
3831
3832    /**
3833     * java.util.Formatter#format(String, Object...) for exceptions in
3834     * Float/Double/BigDecimal conversion type 'e', 'E', 'g', 'G', 'f', 'a', 'A'
3835     */
3836    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatDoubleBigDecimalConversionException() {
3837        Formatter f = null;
3838
3839        final char[] conversions = { 'e', 'E', 'g', 'G', 'f', 'a', 'A' };
3840        final Object[] illArgs = { false, (byte) 1, (short) 2, 3, (long) 4,
3841                new BigInteger("5"), new Character('c'), new Object(),
3842                new Date() };
3843        for (int i = 0; i < illArgs.length; i++) {
3844            for (int j = 0; j < conversions.length; j++) {
3845                try {
3846                    f = new Formatter(Locale.UK);
3847                    f.format("%" + conversions[j], illArgs[i]);
3848                    fail("should throw IllegalFormatConversionException");
3849                } catch (IllegalFormatConversionException e) {
3850                    // expected
3851                }
3852            }
3853        }
3854
3855        try {
3856            f = new Formatter(Locale.UK);
3857            f.format("%a", new BigDecimal(1));
3858            fail("should throw IllegalFormatConversionException");
3859        } catch (IllegalFormatConversionException e) {
3860            // expected
3861        }
3862
3863        try {
3864            f = new Formatter(Locale.UK);
3865            f.format("%A", new BigDecimal(1));
3866            fail("should throw IllegalFormatConversionException");
3867        } catch (IllegalFormatConversionException e) {
3868            // expected
3869        }
3870
3871        final String[] flagsConversionMismatches = { "%,e", "%,E", "%#g",
3872                "%#G", "%,a", "%,A", "%(a", "%(A" };
3873        for (int i = 0; i < flagsConversionMismatches.length; i++) {
3874            try {
3875                f = new Formatter(Locale.CHINA);
3876                f.format(flagsConversionMismatches[i], new BigDecimal(1));
3877                fail("should throw FormatFlagsConversionMismatchException");
3878            } catch (FormatFlagsConversionMismatchException e) {
3879                // expected
3880            }
3881            try {
3882                f = new Formatter(Locale.JAPAN);
3883                f.format(flagsConversionMismatches[i], (BigDecimal) null);
3884                fail("should throw FormatFlagsConversionMismatchException");
3885            } catch (FormatFlagsConversionMismatchException e) {
3886                // expected
3887            }
3888        }
3889
3890        final String[] missingFormatWidths = { "%-0e", "%0e", "%-e", "%-0E",
3891                "%0E", "%-E", "%-0g", "%0g", "%-g", "%-0G", "%0G", "%-G",
3892                "%-0f", "%0f", "%-f", "%-0a", "%0a", "%-a", "%-0A", "%0A",
3893                "%-A" };
3894        for (int i = 0; i < missingFormatWidths.length; i++) {
3895            try {
3896                f = new Formatter(Locale.KOREA);
3897                f.format(missingFormatWidths[i], 1f);
3898                fail("should throw MissingFormatWidthException");
3899            } catch (MissingFormatWidthException e) {
3900                // expected
3901            }
3902
3903            try {
3904                f = new Formatter(Locale.KOREA);
3905                f.format(missingFormatWidths[i], (Float) null);
3906                fail("should throw MissingFormatWidthException");
3907            } catch (MissingFormatWidthException e) {
3908                // expected
3909            }
3910        }
3911
3912        final String[] illFlags = { "%+ e", "%+ E", "%+ g", "%+ G", "%+ f",
3913                "%+ a", "%+ A", "%-03e", "%-03E", "%-03g", "%-03G", "%-03f",
3914                "%-03a", "%-03A" };
3915        for (int i = 0; i < illFlags.length; i++) {
3916            try {
3917                f = new Formatter(Locale.CANADA);
3918                f.format(illFlags[i], 1.23d);
3919                fail("should throw IllegalFormatFlagsException");
3920            } catch (IllegalFormatFlagsException e) {
3921                // expected
3922            }
3923
3924            try {
3925                f = new Formatter(Locale.CANADA);
3926                f.format(illFlags[i], (Double) null);
3927                fail("should throw IllegalFormatFlagsException");
3928            } catch (IllegalFormatFlagsException e) {
3929                // expected
3930            }
3931        }
3932
3933        f = new Formatter(Locale.US);
3934        try {
3935            f.format("%F", 1);
3936            fail("should throw UnknownFormatConversionException");
3937        } catch (UnknownFormatConversionException e) {
3938            // expected
3939        }
3940    }
3941
3942    /**
3943     * java.util.Formatter#format(String, Object...) for
3944     * Float/Double/BigDecimal exception throwing order
3945     */
3946    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatDoubleBigDecimalExceptionOrder() {
3947        Formatter f = null;
3948
3949        /*
3950         * Summary: UnknownFormatConversionException >
3951         * MissingFormatWidthException > IllegalFormatFlagsException >
3952         * FormatFlagsConversionMismatchException >
3953         * IllegalFormatConversionException
3954         *
3955         */
3956        try {
3957            // compare FormatFlagsConversionMismatchException and
3958            // IllegalFormatConversionException
3959            f = new Formatter(Locale.US);
3960            f.format("%,e", (byte) 1);
3961            fail("should throw FormatFlagsConversionMismatchException");
3962        } catch (FormatFlagsConversionMismatchException e) {
3963            // expected
3964        }
3965
3966        try {
3967            // compare IllegalFormatFlagsException and
3968            // FormatFlagsConversionMismatchException
3969            f = new Formatter(Locale.US);
3970            f.format("%+ ,e", 1f);
3971            fail("should throw IllegalFormatFlagsException");
3972        } catch (IllegalFormatFlagsException e) {
3973            // expected
3974        }
3975
3976        try {
3977            // compare MissingFormatWidthException and
3978            // IllegalFormatFlagsException
3979            f = new Formatter(Locale.US);
3980            f.format("%+ -e", 1f);
3981            fail("should throw MissingFormatWidthException");
3982        } catch (MissingFormatWidthException e) {
3983            // expected
3984        }
3985
3986        try {
3987            // compare UnknownFormatConversionException and
3988            // MissingFormatWidthException
3989            f = new Formatter(Locale.US);
3990            f.format("%-F", 1f);
3991            fail("should throw UnknownFormatConversionException");
3992        } catch (UnknownFormatConversionException e) {
3993            // expected
3994        }
3995    }
3996
3997    /**
3998     * java.util.Formatter#format(String, Object...) for BigDecimal
3999     * exception throwing order
4000     */
4001    public void test_formatLjava_lang_String$Ljava_lang_Object_BigDecimalExceptionOrder() {
4002        Formatter f = null;
4003        BigDecimal bd = new BigDecimal("1.0");
4004
4005        /*
4006         * Summary: UnknownFormatConversionException >
4007         * MissingFormatWidthException > IllegalFormatFlagsException >
4008         * FormatFlagsConversionMismatchException >
4009         * IllegalFormatConversionException
4010         *
4011         */
4012        try {
4013            // compare FormatFlagsConversionMismatchException and
4014            // IllegalFormatConversionException
4015            f = new Formatter(Locale.US);
4016            f.format("%,e", (byte) 1);
4017            fail("should throw FormatFlagsConversionMismatchException");
4018        } catch (FormatFlagsConversionMismatchException e) {
4019            // expected
4020        }
4021
4022        try {
4023            // compare IllegalFormatFlagsException and
4024            // FormatFlagsConversionMismatchException
4025            f = new Formatter(Locale.US);
4026            f.format("%+ ,e", bd);
4027            fail("should throw IllegalFormatFlagsException");
4028        } catch (IllegalFormatFlagsException e) {
4029            // expected
4030        }
4031
4032        try {
4033            // compare MissingFormatWidthException and
4034            // IllegalFormatFlagsException
4035            f = new Formatter(Locale.US);
4036            f.format("%+ -e", bd);
4037            fail("should throw MissingFormatWidthException");
4038        } catch (MissingFormatWidthException e) {
4039            // expected
4040        }
4041
4042        // compare UnknownFormatConversionException and
4043        // MissingFormatWidthException
4044        try {
4045            f = new Formatter(Locale.US);
4046            f.format("%-F", bd);
4047            fail("should throw UnknownFormatConversionException");
4048        } catch (UnknownFormatConversionException e) {
4049            // expected
4050        }
4051    }
4052
4053    /**
4054     * java.util.Formatter#format(String, Object...) for null argment for
4055     * Float/Double/BigDecimal conversion
4056     */
4057    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatDoubleBigDecimalNullConversion() {
4058        Formatter f = null;
4059
4060        // test (Float)null
4061        f = new Formatter(Locale.FRANCE);
4062        f.format("%#- (9.0e", (Float) null);
4063        assertEquals("         ", f.toString());
4064
4065        f = new Formatter(Locale.GERMAN);
4066        f.format("%-+(1.6E", (Float) null);
4067        assertEquals("NULL", f.toString());
4068
4069        f = new Formatter(Locale.UK);
4070        f.format("%+0(,8.4g", (Float) null);
4071        assertEquals("    null", f.toString());
4072
4073        f = new Formatter(Locale.FRANCE);
4074        f.format("%- (9.8G", (Float) null);
4075        assertEquals("NULL     ", f.toString());
4076
4077        f = new Formatter(Locale.FRANCE);
4078        f.format("%- (12.1f", (Float) null);
4079        assertEquals("n           ", f.toString());
4080
4081        f = new Formatter(Locale.FRANCE);
4082        f.format("% .4a", (Float) null);
4083        assertEquals("null", f.toString());
4084
4085        f = new Formatter(Locale.FRANCE);
4086        f.format("%06A", (Float) null);
4087        assertEquals("  NULL", f.toString());
4088
4089        // test (Double)null
4090        f = new Formatter(Locale.GERMAN);
4091        f.format("%- (9e", (Double) null);
4092        assertEquals("null     ", f.toString());
4093
4094        f = new Formatter(Locale.GERMAN);
4095        f.format("%#-+(1.6E", (Double) null);
4096        assertEquals("NULL", f.toString());
4097
4098        f = new Formatter(Locale.GERMAN);
4099        f.format("%+0(6.4g", (Double) null);
4100        assertEquals("  null", f.toString());
4101
4102        f = new Formatter(Locale.GERMAN);
4103        f.format("%- (,5.8G", (Double) null);
4104        assertEquals("NULL ", f.toString());
4105
4106        f = new Formatter(Locale.GERMAN);
4107        f.format("% (.4f", (Double) null);
4108        assertEquals("null", f.toString());
4109
4110        f = new Formatter(Locale.GERMAN);
4111        f.format("%#.6a", (Double) null);
4112        assertEquals("null", f.toString());
4113
4114        f = new Formatter(Locale.GERMAN);
4115        f.format("% 2.5A", (Double) null);
4116        assertEquals("NULL", f.toString());
4117
4118        // test (BigDecimal)null
4119        f = new Formatter(Locale.UK);
4120        f.format("%#- (6.2e", (BigDecimal) null);
4121        assertEquals("nu    ", f.toString());
4122
4123        f = new Formatter(Locale.UK);
4124        f.format("%-+(1.6E", (BigDecimal) null);
4125        assertEquals("NULL", f.toString());
4126
4127        f = new Formatter(Locale.UK);
4128        f.format("%+-(,5.3g", (BigDecimal) null);
4129        assertEquals("nul  ", f.toString());
4130
4131        f = new Formatter(Locale.UK);
4132        f.format("%0 3G", (BigDecimal) null);
4133        assertEquals("NULL", f.toString());
4134
4135        f = new Formatter(Locale.UK);
4136        f.format("%0 (9.0G", (BigDecimal) null);
4137        assertEquals("         ", f.toString());
4138
4139        f = new Formatter(Locale.UK);
4140        f.format("% (.5f", (BigDecimal) null);
4141        assertEquals("null", f.toString());
4142
4143        f = new Formatter(Locale.UK);
4144        f.format("%06a", (BigDecimal) null);
4145        assertEquals("  null", f.toString());
4146
4147        f = new Formatter(Locale.UK);
4148        f.format("% .5A", (BigDecimal) null);
4149        assertEquals("NULL", f.toString());
4150    }
4151
4152    /**
4153     * java.util.Formatter.BigDecimalLayoutForm#values()
4154     */
4155    public void test_values() {
4156        BigDecimalLayoutForm[] vals = BigDecimalLayoutForm.values();
4157        assertEquals("Invalid length of enum values", 2, vals.length);
4158        assertEquals("Wrong scientific value in enum", BigDecimalLayoutForm.SCIENTIFIC, vals[0]);
4159        assertEquals("Wrong dec float value in enum", BigDecimalLayoutForm.DECIMAL_FLOAT, vals[1]);
4160    }
4161
4162    /**
4163     * java.util.Formatter.BigDecimalLayoutForm#valueOf(String)
4164     */
4165    public void test_valueOfLjava_lang_String() {
4166        BigDecimalLayoutForm sci = BigDecimalLayoutForm.valueOf("SCIENTIFIC");
4167        assertEquals("Wrong scientific value in enum", BigDecimalLayoutForm.SCIENTIFIC, sci);
4168
4169        BigDecimalLayoutForm decFloat = BigDecimalLayoutForm.valueOf("DECIMAL_FLOAT");
4170        assertEquals("Wrong dec float value from valueOf ", BigDecimalLayoutForm.DECIMAL_FLOAT, decFloat);
4171    }
4172
4173    /*
4174     * Regression test for Harmony-5845
4175     * test the short name for timezone whether uses DaylightTime or not
4176     */
4177    public void test_DaylightTime() {
4178        Locale.setDefault(Locale.US);
4179        Calendar c1 = new GregorianCalendar(2007, 0, 1);
4180        Calendar c2 = new GregorianCalendar(2007, 7, 1);
4181
4182        for (String tz : TimeZone.getAvailableIDs()) {
4183            if (tz.equals("America/Los_Angeles")) {
4184                c1.setTimeZone(TimeZone.getTimeZone(tz));
4185                c2.setTimeZone(TimeZone.getTimeZone(tz));
4186                assertTrue(String.format("%1$tZ%2$tZ", c1, c2).equals("PSTPDT"));
4187            }
4188            if (tz.equals("America/Panama")) {
4189                c1.setTimeZone(TimeZone.getTimeZone(tz));
4190                c2.setTimeZone(TimeZone.getTimeZone(tz));
4191                assertTrue(String.format("%1$tZ%2$tZ", c1, c2).equals("ESTEST"));
4192            }
4193        }
4194    }
4195
4196    /*
4197     * Regression test for Harmony-5845
4198     * test scientific notation to follow RI's behavior
4199     */
4200    public void test_ScientificNotation() {
4201        Formatter f = new Formatter();
4202        MathContext mc = new MathContext(30);
4203        BigDecimal value = new BigDecimal(0.1, mc);
4204        f.format("%.30G", value);
4205
4206        String result = f.toString();
4207        String expected = "0.100000000000000005551115123126";
4208        assertEquals(expected, result);
4209    }
4210
4211
4212    /**
4213     * Setup resource files for testing
4214     */
4215    protected void setUp() throws IOException {
4216        root = System.getProperty("user.name").equalsIgnoreCase("root");
4217        notExist = File.createTempFile("notexist", null);
4218        notExist.delete();
4219
4220        fileWithContent = File.createTempFile("filewithcontent", null);
4221        BufferedOutputStream bw = new BufferedOutputStream(
4222                new FileOutputStream(fileWithContent));
4223        bw.write(1);// write something into the file
4224        bw.close();
4225
4226        readOnly = File.createTempFile("readonly", null);
4227        readOnly.setReadOnly();
4228
4229        secret = File.createTempFile("secret", null);
4230
4231        defaultLocale = Locale.getDefault();
4232
4233        defaultTimeZone = TimeZone.getDefault();
4234        TimeZone cst = TimeZone.getTimeZone("Asia/Shanghai");
4235        TimeZone.setDefault(cst);
4236    }
4237
4238    /**
4239     * Delete the resource files if they exist
4240     */
4241    protected void tearDown() {
4242        if (notExist.exists()) {
4243            notExist.delete();
4244        }
4245
4246        if (fileWithContent.exists()) {
4247            fileWithContent.delete();
4248        }
4249        if (readOnly.exists()) {
4250            readOnly.delete();
4251        }
4252        if (secret.exists()) {
4253            secret.delete();
4254        }
4255
4256        Locale.setDefault(defaultLocale);
4257        TimeZone.setDefault(defaultTimeZone);
4258    }
4259}
4260