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